MZ@ !L!This program cannot be run in DOS mode. $>YJz7z7z7雯7aHW7aH;7sq7z67aH7aH{7Richz7PELV  &@P@Ě x 6P @d.text~ `.rdata:@@.data5  @.rsrc  @@.relocCD @BUj 3PuHH3 @]UQE W~ ;vFSظk;w;wjSjYYEtWvPvEF[u FFuPE F_UQVWEPju&juuW]_3^UQVWEPjju&jut uW YYjhEYY_3^UVjuvUVO3^]UjuhYYHt*@| uIt| uItQPu hEu$YY3@]U SVW}VW] ECkP7C3 9EE] []c@PVWEjVWjVWjW{jVWjVWDjWC[jVWVW|jWC @jVWVWajWC%C@tjEY3}u M @CjWEEYY;E2_^3[UVjuFYY~SW3؋F t8 KYu_[v Y3^]UQSV39^WojWEuW6WjjW jW0t;SjWM :utQ:Puu33ۅuWYY36E:u:tH:Nu:u33;^[UQQVW}jW[YYuKjWf3FYYE;r,VjWu WjWE}u F;uv3_^3@jjW tPE YU SVW}hE3WF\jWAjjWvjWEhEW4VWjW)jW] 3D9t9Et 9CghEhWhEjW~33Ƀ9EEEM]E;C [ ]33MME;CsuF;t`9Nt 9Mu3PW|jWaVWvjWE5 3 9FtM;N uE9E39F `9Mt9N tuZYt3Fu?WjW VWYYu^jW jWlu9F EE3;EE ;}t}u3VWY3Y@_^[jW` YYv U S]VWjS3hES7wt"hESLVh@SjSwjSjSk PuwVG 3;~PEw u@PjSEVSjS 39F~N9At9tGEE ;E|_3^@[U3PPPuGhEu]Uju>jj h@5`MF]U}tuhE@P u hE@P@PL]U} tAju YYt1jju$ uEP5Mxju E ]UVuW3GWV YYthhSjW ;uPE9]uLEjWN  PVx PPhP ^t[P@:u+;v8 u9]t =uPhpEW_ PW YY3@M3[UQQWjWj uVhEjW3 YYPjjW PW]Eu`EPjW MhhEPt;u;jW'jw t4jh|EW jW~jWqjW(EYY^_UQMSV3W}EM~;u SSYYVWYY;ubWY~WhEhWRjWSSWgYHPWot$SjW PhEW P5M pSW+ Ph|EQ PaE_^M3[UVufjUY^uhE@Pj YYj]UVu6費&fY^]UE MV1D{7qhV E Y$V, EY$V jjjVY3^]US] ]VuW~ GPv6YYFuhE@P YYj0N SuQ臻F ~ _^[]U]UQSWYjXE;|YjWbYYt E9]~@WO jWV )jjWbjWS6jW+$u[UQQeS]VW3jFVS!uES} uhS'YYG=dMuj- $")BY5dM ؅uh'S VjPS Vj4S Vj+S Vj-S GPh'SE }Huuh''S u 'WS h4@+NVS $}tuWSq h@VSe u >t)jj+SP VhI'SD h@hXNS4 $E_^[UM3ʼnESVu3WhSPjSPVOP ;uVF3Y@M_^3[WX Y;tOQP YPhEhPVPV j^PzYW V 3FUM3ʼnESVu3WhSPjXSPVhEP ;uhEVEjWPV;tP; < YYWY9tVRQHAP NIJ NIAt@t QPVZ F_^]UE VuNu@+QVE }uFv;prp^]UE p0uE ]UQQEVuu3 +F ȋU FRW}+‰E+F QPEPhm-@V}F_uNv;qrq^U}uEEuEu PuuEPu5GUMAxu@xujuu pQJ]3@]UE@]UE S]VsW3$ /@F@wFDF@oSYYf~D ^~DSEND ;w +ЉV@~@9N@w5ShX~Yt F@;FDv3GE~PFPE~TFT_^[]Ä.@.@.@.@.@.@.@.@Uu>8Y3]UE VuaNQ0Vj tFF^]UVW} |7uFHD;H@rVWYF+F HPWV jX+F'u#u~jhEV[ GF_^]UVuFHD;H@rVGWY4Pu V践N AF^]ÃyuD yt|7Q;/DEËQ|;B$LIJD3UQE VW},ȋEutU2O1rqRQG_^UQE SVW}؋EuNt>GGMPQ@AGx|@t At PQWW _^[UQQVuWVF$4EhVE 3G 9}|ijVWVjjVjjVm(EtW~迱 PhE+YY誱 PujVG;}~舱 Ph|E3YY_^hEVUQQVuWj jV u/3GWV%WVytYWV2$V LSjjV ؃|$~hEjVS WEPSE ;[uVY3@_^EEPTYuE8u։}EyEQQ$V USVujjVjVjVt~SVTjVjVqV$Y^[]UW}jWjW(u WYhEjW' 3@_]UVuWjVjjVtth EjV( hEjV t hEVYYjVjV3_@^]UhM3ʼnEW3GWVQYYuWVYY}SWt WV VAYY؅yhlEWV EPSVI* uh\EWVk EPhXEV5jVuSh$EVN [M3_MUVuj5jV t hV\jVYY3@^]UVujjVKjjV*jV t2jVdYYDzVjVjV3,jVFYYujVYYu hEV{YY3@^]UVujVjVjjVtPV[$3@^]UVujjVjVjVjV$3@^]UVujjVXjVmjVejVjV,3@^]UjjutPub3@]UQQVW}h@Eh(EjWjjW4`EWP6W-6(EtNNtEQQ'PWqYY(jjWEE EE$W 3_@^UVujVjVPVPV 3@^]UVujjVHjVjVdtjX VC3Y@^]UVujjVhVjVV jX^]UVuWjVjjVxWVWjVjV0_^]UVujjVhV{jVsjV$jX^]U} u3@]u{juD jX]UQVuWEPjV~jWjVPuWVPV4_^UjjjuwPuPuz ]UVuhEjVjVjjVjV(uE 3jVJYYtjVujVZhEV"YY3^]UVuWjh EjVjjVQjVWjh&8@VPV<_^]UQSVujjjVVuSVEtVYjjVVM+E^[UVujVjVnuPhEjV)PhEVMVY^]UQSVuWjjVjjVjV  jVjVYEY;~3!+G~ WVYYuh,EVYY_^[CSjV ;]|UQSVW}W`3CSWu ujSW 8#uNVWYY4SWYYyu;u~u;}hHESW0 E+_^[UVujVYYjjVYHPV3ɅQVjVBV$^]UVujVTjVjVjjjV3ɅQVjVBVd<^]UVuW3GWVhxEWVWVYYttHtQHHt8HWVt*YYPWVPVPhpEVNuYYEjWVIPV0WVYYhEu`EPVjh\EV _^]USVuW3GWV3SVWVWVYY;u'SSVjVWVhVA$IWV YYt$hVNjV]jV"uhEWV0 WVYYjVYY_^[]UhM3ʼnE9uu3AVYt Htj3@)EPjV! ~jXVYM3ͪUVW}jWYYuhEjW Wl4HEW~ 3_@^]USVWHuV u hEWNYYt4HEhEW duVW7VWuV6tt jWVV؍CPW u hEWYYSWV ^[]UVW}jWYYuhEjW WUHPYYyjWjWjXjWv+PWF_^]UVW}hWfWPy0jWYYtjWjWOjWWjY_^]USVuWVj3GWVE u WVpYYth EWV WVWSV_^[]Uujhf>@u3@]Uu'Pu0 ]UuYt uY3@]Ujuujuuu ju{$]SVVWG`ESVW[hESWjhXEWhLEVW6h#7@hf7@hDEW|Hh6@h6@hE@aE@hE@nE@2E@UEH@U T]UFSW>PhPF N N G,A;~hESjPw vdG FO UNG0A;~hESjPwvdGOFU FH_N[]UVuF pE E E E PBYY^]UVuF pE E E PYY^]UEHVWj2YuxE@#EWPu j"VwjPu j"VdF pWE @_F$^]UEHSVu W;H~ u#H2;}MjLQVjP_^[]ËR |у?uЋс;Z;Eƍp;~H UVuW~ N hjjVEWEPVeE_^]UEj@Pu juv]Uuuuu uZu]UEHu HH QP ]UVu tt[tB twnVu*YYav ERvJv vjjP(vjjujvjjuF  ^]VWcYY3A;~pt[t9 t F;tujPSjWI F3?1QFQQ$WPSjWJ4vSQW:$3ɃjQSjW QSW ^ UQQS]VW-> uvFPW N^;MMWoYu WbYtM> u WY؋GjjuGjW[jjuEGjWGCSWE0u_u_FSuFuSNEN_F ^[UVu uVE VSjVF$HPE ^]UVu W}VW{> YYuF;FFt O2;| PƋVWYFY_^]UE HPu;Ht'YY]U Vu W}VWYY~jZ~"t;tVWaYY_^ËF=a(3A;uGeEUE(;uFQQ$W] 3҃‰MEUPEPEYYF UVu t`HS]W}t0HtHuBSW+Pv vj 'SWvPjWSWjvPjWEWY_[uEvEMBYY^]USVu W}VWHWv_$jW6uWPvSj WEWL4_^ ^[]UVW u:R FЃ?u%O39MQjPjWW> tSjW_$YYK[WuvhjWBWy_^]UVu W}VWYYtStE~6~G u,NS?#C3#3ډF[jƋWYPFPWvWcN_^]VWoHYYt&HtHt t jƋ F WYPFPW1vW NVWVWYY"}Ht HtHyqS tEHwb tjWD_$YYK[WfjvjjWF %N?#C3#3ډ[FNFWNFWYY_^Uuu'YYM A  ]UM VuYuf}St}tu WYY3VWYYW;~ E E WYYSRjuWF [^]USVWuWЋEWCW;} u}t ËڋE RSu uW&F []UE M]MWEt2Ht"HuVu}WEPEj7EM*E_}u uW_YYEPEjYY_UE xK~:t( tu7VuW}6_^]uu$uuEu uuTYY]UE 7VW$R@uVuO}wFuVu8}wFPu#jYu}VW> YYuL@ N?<u:UW@ YN8J ω FBVWEVjmsuj E}XYY_uj ujujujujujj%ujujjuj ujujju}w _^]ËQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@P@P@UEM;Au u QYY]PhPE ]UhuY3Y@]Ujujuu uY3@]UVujViYYtth EjV jVjVRPV3@^]UjuY3Y@]UVujjVjV^jVu hEVuYY3@^]Uuu[u ju]UjuYYujuRYY]Ã&E]U;uujVTjVjVu u jVO ]UpM3ʼnESVW}WuvujhE^SWE|FVWErt,EPVWVYYPu? uQWY3@VWYYiuhEWjjWlVWEjuWC,uEPVu u hxESjjWXjSVtJuhpEWvEPhdEWguhXEWQguhHEWCguh@EW=;E1M}urD덃}tED8;ErND>;E#~ ;u}A;M;p4H IHu<1;x,3C;|r?tC;~}t?}:@Jc}YNuro@D>;E3MAM;M 8uE_^[Ðzd@zd@d@Dd@Dd@d@d@e@d@Oe@UEhp,Ph ]étI%|uøEUQVWWxuXpUPEGPVM uNWuVȃ? u %;} Cxt3_^ÃtPIt3Itu꺬E E޺E%9M NM E맋vt EM EUS؋C3Ƀxu 8Hu9KVCxuM8HuFUK II ȃ?t t!uu u%YY3[]UVuFttjW~ t jV YYFHHHHHFHOHOHF+F_ jV1YYFFjPVf jV= YY^]UDM3ʼnEVW}EPu WOwEF xuSxuKSv~u 6~uv3F jW}uNE NO`t kN(HM SVjfu Et.Fu!X @F+F jV4YYFjLu 迕YYtnE_^[UQE HeSVu^SW<0F ;t%;r3Wt+uPuhEV%+F MQVYYuhEV_^[UE HtuEhEPud ]UEPu eYE YtEh EPu3 UE @M0FI 0FP:QuPhDEu QPh$Eu3]UE S]VuW|E~,j_;tu4jh|EjhhESy ~CHHN@F_s^[]UXM3ʼnEM EMMMEEHpMMVHpEjP襔uYYu uVUYYEFpEM3^{USVuF W} _KEwQN,QPVr>VQ>YVM+ЉF Fh^,~VP+уV PuF(+P+уV P+уV P+уV P;FvЋF +F _F ^[]USVu^(W} G= wkPF0kPSV=V=YȋF+j[~0N(kkFD_F$^[]UMA,U ;PQYY]UlM3ʼnEVuFDE~9N FUS^Wx++M MUue +F(jYEF+F=@ jViYYFN@AEPVF9UF YYNF9AF _F[M3^yWyI;}+VbFIuV+ȋ…~'QSNY^ZZYY"Ou[_US]WjSV+^ thLEuV N;MvAPQPP;MwF+F jVfYYFF ÉOHO_H[]+F WjjVXF@ xu%FHQPtjjV+ F8u݋F _UQVuF8Wt E E FHNxP N @F}t.E ESE;FsEʉXY@MAu[3 MB9EG_V^UFW8E~H@u+PuVpuGF+F _ jV0YYFjX]UVufF4f;F6v hEVYYE N+ȉN F^]USVW} 7@u؋FYHD;H@rVY_Atk@wOQ7VvHGHPVe؃{Hv"CE VEYM E GH9E|F@F+F jVIYYF_^[]ù N9N0~F+F(Wj__@;} QVYYUVF(FPVF A v uVfF6fF4F9ftfp^]UVuFptM HDFpjP荏E NFyXtPFVPXYYj0{̋F0W N;~jVPV 9~0YY_~ hEVMYYFFUE xSVuWtPfYNV+~ Q x}xGKN+N; PVYY^ ]JuGIKM 9Fv FF+H^ ]E ȋF;F$u !M FXN WKщPO NM3҉PHNQ;HrF8@FtFjRVs F3F+F@; jV-YYF;F$uFN ωHN NˉHMHF8t jjV F@VPYyjXN+QVY3Y@_^[]UVufF4fF4f;ruHhEVYYuu V5 u jVکYYfF4FHD;H@rVY^]ùf;rjVmUVuF28NuE jPV uC,NP8Jtu VYYtF@FF F+F(jYPV?YY^]UVuF<tuF;F(t hE:YjF4f;rhEN@fF4fF6E S+Qhs@V؃ tv^SVqFN H^fF4[^]UQQSVuF4u^u +^(EF9E FtEEVFt EtBW~ }WV4WuVfEfF4F(ÉFN @ FE F9_EFtE^[UE eeSVuvtEEEF+F PEPhp@V:juuV4$^[U~uvu u6VF]UEE E jPYY]UQVWt'xt @ @EEjPuWeEjPYY_^UVuW{(EjP}eYY~Ue}{}uwfGHYt%HHtHu&gEj]PY73YEMu{4uEjP}Y3Y~uCs 4 F;|_^U SV39^ u_0GEEjP]Pu~ teG8E]EjP]uYY~JE3ۉEGGDEEjPEGDEEjP0 Mu39^ u_$EjP] eYY~GU*E9]|^[USVuW}G ;E t~ t3GWytP;r tI8uj jjQ0@ OXHOxHPB_^[]ÊH_уӄtHUE H9HtPV1r PQ^jj PuG0]UVu~hW~tbSFhH;M rUNhHWPVt.PHZXZPZYRQH ~hYYu[_^]USVjL3SSu/j Vu ^^(^^4^ ^,^0^$^^H^^8^^<^@^ ^[]USVu F,W}3SPv WS/F4SPvWB/F(SPvW1/F0SPvW /F8k @SPvW /F$SPvW.SjLVW.0_^[]UM yAtjPQu.]UEVp83W~P}B9x;8}M tA ;|3_^]k UVu W}NfFItuItjIu&N FtAt QWYYv FtTIt6It+IuIFx|@t PWYYF9Fu'N!G$FDG$FlG$FG$Fw$_^]UQEeSVWx_pmFu} t0u,Ft!@uMIjP! uN,FMNDEG0u6 G00w03uE_^[UQQFS3W];t@t PuYYF;@MjP莐 tkuejkPۋjvPۉEut3V  ʈNMQ,Vq,t t 3@_[Åu2~t+F O||@t PuYYuڊN3GtlEV OzEuz|FB =uz|B@t PuYY}uz|Bt RuiYYuC9]:36US3VW9Z tB `39Z(~)3B|0|0@t PuYYG;z(|39Z$~B9t`A;J$|39Z4~#B9t@t PuYYF;r4|39Z8~"3B9t 0I0HG ;z8|_^[]UB @t Pu~YYzVWt23zvhr~|@t PuRYYBG;|>B@t Pu0YY3zv"r@t PuYYBG;|_^]U~P|FH@t PuYYF(NS^W P;s;vV ;s*z|@t PuYY;Vrb;v+~ N0 NGF+F(j[;}~+PVYYF,;}Z~+PV YY_[]Vp$NNIthIIt7It3^ËNDP։H$F8kYN(F4F0F,F$^LËNlH$H(Nlp(fPF0kYN,^ËNP։H$~FYt^Í^ËNPH$YtfN3@N^DAW39~$t~$u_UH}3]Ëu`@uu}ut3@]VSWF^t(t$V jKYtbuN3GtEV Ozt-jBdYu PWYtbz|B uvs_[^HtHItuh EuGYY^]UVjuZhEhu&豞ju藡^]Uutjh,Eu讜jX]USVW}hEjW6|3u PP#YYjW距ÙPW:jX_^[]UVW}hEjWe6f&@jP_^]jV1hHEjVםVjVYYYUVujV蒘YYujhV- VY^]UVuhEjVժ 8t3^]UhEju豪 uj h\EuiPhPEu3 @]UQSVW}jjWjhlEjW=WE$uS g(u SPYY3@_^[UQSVW}jjWɪjhlEjWWEuSZv(u SPdYY3@_^[UVW}WYSu PP5YY3@_^]UVWhuɜju螙0u4EhpEu聟 ^]UjVYY~^SjjV腘؃ t'WV u Se _uSjVVjVf uhV1 [uhV3 @]UVuhlEjhYY^]UVuhEjPYY^]UM3ʼnEEVWQPLP?SVWNW6ǍH@u+t|8 tIPSVWWuƍP]j貗3Ƀ ; DP'3Y@M_3^XUM3ʼnEEVWQPqYYP]Y;vSVjPۃ+t;tҍP觠Y_^tjYYt3@M3dXU SVWW]S芄NYYu1Wi؋E @YEu衃Y<jjyYYGhEFPW{E 3ۃ CENtuWKYYuPuW萕YYu/uuSJjjWe3]WjuW蟕؃ t;*thxEuWK CatF t6HHu]EPhEu}3C ;uEQQ$W視 3]WG뀋]W3CYEhEuWˤ ujW虑W: E+E _^[UW3GWuYPEHYY_]UjuYPE,YY]UQSVuWWVfYYu hEVSYYVSEȁYYtp03pPhEV$5}t3@*hV YYtjVʐWV;3_^[UQSVWW蔐YNj[tou NW5YYu)tQu WG$hEu!P~13C.EPu W& tu3uCSPH];Et3E ujSYY_^[UWjuj_YPEOYY_]UjuYPE3YY]USVW}W$ EhEjW1jjW豥4EPS赃(t jj5YYS謂PWX3 @_^[]UQVW}W)$(EjjWEȨhjWEP4Eju3ɅjQ4_^UWjuj_P^N}YY@PYY_]UW}jWP4NYY@PqYY_]UV} YM~jV&u hVjV jVϘujV]Ujjuju uhHEju$]UVuhEV蜘jV諏hEjV迖hEjVh+@VhVʎh8Eh EVDh@VhYYhEjNP hEjN P hEjiN@PjV虍hEjVShϊ@VjV軗jVq83@^]Uu uҎuu萓jh:@u]Uujju3@]UQSVu3CSV謎YYShVIVMWjSV賡VEhlEu]_u uSV SV蛌YPV< ^[UVsQtN8QBQ v8;Y t u,;t(F8QtN8QBQ v8YF~_| hTEV1YYUEMVu f0F83@FFEF@FC8YQtK8QBQ s8ZY;EVWzj ^;h _\t4PC8YQtK8QBQ s8Y@C8QtK8QBQ s8ύYfAt;;t tat buCjjXuVUY,j ȃnIIIIt|PXYu3-33k tЋC8QtK8QBQ s8"YG} PWYu~hhES VY6j @j 9j 2hhhES^ E9]_^3^C8YQtK8QBQ s8zYC 1 &F8Q;vN8QBQ v8@Y uȃ<9IiI#PVYF8Q;vN8QBQ v8ʊYzj-X6u6!Y6SF8YQtN8QBQ v8oY0EWYtWY6TYuj.nuY6TYu65SYu6>_t/F8Q;vN8QBQ v8ՉYG6F8YQtN8QBQ v8蜉YPIVYuÃ>_tFF8Q;vN8QBQ v88Yv8#Y=tj=TF8Q;vN8QBQ v8YaF8Q;vN8QBQ v8Y=tjYu!SuPE؅u[u3@(u 6V4Eu jXjPWz 3_^]UVuWjjVjjVۉPWu u@,VyjVau EtEPVyYYjX_^]UVWhPEh0EuSu EhSc{jjSw(uu h0ES~ jhES[y ?;uF>;t>j;VeQYYuƍP@u+<0+PVSy tguhEjjSew PS?jS4thlEVD u$Vh ESkyjStjS贀ZPnCY3_^]Ujjuv Pu jjuv PhTEu}]US]VjjS8hEPtVSeYYt VSYY3^@[]UVj-VCPYYtphEh0EVuIPhEuxju.s$^]US]VWjjS訇hEWt!SPV$ t VSYY_3^@[]US]VjjSWj.VOthW+PVSZw hEjjSu PYYt6S PW tt WSrYYWVhESw3@_^[]UVuWjjVȆh EhVxjVs t hEV{YYWjVxjVZsuWhEV5w 3_@^]UQSVuWjjVWjV|qhEhV3xSjV*xWVt4t(WV|uYY=xEDSh\EVc{ 0hTEhVwWVrt h0EV1{YYjhEVu EujV.xWVxruPjVtPShEVzSVujjVU{WV@rt&WVrYYt jVj}jVvpEYY눿xEWVvSjVxSVujjVzjVq0t SjVx SjVvjVNt;ujVOvjV~qSjVx_3^@[UhM3ʼnEEPjV« t$EPhXEV艶 tjVqYYt hEVyYYjVqjVyjVoM3̓4jVphEjVwWVthEjVwj.Wu0u@+PWV thEjVwUSVuWjjV݃VnhEhVXuWSVujVp0tDjVnjWhVFztWhEVx jVpWSV1whEjVOujV#pjVt qnYY hnYYjVoYY`j_K;|!WVojVojjVxG;~3_^[]UVujjV蛂jVuujPVujViojVwhVSohEjVgv3^]UWu 3Yu uWrYY+hEhEPW҄uhEPWÄjWm(.ujWv _]USVuWhEVw3Wh̬@VshEj[SVuh|Eh,EV(jVnhVmjWVtEHjPVrGWSV@vEuhTESVkuhPEhDEhEh$EhEhEj h EVqhESV&ujhEhVwLhESVu3WWVsh ESVthVmhEWVCSV8l@_3^@[]UM3A@ss]Í ]UEt I]UM;sE]UEPM ;Qt3]ÃtJtJtJuDz3@]Ë+@]UQVEPuMsEu YY;Eu3`xtXu&jEPuC EEyEEu3@# EEPh?YuM38^UEW~H@u+PuV|-GF+F _ jVItnIIt[ t/tE%UEEP}E}܅u븨E}E0}܍EhEPqEPaEM܃E }}M@F+F; jVYY^%}}EEEEghEOY}ЃEj%WSFYYEЅ]W&F+F HPCPVak^vFM_^3̓[-.UEPu u& ]US] VW<=uu}VCSWr D7<@u_CmÍp@uM+;Ev+Ey؊GGu0EË@u+IQAuȃhESqmYY;EvEUEf<t"PSRp} OGGuU0E&Ë@u+ƍzOGuȃJBBuEf_^[]UVG}0tjWmY3Y@(W;lVFPu hEWmVWMl jX^]Ujjju_|PzPu$l3@]UW}jjW| PP{Y@PfYY_]UVW}jjW{jjW{VPV{YY@P+YY_^]UM3ʼnEVuEPZOYu hEVp EPVk3@YYM3^+UjjuV{PT,Puk3@]UQ8{EEQQ5E$uk3 @Uuu ku jun]UWujVljV htjVhYYjVeYY_]ÅyuhEVp UM3ʼnESVujh4EjVzjV$:g jxYjVzYYH>$8!Pu r$uYu Vi$WjY\E3_j PVl3hXEVshxEVshPEVs hLEVC@PhDEVCHlPhGH_$ M~/F4EE@U ;u E;BtWGHEE9E|GH@<~h4Ej_4BE;~(hEhjSwq4GE$@O;|] F,F,@tGtPEWp4 F,HPjj$VMIIe AxHv5{3GjP,jPV}@HE9E|_^[UQVW{4W赳K0N3ɉ^ ~s0NN 3QNN$N(N,fV0N2NS@QWEP @KL8FOAG+Gj^; jW荥YYwGM@ G+G; jWgYYw_^UESX4VWx07j_jjWGH?wPF,Pv SSzYF GF,G@=?wGPF0PvSdSCYFGF0G(HwPF(PvS-S YFG(F(G,H?wPF4PvSSYFG,F4G0HUUUwk PF8k PvSSYFG0F8FHH?wPF$PvSSdYFFHF$OEH0CH_^[tuHq QP= ]U M3ʼnEES_0VPSE,W3NPugPuS=M^3[UVjuV]uv0 j]X]UWSqYPSI|}hhpuSq_^[U SV^0WSjMEEC2EECEECMEC2EECEEVC3V}hhA}Eu"uu&kuv0IqYYuSpYPv0\{ _^[UM3ʼnEWjEPV }EPv0MsM3_USVW~0jY}tSuj W!oW&pYMMEEG2EEGEEGPuWjuuVWQp}tSujWnujuj!Wtnu Wm}YYtWoYFVPW,z _^[UQQSV؋C0Wj E@$hFSEMP3ij hxFS8PGUj hlFS$Pj_?uj_4j=Xfj,XWj,8tB'uQQ$V!kPv$jVmjVi$jju uF_^[U(M3ʼnESVWًC0jE؋@$hFSEiP3j hFSTPGqj hFS@Pj_[Vj_Rj_j,8[P4j,GYYu CEEPHPjMXjuhjWuu]M _^3[ U MVs0EWF2EEFEESFYK,t'=t thFS6 WPYY ЋhhYY__^VWV0YZ_^UQQMSW~0$WlPEPW`guWCPJ#ʋ4@H@;v=? PSYY^]UQSVW}@};r!U T u֋u1U+;sߋ]CHI#M9x uu ύx3t}uuu YY_^[ËSHR҃tHUVuW} vVYGPjjVNIHMx@H `NIp NIp_^]UQEPju*Quu#A3@UQQS]VWEPjSQujSEQyD0x3ujjSQ y D0y3}3G;E~E;+@PEDPjhES@ _3^@[UM3ʼnEVuWPjV^PPVbI5E9r P?HY8uPHYM3_3@^XUM3ʼnEVuWPjVOPVH39v:E9r PGY>PgYF;rƍPGYM3_3@^UM3ʼnEVuWPjV&OPV*H39v:E9r PGY>PbhYF;rƍPNGYM3_3@^"UM3ʼnESVuWPjVNjVqOPVGOSPF PFYM_3^3@[UQQSVEPju#NujjuE?OyD0x3ۋuSjuO y D0y33C;EvE;~3N+F WF; Wu CYYWVuC 3~E\;Pu=GYY;|_^[UM3ʼnEVuWVt8PVVF3G 9|RSWVNYY;thFWVfK E9r PEYG;~[PaEYM3_3@^5Uuu uD 3]UM3ʼnEVujjVELjV7PVEPh@V3C(t hFVAYYPDYM33@^VF%t7[t^À>^uF>uhTFwgAYYF<%u>tF>]u>uh0Fw?AYYF^UVudYsHt>at1HHt%Htt u@V ^V VV NV FV>V 6ut+HHtHtHHt39u73V^ V VYu@ Yt3^]UQVF8^WEueF;usO~<%uFPGYt-E7~-u;}s;;~;tFG;ur39E_^USي%t'.t[t +@MIQU3@ @PY[]UESW3;ps# uE Yt EGC;Xrx]CS7Pu uOy3_[]UW~ |hFvZ?YYuE \DSGV~ _uN ]UF HxL9tHyhFv ?YYM+LWu |uVV u_]ÃVx ;F }|uhFv>YYNT+;rtWʋ3_u^3^UQSVu W]:$<Ht H3CSVu)C7<0uE+E Pu SG: "u uE1S:u}YYG;}r_^USV^jS.YY|0~rtQu!jS`.uu jPS7jS/YYuMjS,E+E Pu S1\EWu 3jS/3 _u]u V 5jS.YYujS.PS.PhFS|6u9Y^[]U4M3ʼnESVuWPjV@jjV@jV-@PjVA,;^u CDžtttth4FjV> PVk9ǃYYSWP t-PWP 9v6;sM9r P7YGu9`+PWP7P7Ve/MjX_^3[UQSWEPu u7?  9>rV47Y"ZMt@< t < t/<"t<\u9>rV7Y\9>rV6Y jh\FjhTFV6 C}uM9>_[rV6Y"USVW} ?؋tPhFYYtF>u+ǃrhFu3YYPYtFPYtF>.uFPYtFPYtFPYth`Fu^3YY+} %GPu CS 3 D_^[]U4M3ʼnES]VW3@QPS=PS6;?%uG?%u19r Pl5YG>WSEYGYitPEt$GtXct\dt3Sk=$EPP/EP@u+Ljl^f1TDS =eWotHHHHHHt EP@u+jl^Lf1STD<BPEPPR/P@u+PPP54 ;zPw43Y@M_^3[JÍPS;Ej.Pu#drSE(P?4VEPP. ISYYYGPhFS0 ]UVuWh8FhEVa@jjV-jhEV6+j_WV'WV/WV.&WV'DhEWV.WV&3_@^]UEDzF]ÊNE EW3G3O_F]VBHWtAHt9Ht&HNt3G3O-3@ H#A QQ$YYNˊN3@H#F_^U xu]E]EEDzEÃUu]Ë~ M ;AH]ËE VBS^WSAYYu,~ u |;tvuhFuLjYY3M +AA[^]USVu W}VukYYN@;}^ ҍT:u6@;|3+NC;}VL9u=@ ;|3_^[]ÍHM E GF OHO@G3@͋D PW@GFUHwHP YMD3@]3]UG=wPFPv u迫 u蜫YVF ;}‹+ʋV dIu~]UQSV3;u GF]rNV~@YE~hFuhEYY3FF=wPSSu- u YG;~3ɋ֋G\\\ JuEwGw^[USVWj 3SSuتjVu覈u} ^^ ^fFFFuE$_^[]UVu F=FtN3BjRPukFjPv uTjj VuG ^]UQQE VuH;Ns N D8E QQ]E$YYȃyuAED{Iu丐E^ËUUJ3@M H#ABxu9Ht @uE]UQQVW} Gt_tHu47uYYN]E] E Dz u u"֋EFWP脵YYuvu鸐E_^ËUVuW} VWpYYG=EutEHuuEuD0E҃}~K3F3}t/C NxMtMQEYMGu֍EPxYMEt33GEEE;~=EEE~EǙ+9E~ E}E9MtEǙ+;|+uVu|^M _3^SUSVu W}׋.؃{uFu^F;FvF~t ;~wF3uuuFuVuNS;uHCG{ߋ}CGCGC|@tFt Vu%YY_^[]Ë@9XujxYccu UVuVu GYY=EuEPu uuE ^UQSVuW3jGWVr0WVjjVE^0 9}|?jV:SV SWV#WjV[&jVE0ujVCYY;]~3_^[ËUVujjV/jjV/V jV ($DjVjVjVjjV%jV,ujVjV'u^]3@UQQVu]jjVt/VjV'?jVjVjujVEYYz]jVP'YYuEQQ$V@ 3@^Ujju.ju!Pu03@]Ujju.hFuh$ju3@]UQS]VjjS.jSSpHHtLHthFS$YYMjS/YYE;};~&W~WjS!VjS#;u_uujS" 3^[UQQSVW}3jCSW .SW6PjWEl/ ;|J;uEVSW FPSWE VSW"u;u|WuSWu"3_^[Uu jVW jV-u$u jVPVPh$FV#uH&Y]UM3ʼnESVuWPhEjV-jjV-jjV.jV0 jV$jV.YYPV0&YY)WP(P!%G;|uWPYYPY%YM_3^3@[,Uu ju/!uju"!]SWjV^YYt=jV%KSVWVjjVB"jVjV4 WSV _[UQW}9} S3VuC}u SVWSVjXctWu V3 jVYYE })E9]Ǚ+‹WSV>u SV4jY tu 'jVuSV jXtuWV jVYY}DWSVjVEHPSVEHPWVqE} ,HEGWSV &;}~ h\FVb YYjV'GWSVpjXGuMuSVQ -E 9E} h\FV YYjVMuSV"jYu9}|uWV XjVEHPSVWSVEWHPVME ++Ѓ,;} OOM G}HMWPVE 9E ^[_UVuWjjV)jVhEj(VjV(~ jjV) jVWjV{_3^]UhFh$Eu.3 @]UQSVE`F)uW}E 0P@u+PQW*OG0H  |_^[UVuuVxxYYu M F3^]UM AЃVutJJt N@tNUP!YYE^]Uuv hF6j6b]UVu uv t hFY^]UQEjPEEYYUQVEjP}YY} hFtYE^UQEjP}YYu3Wuv6uWXEHPW6 _UVuWvG=wPjj66ɚYC{(3ϋSdIu!M}{}VYt_HtDHHt#Ht hFYGu9EjPEYYGVYGgEMuG=?wPjj66YC33{4;~'K4@;|;~s u[YYKF;|_^UQQV)F=?wPjj3螙3|YQGPÉw0YYF=UUUwk Pjj3W35YGw8~R3΋W$ Iu~=!MuOu|ODnOD MuuɋUFu=?wPjj3ǘ3襘YG3w$~ O$@;|e~.MWAM;M|^UVuf@4f@4Wf;v hF`Y6h@8@ YH+H jPZYY@G uE G SvGt3@3_^]UQSX VqI WMx!ƍP@u+;t;Et%@)E+WV8YYt3;E_^[UVu FW};GuFuAu3@>3:uj3Ʌ!Ej WV u WVuP _^]ËG;Fu^uu3@3Ãu 3ɅjVW u'j WVw t 3ɅVWS/P USVu FWt\HtuHtrHt[MHHtHHug ;tt33@;tT@EHtu8t33A;t"HN@FEEUOtƉCEWVSCL H.C@C t{EjVSCK HF FEAu A{h_EjEXF^0F8>F EEC~tVVYYuhF;~tFPPzYYuhFExtPP]YYEu hpFS4AYYE FEEN F0H N$H$N(H(NHNHNHNHNHH0WKMPSKLC@K CE xMt#HHHHHEEE EuCKI+HEKuM9U~k2|ΉM};y~WQSE uuVSOHO MH|@tFt VS `YYM}KVSQYY=EHIp <OHQSMPȋE My~AyEEЀ?u UDEPSPYYMEMuʼnFECCHD;H@rSK^YC EKURRIO}9+yM+O}u;USS+S}e;UWSCEYYMS 4EƉU}Ce}-kE9}}EVPV@&EEE;E|E {hsF~Et vStPYY+ǃF3҉FC U;{s+3MPQU@AB9U;CrUSVCFFC@t DC{ht uSOYYEVSCDM YYtC@CEC_^[ÍIAA%ADA]AyAAAAQAAA/ A A AK!A!A2"A"A"A"Aw#A&A#A<$A$A%A'%A%A%A8*A &A^&A&A'AQ(A_(A(AUVuFMQv PV tMtIF@F^]UVu>uVYu NF^]UE M `HMHMH ]US]VWt2uVYt*>;wWvu /)>~} +u3_^[]ËUVu FW};v/ sj _OwWP6u`~ u=~Y~_^]UhM3ʼnEVuEPu V2 t/EPhFV< }~uEPhFVjhEV M3^UVujV}EPu VjVVK ^]UVWu }VWOjW#t3*jWmjjWjWu VW3(@_^]Uu uYYuuhFuT ]UVu uVYYt9uV,jVjVu jV3 jV3@YY^]UVu 'W}='w WYtuVW tVW jjW83@_^]US]VWu S}YYj.WyYYuǍP@u+48u)}uWS%jSGjSu?jS>.YYu3@EPjSuWSjSdjSP(jSzYYujS>.YY~T3_^[]jSYY+ƃ uWP~ Wv} F3>@_UQQW3G9~~RS^jS#YYEEuSYYN+B }9Ev EGM;|WS3Y@Y+F[_UVultF ^]U}t/SVuW} M9rVYG}u_^[]UE H@u+Pu u ]UVuvvxYYF^]UVuW~EPjW+с  9UwuPQاEjW@t jWYYF_^]UE M`HH ]US]W} '='w SY|jS}YYujSYYSVjWS jSjStVWSjWS WSBYYpVWS ^_[]UVu >tE&|E6vYt3%Wv~hjWM3;#_^]UV0:juuPV@Pu hFuuuu,jX^]UM3ʼnESVuW} VXYjhEVx ?PY#u1DžYt u u rYth$FW! uDShF.WhFVhlEWhShEV YtuꃥPpjjVPPh1AV.(؅t YVtRhEV+ sYYM_^3[aUE Hu3]ËU `]UQQE uEEEEPhe3AuCU}u u ʣ3 uu 边YY]Ujju Ph(FV@PA 3]Vjh3A^YYt h3AVYY^UoM3ʼnESVW}W-$P hFSVWh\FVWhWtSVWjhW@@j/PaYYtWh\FVWH8$t PWYYt/hW3@YY9|"WYY;~jWPWL@PWSVWCPWh\FVWW@jY+M_^3[ UlM3ʼnES]VuEPjSu( uVu hFSZWEPhFSV3u jYE3_uM u uuhF9EuEEuuu hpFSwM^3[vUVu uVPVPuhFVPu V&,^]UuuPu u]UVuWu VYYttGE )] ~]]]uWuMYYuSvW6u Wz>uÃ+PWYY_^[]UM3ʼnEES]VuW} H@u+VWܪYY<+PWPIPq<W蟪uWPFP]VjSRM_^3[(UQSVuWV] 3G;$YEuSVq"YYh\FhVdjjVtO8$uJjh2NAV7SVjVjjVjjVPV"E@PV|DuVpYYt[jhCAVSVGjjVjjV_,tPV(YYtuWjVSV!ujh$4AV -u(h FVSVhFVjV _^[USVW3W9}tuu uru u2 u;t3Њ:utY:Zuu3Ƀt*G uPh FuPu u)_^[]ËUjuu u]Uu  E]UVuWjjV W EuVUWh0 FV3jX jVY3Y@_^]U VW}jjWEjjWE8jMQP蒽Vu,t;SW3EZPE0uVhT FW jX[ jWAY3Y@_^Uujuu t }t3@]3]UQSVW}jjWjjW~ESV t>jjV EuE FWuSh FWVgjXj}u X hEuYY؅uV4Wuh FWSh=AVS賳VjW43@_^[UQSVujjVjjVEjSu$EuVTSh FV2jX jVY3Y@^[UVuu (Et j/u-YY^]U@kM3ʼnEVuh@PYYtPVKY3Y@3M3^IUVWh Fh F0EP4Eu&jY3~Vt,E_^]UM3ʼnEhdjPj `PDž`dEdUh CSu C  Fu C FVWP$}Yj Y<_^uf< u C FEt C FjYEu C FC F~uru}u C FfC | F]u8Et C d FJC X FAu}t C D F-C 8 F$u}t C FC  FC FM3聦USVW3]}}}}}YuWWVh@ FV5E $Vj[SV[h0 FVE$VSV:h$ FVE$VnSVh FVuVSV,9}_^[t u肕Y3@UQVhP Fh F0EP4EteEP8EPօtujutY3Y@^U8M3ʼnEVuWjjV H@u+uj/WuKNP*YuPYYM_3^3@[UVuWV$EhVGh FjV:uVjjVjjV'M 8+Ȋ@uWV=YY_^]UE/t\uM @8u]U @$M3ʼnESVuWV3YuPESjV jVqYYSSV>VVjV]lSjVj +Ȋ@:uP3jVbPVjVjV,uGjV +Ȋ@:uPPVM_3^3@[U @M3ʼnESVW}P3CSWz3 9Ӄ+Rt_$|e%~U'~[)~K*uQ;s|*uFf.*)f[^fA/]A*-|.~^u %YAU;s7F;lPWY3Y@M_^3[h FWWi 3UVW}hFhFWhFhYt+jh2NAuWujjus 3yhMVuttPWVq uPthF`YtPWVN u-t,WYt!hd FVWVjV733@^_[]Uj uV/ tjuV u.jjVfPVuPjPVu]3@]USVuWjh2NAV]3VyjjVmh<FWVDSu b4t_3^@[]uFYtjjVPh0Fh FWV 3WjWVMtWjVYY_^[]˛UVWV~)V\YYuhPFu uVVY_^]USVW3VVjuVVju ;tf;tbˍQAu+ʋ׍rBu+;|B+ʋˊ:utQ:Puu33ɅQuY3Y@3_^[]UM tU k!B u]UQVjjujju PVEEyE$u 3@^UE`T@@#Eg@D@Hܺ@LvT2@P@X]UEH@PDeSVpLMHPWxHUME } r3UJUQY33M3‰U} s3#3΁yZ:} (s33ʁn&} 5U]UuE UE}} PUM?xHH@pLMPDHP_^[UM VuFX 0FX~X@u VYFX^]UEu @TPYY]U}tVu MPuYF}Yu^]UVuhV~X8YYjuVujVmjVeFTPVXFTPVKFT PV>FTPV1FTPV!@^]USVuWVuF@YE # Z # :Mu_^[]UM3ʼnEW}PjWȃ tt VP[ QP PX M32DU2DUB|j(EPWE 3@^3M3_UQSV3SSjuSSjuE 9]t4;t0WyA:u+QVu:@Pu3@_3^[UVhEu,YYuuh|FYYVuju *V̍3^]UQVWH@u` F+VWEjYYSP@u+‹؋ǍH@u++Í|VW>YYuыǍH[@uu+PWV.sǃ H@u+0ƍH@uu++ǍH@u++EVNj} PWr >_^U0aM3ʼnEESVP3ۋSV ;uVhDFYYWSPYY;k;a33SWVc;PPSWVSWVPh<FPVj/P@PP(PH :u#+@u3;tdShPyPPPcPPhF u:u3u@#+A3;P@:u+hP~hEP ;VjP ;SWP{ uYu%mPh$PYY Y; ;3Y_M^3[ÍPh|FYVPPhFUQVjjujjuPEE$u蘾 3@^U M3ʼnEEES]EW} tvVuhu v uvPjPȩtWjPO;u(jVP?ڃ|*u"0 jP [-|s'u PYYYM_3^|UM3ʼnESWV訪Vu EuSW0؅|sVzjjWE]tw WEPSuVsxuEhLj PWEjPVyݖ0jW VjEjPt 賖0j3M_3[{UMSW3}}}9y,uA;AtEY4Q03}U;rMw;vGI@Vҋt ;u9|u T;t 9:tE;uE}}9]rw;Er^M ;_[t EEAEUQSVW_Pt=ÍP@u+ƒ PcjYujj W} 3ShL&ÍH@u+P$jYtShLV蔽 V1YEuk0 j WV{jhLPYYu.;0 j WuVV=jUhS|YPEYY_^[UEHE @u ً]Åu@]PQsYY]UXEPu t3YYyEu PoYYËM@3 uE@E3MfE܋FS]W}ătuf9Ut E܉F*u3 tEE]ȉ}eM3 EtD3 ^0~4uVuW}SWYYt$tMh$FWmYYt)ut 3_^[]PlSWy tVSPWSWYYYUVuvQfY^]UE VW}tut7)YtG&_^]UE3ɉHH]UEt M MH]UQQEPEPu N)uuuUVuW39~t'jWWWv;uVPV6~_^]USVu~tfUw[Mr;wRut} tDjRQu vuV7PV,|s&u ;u F F F Ӌ^[]UQQVuW39~t F (S;u%WWWWvV;|$;r F3[_^PYy F WWWWv6V؉U;|;s6Yu9Eu F F U M3ʼnEESVuW}3SSS>Su 膎tYIz0jW I 9EEPjP觊;t-WP6> )}9]3M_^3[@_y0jUEEt@@#E ]USVu3;tHW39^ r'w9^v PI'Y;^ rw;~r6Nv H#VN _^[]UQQVj(MYuPju 3`S]W} uU!eer)wt#EP&EYU9}rw9]r3FFF ^~^~ _[^ËPPMYuPjulVM3UVu~tt v8m"Y~tt v<Y~tt v@E"Y^]U}tuY]gM]UE3ɺfP jZfP3҃HHHfPHHH H(H,H0H4H8H1V1YYu_^]UE3#fPf;UuP#Ut U;}AuPj u 3]ËM tfP ffx v@ ]øyL]UE uE ÉEuE tnSVWeUMHf9JuJ f;H u x r 3tuH JE }t PYMEEu_^[EUVj0Yu3EE&FfEfFfE fF ft!jPu F u Va0Y뽃f ^]UQEeS] VWE;s]E;w[EP'EPYYM;w5uQPVLt>}tM E}E 9]rE_^[jjucu3jjUESW3؅tCVHucf;tupf;t t0;uރ PYt7ƅu^_[]UQeEH#M t fH ffMufEUVuFF#E t7FuPF uPF ftujPv F6u^]UQQESVu;F4E rw;F0rjj VC 8F@W"x@PjPv~m xhv3CSEjPi;t (Y0jMEEEP6EEP'YYEfESPvm yX0j V =E^ SjPvjtShuVhV-uYASPp~~Y~~~ ~(~$~,~8~<~0~4~@~H~D~L~P_^]UQQEujRjMQpP=H tCItIt Iu6jX3?uu R jjjMQpRP|s j33MEU tEtUVuV6v ^]UE3ɉHHH ]UUu3@]ËBVtB3WF3SNJvrb t] tX tSـEu3Fـuj u2j^J;s%3A;ruA;vuBG;rj^[_} rt!jX9E u uB9u t tjX^]ú;s3@S=s$? ˆAjX=s# ? $? ˆYAj. ? ڈY? $? ˆYAjX[UQV39u uE;t033B3ɉU9u v9EEL=s=sjX =EA;M rWu$Y;uVju 3t]ËE Mu33]ËM SW$ (  FPS<%YYt<~~3;|ۃ~u F9( ty9Nt9 uj u҃~u[jh ~Wu2|1r+ u !NFF_; RFPVu U( 3;wr;Ms E+_[]U>t]ËE Mu33]ËM S$ ( W39(  jS0YYt~ۃ~ 3A;tYu F^9 u9~uQjh ~Wu/|'r! u F냉; vNFPVu U( 3;wr;Ms E+_[]UES3+VHHtvHtJHtHtE Xu y"c9]wr}s E M@jAX:E3fH49X$w9X v%PH;w;vH P$E  PsAY33uu uuuItu WSh ~Wu; |;sjXBj8hL jQ8 < @ 9 ,;tF 33_^[]UEVW3+HHtzHt=Ht%HtE xu ;!Y33_^]ËE M@jAXE@jYfH4HHM 9ytQP IH$HH뱃 x멋E  Puu uuu넋u j8hLWv  jjj P8 < @  8( $ ( ;/ F US3V9] t}}t }t}ukhP Y;uSjXW}^^tSju  F ;_AuԴAVPu u;uVYSjE PX 3^[]U M3ʼnEEMVu W3+ωEIt=ItZIt ItIVgYDNNH7NHN  ׉Hx V}N;r w9MvMM u 33WuP3Ƀ;|;s jX)FV u{9Nw9NvqFNS39~rUw9>vON+u= v 3QPP|.r( t';~rw;r33[M_3^.jXfFU} ujjE P 3]j YuPj܋MUPMhӷAu HMuHP HP]UӋ[ EH33_^]UEu]S]W} u}wtj jP 3\Vj YjuE jP 5E߉~^F(wVh"AuFVu VY3^_[]Uf}ueA]3]UQS]Wjuuu S"uuuu S辷EtEVu8E K@Dt(uVPYYy|jj S uVgG F0G0FG4FGF(GF,G(F G,F$fGfF4GYt@t3@3ffF6E FEFEFFF3^_[U} u3]Vu YuPju 3u uV ^]UVuFt PfYFt!txu F8u PfYf ^]UjyY3;uEQ jP 3]ÉHHH H]U}u3]uYtM HMH]UE3ɃHHPPH0P(P,HHH H$fH4fH6]U W3}9}w 9}}E EufNfɋу2ˆEMtjEPFPЉFF ji@F EEPFPUЉFE;Etw ;}i_UXM3ʼnESV3Sj EPW;|;sFPVW j u;t ^SSEj PPEPWx5EPEPuuE8EtE8Et3M^3[I%UESV3+WHtnHt#Ht>Ht&HtE pu Y33_^[]ËE M@jAXE3fH6HH3 tƒ@ P$uuuuڃ;|;sjXVu SWuuNjuM }o^XUS3V9]9] t~f}uwEtSjojaY;uSj\EW^FxV4F gE#FxV4x@:ujS+PuS2Vh}Au u$_;uVYSjE P 3^[]UQ}Vйtt23#3 LBMu} SWj_UU3#ы L#3L3 L#3L3# L#3L3 L#3L3#ы L#3L3 L#3L3# L#3L3 L#3L3#ы L#3L3 L#3L3#ڋ L#3L3 L#3Lm 3Ћ#ы L#3L3 L#3L3# L#3L3 L#3LMK9}rHUU3)}#ы L#3L3 L#3LMu}_[t3#3 LFMu^UU u3]uEyY]USVW}3;tnw;tg9_ tb9_$t]j___YO,FFF^;}؉FF҃SqSVS;uYF G0V^(~?Y3jX_^[]VpWx >@Hp1@_^SW~W2C_FY;v؅t&Swv ^ _^)^ )_uGG_[UVuWFx*t!EtIt[tgt qtue@t Pv(V$YYF@Dt Pv(V$YYF@@t Pv(V$YYF@8t Pv(V$YYvv(V$fYYquj3jX_^]ËF,NDFE8D>:F:Bu}]B:Fu>B:Fu6B:Fu.B:Fu&B:FuB:FuB:FuB:u;r+;~uqp;E},4FEEq4#uA@pE;Ev M5At;w_^[U SW~,}}^<+^tFlN,+؍];rhF8W 8QP FLND)~p)~l )~\EA+;#MfuF@}x+;#Mfu߉]> ^t^lGM^8E;vM}u3Lu+E7GS3 G@ uuSw0eBuuSw0tG0 EGFtFtÃruVl~8NX+FHL3#FTFHtP~HNXF8D^@ND3#FT~4FHfA#f{FHNDfANtBȃru~ts xaF<;se~t~l;s*+Njظ;v؋F8SjPg% ߉1;s'++;vF8WjP2% _[UQSVW}O E;sM3ۋGtwGt;GlW\EOl_tt;r7+ȉOtGl;|O83S+PQW>Gl7G\9XtEO\WlG,+-;r;|G83SRPW>Gl7G\R9XR3_^[9] t} u>O\;|G83Wlj+RPW5>Gl7G\39XA묋GlW\;~3;|O83S+PQW=Gl7G\9Xm3@gUSVW}Gt;s UGt;s } 21riGHOXWlw4O8L3#GTODGHfA#W@frGl#G4O@AOHWDfwlf4JtOlW,++;wPG``fOlf+OpG`,f V2x=Lff;s x;L xGlOttfOlf+OdGx,fIf Sx=Lff;s x;L xW\;|O83j+PQWf7Gl7G\139XAM9t6W\;|O83S+PQW!7Gl7G\9X 3@USV3ۋwtw#wtw 9];_`Gl;W8ЍBX;umX;ue;u[@;u<@;u4@;u,@;u$@;u@;u@;u @;u;r+G`;vw`3ۋ3`rjG`,Ff4Jx=Lfx;L fH39G`)GtGl_`MOlG8f4JfH39OtGl;lO\;|G83WlS+RPWE5Gl7G\9X33^[]Ã}u>O\;|G83Wlj+RPW4Gl7G\39XA9t9O\;|G83WlS+RPW4Gl7G\9Xo3@iUSV39_tu9_tGlO83_`f4JfOtGlGlI9uW\;|O83S+PQW4Gl7G\9X]3^[]9]t}u>O\;|G83Wlj+RPW3Gl7G\|39XA9t9O\;|G83WlS+RPWl3Gl7G\79Xj3@dUVuWVoYuv_^]UQQSVu3W;~;M 9^ w9u 9^jG=u W9^u@LFjMW(7UO(*SSSF0OGO GGGGOGGO;GGGOGGOGGOGGOGO uj} |3jXWGGO GGq9X$ʀ9X,ˀӃxˀӃxˀ39ЋGGGOIW GGOIW GOIGW GOGIW GO uj} |3jXWGOGI W GGO9Xt!@WGOIGW GOG9X,tQwv0 F0_ GEO0 }"|}3@3҃B3 9_lt 3j[Gq‹+Ӌ39_ltV2V0SSS"2 F0EG9XOM[G;G u6O9Y,t;Ev+EPGEPv0 F0GE;G t&OIW _ GG G3@9G rG9X,t!G;Ev+EPGEPv0 F0GO ;Hu _ GIIG9XGEG;G u6O9Y,t;Ev+EPGEPv0: F0GE;G t#O WR AO OGU;uEG9X,t!G;Ev+EPGEPv0 F09]u _ G[[G9X$GEG;G u6O9Y,t;Ev+EPGEPv0~ F06GE;G t#O WR$ AO OGU;uEG9X,t!G;Ev+EPGEPv0 F09]uGgguSG9X,tDG;G vGH;O w0V0OGGV1OSSGS F0Gq9_ti9^uHO(39^u8U E ]E~j Y3+ +M; uG=u 9^t a9^u9_tu9] =u ukuk W(*LYYtuG;;2uf9E u W+YJ} tDSSSW*} u2GLOD3fTAGLDPSwD[ 9_tu _l_\39^} G;3@uzOV0GGGV1OGGV2OGGV3OGGVOGGV OGGV OGGV OGV2eV0\yG;~؉G39_9^?LFjX_^[UE S33VCW;81}$8};ujO9O u G }BO(9O$uG$B} uE 9M}3] }~mj[EHw}uEwj X9E w}w}uEhjw(W uj Ewfȉ^3ۉF0CMjCF43@NP3҉>FLHFTAYj^,SFXw(W jv,F8w(W jvLF@w(W MFD3@jPw(W V 3҃0F9V8tE9V@t@9VDt;;t7kPȋE EWF$nYF@LWGYjX_^[]UMV3;t\A;tUpqqqP;tQ000pp @p p8p~0F( T+F0;v+WPF4F0P )}tu+]Sv4EF0뼋N(~09N0uf0F,;sljF,3_^[]UE,S3VW;p;9P 9u 9P> u H 8^8MH@}~fpuE@4L0NlFLRFTPQv` FpPjK$E܅tE@3LNlFPRFXPQvdF`DFpPj$E܅tE@3LX} }ri}r`EMuH MHMMHP^8~<> E^8~ ff}‹MMtcuM MtF\ Hu;M+ q;ut}+1fufqMu؃}uMm}u_^[UMeSVWjHZj_uj_f\]FuuEM F;};t^;} f| /t;Etf| f   f f 3Eu j;ujZjZj_EMu_^[UeSYVWjZj^uj^}MMAM]M E]M9U};h9u| ~ jZ+;~TUfHf P@HP]@*fL2f]fff Mw;~ jZ+;~V| ffHf P@HP@]*fL2ff| ff M jZ+;~[ U}fH]f P@HP@]*fL2ff ff Ή~_uffH]f P@HP@]*f򉐼fUff } jZ +;~[ U}fH]f P@HP@]*fL2ff ff Ή ~_uffH]f P@HP@]*f󉐼f Uff  +;~U ffHf P@HP@]*fL2ff ff Ή ~\uffH]f P@HP@]*ffUff e}u j;]ujZjZj^EMl_^[U싈SVuW} ~PffHf P@HP@*ffff  ~Tu NffHf P@HP@*ffU Jff  ~SwffHf P@HP@*f􉐼fWff 35L ~[~ ffHf P@HP@*f󉐼f}f~ ff F;oMIQM IQ YY_^[]USV3W}9 Q42BjMU[u~r+;~QUfHf P@HP]@*fL2ffff Ή<x=L9M+;ˋ]~VUfHf P@HP]@*fL:ffff ωM05Ltr+x>LjZ+;~KffHf P@HP@*fL:f ff ωuNs x;L xLjZ+;~KffHf P@HP@*fL:f ff ω}U;jZ+;~RffHf P@HP@*fL2ffff _^[VW33tf99u?F~f9u/f9u&f9uj Yf98uA|33@_^ËSu5PH@HP@3!f[Ã|)PVp2@f^[ËS~%PVp2@pP 2^~HP@3!f[UE $ | 0 3!ǀ Mǀ, Mǀ8 0Mf];U,u G, R$ E ;wKэ{;w} tuSu VR; ~V}ffNf VFNVF*f󉖼fUff @P( @P @P PP) ~VUffNf FFFNF*f󉆼fEff h;Lh6LYY}_^[t]]US]VuW3@;u$E ;r+;+M s't AKu;r+3û3]E[QQQQQQQQQ Q Q Q Q QQHw3Ҿǿ3MIQQQQQQQQQ Q Q Q Q QQHtt AKuƹ3ҋNj3 _^[]UE EPgY]Uu Y]U@EHPSKLMԋ+M VpWx OωMč:MЋN(M܋N,MN0MN4M؋N8MN)MMMAGMu+MM#+MM;Ms)MMAGMu֋MUvTBj3YM@QmWQWHuE$+ʊQmWQW}w}tQG}vIG;]s7;},@x3L@3L t @3LM +)M 3AыM KOH M+˃HMJUU#U+ρHE _V8F<^[UM3ʼnEE EES]E3VuWj Y}33ɉx9}vEHDEfA;Mr jX3҉MEBf9|EuHE;s;vE;u%3E@UfEEʉM;vf9|MuAM;r9MsM\M+Av3;~ 9]ty;uu3jfEYfD fD ܃fD r39]v0ExEf9tDEMf]]EK|]t9UuTw}uPvMM*MMM ;U}E"~M UɊUUf E`3ɋ]fM3ҋ+MB⋍|MMM] )U+˃}]u3ۍHCMut S#ӉUeEfLEu;EEMAEU;+t#MM;M}uUM<ȋE3+B;Es)EDEE+Ӆ~AEEE;Er3@U|9Eu }Twk}u }Pw\E UT+EfTEtMt*EE@E3fEEExE3M_^3[iUVWP3kYt,k |FPRYut>$u EF03_^]jhALVC tfF VFB;rPQLMYYtfNEF^]UhM3ʼnEEE SVEW}PP@ALljYY<%t5PYYG<%u%u'j%YYPGYuHkSC@t ktC kt C 3ɋA#H{HHHj%XfEj3Y}fE܍}ݍp@u+j ^+ ttktK tK k tE-}t+Gt Gt#GxPhALVW+|hALVW tlGtҀ Et Ҁ GfCQQE$PGP =PYY?G?u@t[SC uu ffCKًu&j YYNPYY]j YY_N2t Dž>t$DžhALuDžDž t \|sكDžً;[3;DžDžhALuu DžuۉutTVWSJ 9؅wruNjMۋ+39tu;0N;~);~ 0NH;9tu9utڃuIuA9~3j YYp9Ӌ9t j-t j+ t%j YY9t]uTj0YYtjXjxYY;u7t/ Oj0YYxO)!PYYHEF;vׅ Oj YYڃt5%j YY9ALPYYG?uمs%j YYo>su+t} E3+jAL_SuƍP@u+‹[)tj"YYu]%j YY%Ot"PYFYt{uׅt,!j YYtPփtj"YYt#8@AL?M_^3[yUSE Pu3ۍEhaBP]]]]St&9]u!9]tEMEhEPMY9]t uHMY3[USu 3uEhaBP]]]]t&9]u!9]tEMEhEPMY9]t uHMY3[UEPu h{fDu]UM3ʼnElPhLEu#lul<u PEjXM3+U졠MMt3]S]DMCHMCLMCPMDTMCt ttAtjXt MM3[]Ã=Mt6 Mu.!MtMt PE%MUQ=Muj%Yt3ÍEP|*#EYU}uj+X]ÍEPu uD ]USV3Wuuu!u胛EPhVVu}9Eu>KSWRPm (E}~#} } M3I@P`YeEPuYYu$9EuEPuYYt @EE}9E8t3H+E_^[Uuj+X]Ã~@thALV腞YYjW~Dujj{YYujX\~DSjWÂVW]؃tW}3H!}~@tj[ WqYVWYY[_]UVujRY^]U}t]fA]UjDMYu]Ã`M VutVʋQuA^]UVu PMYtWVuYYuVHMY_^]UVutW6~HM&VHMYYu_^]UE[L$z.BL]øML]ø|ML]øPML]øLL]øLL]øLL]øLL]øpLL]øLLL]øLL]øKL]øKL]øKL]øKL]øhKL]ø4KL]øKL]øJL]øJL]øJL]øJL]ø`JL]ø,JL]øJL]øIL]øIL]øIL]øIL]ølIL]øË0B#0B-0B70BA0BK0BU0B_0Bi0Bs0B}0B0B0B0B0B0B0B0B0B0B0B0B0B0B 1B2B L1BV1B`1Bj1Bt1B~1B1B1B1B1B1B1B1B1B1B1B1B1B1B2B UQSVXEu] Ex!*:;}hS?YPV 8WVu&PWVPSPh\EuSShRLWV_j VƆBYYt +΃|j V(YYt +΃|XE9Et uE^[UXM3ʼnES]WXE}  ;_$ 9BZLZLZLZLxZLdZLPZL}iYRP}M+ȃ;3yu33t&PS&tFPSt} t,Pu tPu t}t,PuƓtPu谓tƋM_^3[U4M3ʼnES]V3;t39u v tCOu_M^3[蚤U39Et9E tu u軰YY]9E u3@]UVuW} ;ujF;GubF ;G uZwvYYtIwvYYt8w$v$YYt'w(v(sYYtw,v,bYYt3@3_^]USVu W}GYu_^]UE HP VutEp+H ʙ;| ;r3@3^]UM3ʼnEVut]~8tW~Ht jjVd EP`EEEEEE$JBPv8 ~Ht jVYYYM3^UM3ʼnEESV0RQYYtzWx@u+ǍxWSv8 EtJtAEPuEEP th[LV|eWSv8?SHMEY_M^3[iUVW}7~Ht jjVH UM W)YtG~Ht jV[YY_^]UQQVuuYYut1P@uSW3+jCSETMYYuVHMY3_[^ËE wV_ FYu!FEW@PuEp8uWHMY3uHMY@UQES]MV3 ~HWt jjVK UM S,Ytu h[LVN{ Ge~Ht jVIYYuvSYunEPuu S؃u9EtHۃ~Ht jjV uu SV~Ht jVYYu SYeE8E_^[U3Vu9E}jX(W}9Eth[L7zYYVuu W_^]UVuNu6oVHMYY^]UhyNBhChCjuM]UVut~Ht jjV u Yt~Ht jVYY^]UM3ʼnESVuWu3M_^3[莘Ë8-QQ@h\LPX t7h\LVfy PYYP@u+ƒ~Ht jjV GWSv8 ~Ht jVYYSHMY(QQQhl\LPt 7h@\LTPYYu 7h \L*PJYYP@u+ƒ~Ht jjV3 GWSv8?SHM3ۃ;u-PV;tO__ Y9^Ht jVYY;t>PPh\LVwYjX3VM9Mu(hyNBhChCjVu M#^UVut~Ht jjV u Yt~Ht jV4YY^]USVuWj.[7HM'KYu9tHM!!YtHMY_^[]U6HM&}YtuPMYujX]É3]USVWŐ} G跐G诐@33Ch,]LGXCGdDGhGlG@OHOLO084LJ<LJpG 8_$_(HLL|LJXLJ\ LJ$(Yuqh$]LYu\h$]LY3;uEj8t 8t3tt8t;u3x39S39|DHx|w@"KYYt"`ujh@TMYY`txy[BSSXXYY\tPtLtPPMYt0ffF8FEPj ~hd^LSeYYjX2j:4YY39P!9(P;t9x3M}f9t19tjAXIPhX^LEj P4E` FuT^LuP^LMQ0WRP0h8^L$EujtHMYE䉃ǃ3M_3^跂;tj MGQP蚕 =wO9MtPύYh^LlU샾Wt*E0HMPMYYMujX t"E 0HM PMYYM t̓t"E0HMPMYYMt0tIu u~h^LVb X3@|3_]UQS3@@ ]t%9|uh_LPMY ;t-h^LuPMY ;tu PM$Y$9 t9$t8tWPMY(;uEE[U SV3C3SVuuz E9pt E 0uYtj8teuuEPW;uE u Eq}ukh0_LuaELu􋇴MQPW;tt}uh_LuaE EGHE^[USVWHM$Pu|YY|tN HM$ HM$YY  $$ $tN0HM40HM4YY0044047HM'uV}džp HM$3 HM0$HM40HM4HMVXPV\D`X\HM0_`^[]UVuW>jW@@YYtE 3M 3S9t5HMhL_LN ujX@[TDHuvHV)YYt5FjWhjW`M 3@TV|V"ZDH3[_^]UE SVu3W;tl$9$t džhhu džhxZ‰Edž^p^tVSSVSSVۣ_^3[]Ë;wʋAj04YYUS]V3E@W3tUu VYYj7X;u2pt;My@u4S/Yu%3u VPYYuE 98t\_^[]USVu 3W}@;tVWЋYYu >u _^[]UQQVW3}};t7H@u+MjU#QɍU#QPVuLt3}ut>:uhEPMYEuj_3HMEYut6HMEY_^UVuW3;WVCF@YY;t VP`GYYFD;tP;YS;tWPYY49<t @HMY,HMV,0VHMHMV HM 9tHMY9tHMYHMjVqV0HMHM[9~Ht"jjVkFH@NHHjVA萩VXVHMYY_3^]U E SV3'Wu;  q<*+R tlHtOt7Ht!HEMEMEMEMEiMEMPM391M4 tmHtWHt:tHM91MSM391M4;EM`d!EMXEMpE390E;t ԃ@$)BM391M$M391ME390E,;tǀh! ǀhTM391M<M391M$EM0M391MM391M M391M E90EXǀhj EM<EuEU9|3|9xs)l;HuHHMHlYExE|8ZK=titQHt6HHtwM91M@EMM391MEM`M391MxM391MsM391M<[NHHtzHtBtHM91MD)Eu3@Ml Euh_Lu,VYYj+] 3;ƋE|E90Eǀh,oEiMu;+ i[HtdHHt6HtHHEMEM391M\-EE? M391M0EMM391M`M391Mj"HtyHt H EMipE;uEXYUt33FA#u |XE+t.HtHEǀEǀEE;uETUІt33FA#u |jT}M391MHeEMR;Q8CшB$iBEMEME0|YMdE+tHSEǀEM391MXEMXM391MlpEEE0?|YMfBE0|YM)EMEMPEMTM391MdM391MhM391MpM391MM391MqM391MYEMFEM3E0MYMLEMPEMT;lNDSEB$BM391MM391MLEMEMoEMЃtxLEH w5$eB3@+jX&jjjjjjj j j 3MdEMPM391MlM391MEMEMM391M`{;-HHttHHtZt(H t!M391M"u E M391M EM, EM M391M M391M M391M --$&Ht8HHt&H E EQgVu>}9tHM!!YE0&EY EM@ M391M E^V';u\: B$BE}lHHMYHEE(ǀh$7 }9tHM!!YE0*EY uEM  uƜE; uP=YYu`YjX { uƤxEMHZ EM8G E}0[E39Y EMD EM< EM8 EM uE}0; e@0 uƔuuƬE}0E39Y8K uKEMP- ';} ɊB$)BuE0YE uu׋űE;t 8u_LuPư벋E}U ;x|#؃;|OM;rI;E|w>HHMH|Yx tE3AuQDMY;u E8x |txu SX HHR YEHlLJhEME}00EjWy^uEqE8;dh_LW;tYYtujjV_)h|_LWtYYt(ujjV軗\jVht_LWsYYtVu_hl_LWsYYtuB_Yu39ujSSV]WPMY;tX9tPjjV"j Wh`_LsSStG PjWSV1OjV%WHM <WEHMau,&uu  EM@uuuEM4EMEMuƘuxujE;R8IPuYOu7u)uE839^Ht[jjV襕 ~<u^8^qBqBpBBBB&qBsqBvBwB6wB#wBNwBvB vBvBvBfwB~wBvBvBvBwBwBwBwB vBFHt PWfHYYWmV@0YYtu VYYvDh_LW=VjV豼jw@$tSXj\jYY[_3^]Ë\X@ A uL9F@uG@<uTjjjPbtvD>h_LWa<jV3@3UVuW} _3^]SVW8p$p SW8=| hBV~ ^$_^[U S] VuW3É}E(t@<Eu}E8E89}tSV%YYt}SNYYtc?tF@t EeEWEh`LVF;}t?9u&th`LV!;EYY3_^[h`LV;eYYGEt܋E@}eE'X\A B 3E9ut?9uX ;t 3ɋ;t3;t;t4J!;@T"9lu O@P@M;t @Su'YYthX`LuX7YY&9}t;;usE]EsDh(`LW17 }2]Eh`Lu7YYE3@F@W3;}@ {@;v19Av&h`LV6YYt jW7AYY3;_W>WhGPjP^O`OddžH_tVYu3} @8}I83USVhaLV"RYYj[SVhaLEYa t8vjVhaL=a t LJ8VSVhaLa t LJ87jVhaL` ujVhaL` tLJ8u]j@Sl3YYE; VMQMQ+PSuuE;0HME0YEt$P@u+;sjjuu4SPMY0tQ4HME4Yt$P@u+;sjjuuSPMY4u EE@LJEuHMuHMEYYQ];[C;tPaYu <:t<.uF>u>%uZjVhaL[ t?h|aLu3YY.PN_Yu PCaYu<-t <.t<_t<~uFuˀ>]uFh\aLu3YYj:VEjYYtHej EPFVEeM t t /t u=|;Vh0aLu@3 .;/ujXBj/SiYYtE<tSPMY^[USVW3j@]]]]iYY;u@0URURU+RHPQ E;9]t:SSu3@V|;u E`u 6HMY>9]t$SSuu|;t΋u6HMY>9]t$SSuuS;t}7HMY7uHMuHMuHME _^[UQESV3lt3oWSV0 HM HMM 3Gt t*u}@ tuQSЃ EM}uSYtE*\X@ A t<ulu3lCHt PV苹cHYYHM3Y9<ttt uP9luH9EuCt1xtPsDhaLVn0!uS}YYutEE VEY_^[U4M3ʼnEEE؋E EЋEeEԋEV0!WEE3}fhEMܪ褸YYthbLS<0YYjX;VEPhbLEhEPZYYts>/u(~/u~ǍH@u+@PWVo >/t7j/VfYYt'Ot/uGύQAu+AQWV3 }EEO}VEPhbLVhbL} htbLEjhlbLZ t EhbLjh`bLY t EXbLjhPbLY t EHbLkjh@bLY t E8bLIjh0bLY t E(bL'jh bL^Y EbLuEFEEEj@udYYj?t@P^dYEYtEP@u+‹ƍH@u+@PD7VP|W}FWP</}؃ >u j/XfE>?u%ƍP@u+@PFVP/ /umVYEuj7EΊ:utP:Quu3t ,HMEY,0uHMY}ƍP@u+‰EH@u+EyAuE+σ8uMAAu+ȍ|EPDMYE)WPI;E@PEVP8;tHMY}WhbLS+}؃ ǃűuuS"8[j%PIbYYEjXPuEhaLϽ th|aLS\+YYEj EPEEPB]MЃ 9]Eu+PUԊ@u+E@PQu Ẽ h\aLS*YYLtj#VaYYtj#aYYt5\LE\Lu6UYYu/EE0uuh]LS*3 @M_3^VIËF W~hWYSPKW ;u䋆;t#N,H8p8PQk FHPtWSv&Sv~(<Euw8WYY_8_<_@};uԍF,PTtPSPSfVHM3_3@^[]UVuW} 't>> u6v軶Yt)FSjQPv蝶PH[3_^]U8M3ʼnEEEVW}諫jYU^eEЋE3BHUeȉUeȋM MMD}̃eEjEPHWsEЃ EtEEtMt E9Ft{WE܉EjEPWr t2jjTMYYEVFjEPWdqtl{E̋Htv p uuSуEԉFE} ue{4uC E؋E؋3ɉE܅~ ;DtA;|VHMY E܃EjM܃HQPEq tw{tz\t*x v$e9uWS蠸\YYt@Xt6x v0e9uWWS萸XYYt @9e}t)}̋Gtv w juSЃu܃HWYYEEEu;C4PEPC PE+ s4M_3^:UVW}p@t9{t C0F~sjsV^@C C3YY93jX3@_^[]UQM3S;m9 a] ;Q4A39S@>{ VWs3GE;t} 9tU 9Ut IQNYtK ~} l} jSYYtjP蜫YY{<uc8c<t } tusV PS%YYpP]}WC 3YY;tS@O 09^t @;u RPQ蘪 Ct GtKHCGO _3^jX3@[U,M3ʼnEE SVuW3E؋EuEԉ};> ]E܅x;E}EƋXGjYU33CtEt3CJtEttBr͋E܋]܅uEEEu9}tPDMYujXV39utwEXhjYU E33C]tLfDF3CJ]tLjXfDFtBrE܋]܅uUtHM؍DUQP3ftftf tfMuDžtfuVhdLSGuVW1EtG]t@M؋ED3tFttf1KueWHMEYtM33@M_^3[/U,SW3}}}}; 4 3ۉ}]9(t;0Vh4fLVrF }jY;tN }(~9 ~9uF ~ B MAd!YdtQaYtF ~}19 F  3ɃE QPVx( F u\Xuu P PhfLau\Xuu , PheL=FPNT#уt9QPvtvp\X PheLV/vtvp\Xuu Ph@eLV~ ~3@lEjXjPWE% ~F  $ BVYEYjX9F tF jV|SYY<jVjSEPEPWVdEYu03@9F tF E@VpPM E9]7VYYE;9]tj9}tjuYYɃ bujjX9F F {P@ Et!]heLV YYEu}YeM}juPYYɃ ]~ }u(YP7ȩXV耛\Vr}[3}P7'Y@ujX9F hF `jX9F TF }GE;EP7J}EYYt&3PPWE ~ F }~ F EPj7X3 E9]t;u Ƀ9]EEP7蕝YYE9]u~ fF Z9]ujuYYɃ VojuW돍EP7辜YYEu9]7V{YYj X9F F 39ptljX9F tF MrEPW豭YYEuU39Mu+9ltptuQQW jj 9tj X9F tF 3Uj a}79pMQ3P]YYt EE39]VFjuWtDt7tEuHMYj[SuV9 u9^ t^ MeEVY9juW- EP7]YYEu9]iɃ V莟jEP7转YYEu39])3Ƀ}L 7Vzu u sj 7V蘥YYj7)PYt E*uu V" E  t9| 9y t9[| 9Mj !]!]|NtH9|:;v4F u@QSPRPV|Bt<;|,;v"F u@PSRQ뚍EPV7, Eu7qYu7QY}u}8u,EP7Y3Yu9]E;t]E39]t0A@u ǀlV>SuW9]V\V處\ 9t j0vYYuQY9 uZ9]uwt8uHMjPVEEu!EEjX9F tF M`9]uuHM YE jj[jjW E#SuVn E jX9F tF Met3\V萔udjuWS}uE?t'ltpt~ f {~ F@F H_!jVYYN~ uV聛Y~ tOF@F H:t4PLYt)ǀl3Ƀ~ E*~ u>MFHMpIPqQ ۃ~ tF 3qE9xdeEF"v hdLVT j EF3jX_[ÍIBBHB BBFBBdBBBBBBB%B BUeSVW}EU? w[lpt{ uSYuuWT lEt;ttSYEtE6uEPwDuuGDEtpWuu }uɃ}GM DEjX3@_^[UQQSEjhRP艧i]U[UE +EM+Mi]UE;EtM +M+EM E E5XfLE]ËE +EEE5XfL]UE]UQEU e3;XURuuQPtMx3ËEt Qu!j7XUWSDMYujX+Su WE 3_]Ujuu u8Eu@E-3'Q]ËM3]UQQSVuWE8jp@U ]YY3;XE#MtWdhM+;rt)`WQud ;@;s`(@хu9U}EtUMQPERPVlyE(}tW`u_ hd;3_^[U싎t4u uPVу]Åx3.0kj`fLjP'0ju up' 3]UM3ʼnEEVuW}t}tytoM IfLtItItItYfLfL fLfLPQRhxfL\hPT\H@u+P\P3YYuuE WYYM_3^UM3ʼnEVutK4tBEPu hPSP@uj+PPjVM3^mUSVuEPu h@SS8t) WuShEhPSdž _4t4ÍP@u+=?sƄ0 @0jPSjV=^[]UE VuTWjuuP4E}'EuCS@E؁3'u eQ%SViPhfL6 $7[E_^]UEU 3;XURuuQPbME]UE VuTWjuuP8E}'Eu?S@E؁3'uQ%SVZhPhfL6b$8[E_^]UQQE3V0MM9Mu3iSWtaE ;tj85}WLMYYujuuP  3_[^E t EE t;u9Ht ;uE@9]w]}t@SjuU;t1;uK}tHSjuU;tA;uQ])]ufE@@thgL3uu SPhfLV!uj]YY$hfLVYYjXUEuEP@u+Puu ud]USVuݖ 3ݖ(Wݖ0ݖ8ݖ@ݖݞHHMY_ ^3[]v HMvHMv HMvHMvHMvHMv,HMv(HMVHM$USVEWH@u+؋ƍH@u+;s3%+Vu#&YYt3;u@~._^[]UQEP@u+S3@;Vu PMYtAj?Vm1YYtƍP@u+t>/tVHM$` FPMYu3IƍP@u+W;s3%SVu贌 u;u3G 3<3/VHMY_^[UVuPMYtcP@u+€>"WuWFPV Ot |7"uD7O>/tVHM$` FPMYt D78/u_^]U6HMuPMYY]U Vjhf7eYEUtBS~ u~,t)F;E!|F;Es;7uEO uu[^UM3ʼnEEPVj uEPVj t3@M3U4M3ʼnEEE SVuEWE3Wej@GWTM؃ u3 }hDMYu SHMYj;V.YY < t< uFuPPhhLƅٞyǍP@u+‹Ѝp@u+ t u@u3ɀ8=tD< t< uJu < t< uGuuNPhhL"YYt C0PhgL^"YYt C8PhE3"YYt#s WZ6YVYCtPhgL!YY?.uGuj.Wi-YYu DžgLt4tWNJ:utH:Nuu3u=sW>YKC$WYuWhgLDž PhgL !YYts(W2>YbPhgL YYts,؍PhgL YYts 뼃{u&PPMWCPM{YYCtxtttT8tOH < t< u Auj;Q,YY8t2jP+YY DžC,3;t\8"u@j VP +SKCи;|;s KCMSK9C ;t2VPYYȉCS‹ u C ; |;sss39su9tPMYC;ts9s uxtnj?W*YYu j/W0TYY+Pj/W tB+ǍpFPDMYC t!VWPC s Cu DžHMYu {Pj hgLVυ u {8>#j V *YYtj V)YYtPhEVS t3F33F9{+'IItIIIt(ItI$PPMC PPMCj WP诟 CSjgLY3tIjgLY3t5PMYC tP.YCDž` FVPMYC u DžVPMYCu DžDžhgLPYYC03hgLPYYC$8.u@PPMCY;uPhE3W ;vj^uhEPMYC;99Au9At K KC4}svY3Y`N;tC;tPQYYt ;u9{u Dž9$N; C;PQYYDž9{4u 9~4wHMwHMwHMw HMwHMw HMw(HMw,HMjYSHM$Éu39~t8xgL9upgLsss sssPh8gL$9uA;t20;u 9{ 6;mwF ËM_^3[-UESVW8E G tP@u+‹3C tP@u+3;tH`GtP@u+‹3CtP@u+3;uċGt#Kt:utP:Quu3_^[]USVW3Ve[}YEUuu; 97u &3E;BKC t;E ;M9s0tE3@;tqC;t39s$t9uuPE Yu9s$t9utHsu YYt7C;tuPYYt!j@DMY;tAEjYME3;R};PEDMYu!}tE0PHMYuu3_^[ËEt ΉuhBjWV@G3Ʌt|A:;rED0 VHMY]UVutW} >tKVHMYu_^]UQMtKtESVW]F F>u!9uu};u;EH ދu͋E_^[UVutvHMj6^VHM^]U HMuEEx0SVWgLgL}uuP UuE` FH$߅uދPu@hLtt :.0EuEx8gLuEupppuuSWVRh$hLJ,_^[UQeSVW~ uhE*YYtx EWhhhL, YYChdhLuYYu3@=~t#؅t/ShEWUJSHM6u9uuWMY3_^[hHhLW'J}YYuW,YUQQS]Vu 3W3@}E;u2jPTMYYu31ƅuhLPPMYCta!{t5hEV-YYt !}E>thhLVYYE!}EC9}VDMYu6WHM3Y9uuSY9u_9uVuIYHuVW Mj Wh`_LF 3҅tG B t u@ujjPRSuuVW9$uWHM}Yt uYC_^[UVutj6Z&f YY^]UVuWtcjjV 8 07VBu7hhLV uK!jV7 _^]USVu39tD9tVgYjjV7t>h iLV(9] tW;t PkKY_jjV/7 9] tFH;t ;H,t YjV;7YY^[]UM3ʼnEW339jEEPjhS,EyShiLV kEiEEiYYWWEEEPWWj EPhS0Et@EPShTiLVpM3_@UQQS]V3ɋW}~At ~ItIt>Itu3a;}E uwEUEt\Xd`p0i+u_^[UM3ʼnES3V3lWptxd;u f;u3hQ|P WǍP@u+¹;<QjPƅq XM hP@u+PWQBx urXMP@u+DžhphPWuu v{3Ƀ+tnHtcHu PWhjLVp  \MX@u+PWQw u\MP@up+03@9ht Wh|jLV z9hjpX9E u ǃ } ulPjWS&iplhQ0flpPu WhLjLVmlVm,} uHPPj! ~jXxf| Ef~Džt} u~PPjӛ ~b9Wh4jL} u"jXxf| EDžt&} u'jXxf| EDžtf~=$EBddxPhjLV^ xxTEf~t|PuׅxPp|jP|  pP|Pu(Ey@EWS$=MPWhiLAxPhiLV ǃU@EWS$LPWhiLVj-XM_^3[ZUQQejjEEEPEPhhuEt@EEt =H't33AtUEVW8Ǽj Yf8j Yf_ ^]HHtu4j.SFPj j.SFPjt:tFPTE3@'3UM3ʼnESVu9pW#PPu Et@EWVgKPWh,kLIW|jPU  P|Pu (Et@EWVKPWhiLSuXEVJPVhkLHj xXYf|u+XEVJPVhjL VY_M^3[UVW}7j3MQ@Pju E,Ey@EPW0JPhhkLV hTkLVYY_^]UM3ʼnES3VWDž\ @XDžT9MurV`SP j_WjS`5ESDždWCSRPWj RPWjRPRPj3`PEt MXM=MtITPXPWVuEuX;\j\PWVu,EM_^3[UVu3W} ;t$9N8t;Xu$9hthWViYYWE3_^]WVSWv}EjEPWUE؃ yhkLWYYjX} 7[fT\`h6FP NP yt+t$VPV\:YEt FP@FPu܃\u}uEE E3_^[UW\}EULPM Vt QqUsPta3Ƀ~vIMtGDPEE8tt4F;Etvut!SϋdYEu vuE0^}_t uS.YYEUXM3ʼnEEM S]V3W;0MĉE}ȉuu9t 3EjEPWU E;}hkLWYYjXOƃ\EBjPjjLusuu;|Wh`lLu EL'uj9sTueuuf=|Du3A 6u#7}$YhLlLuYt 7}Y}t~EW$HEDPtfj.MQPXWSAPEPh(lLu,DP(xEt+uċΉxYu M\uEF39u9sTuu3A=YE;69tMč\TLPKLE\t PSYYuSfYYu`MċU@u juYY7SSf uSw@PVhlLuwEM_^3[UE]UE%]UfE]UEwo$BA]ðB]ðC]ðD]ðE]ðF]ðG]ðH]ðI]ðJ]ðK]ðL]ðM]ðN]ðO]ðP]ðQ]ðR]ðS]ðT]ðU]ðV]ðW]ðX]ðY]ðZ]ÊE]Ð+B/B3B7B;B?BCBGBKBOBSBWB[B_BcBgBkBoBsBwB{BBBBBBUUSVu t tPQ:uBFPP3:^[]UUSVu t)t"}t"PQ:uMBFу}u3@ PqPf3҃:‹^[]U}r#UM +P< AtMu]UxM3ʼnEEMeSVW;EkThoLW}荴|jEPSFPuEh|oLWFYYaj8EjP Ext0E xɁ MxuhHoL Eh oLW#|YYuMhpnLW YYpHHt9Ht-Ht!HtHt E +E"EEE EjDMYVuhLnLWYYjjY3FHQP3WWEPMWjhnLWP ;tB" ;uQS=PhmL PSx=PhmLuvHM!~Yy}EPj uEPjى t hmLWYY3E܉EEEčEjEEF@DMYȉN 33;F PRVDRURPMWWWWv@QWvP= t?" ;uQS  u F@: t;?E؉]̉EȃxuI;vCQhqLu1EPE0pETWM $E9H;t MQP@EẼ }E|} 9]uhtqLuF0 ;EN8+EuPQtE } F0]~$tF$hz^0} u F$O9]FF$hoL+UQekTSVW8|h,tLSaFuj#X ND;N@tfu hsLSYYFDu hsLSYYFDu hsLSYYFDu hxsLSnYYFDuhHsLSXYY늃~ t@FphsLS jEPWZH @t%M;NthrLSuWbI3ujhSPcȋEڙRPSQ'd2;|;wӋtUы$t h|LV{YYDt4߮ \$߮\$߮\$߮$륃}xCHL tQPh|L0h{L0YY QPSRbX\|l 'v jjdS|bRP-|: v/jjdbSRP:bd`@QPSRaHL|l 'v jjdSaRP-|: v/jjdLaSRP~alh\L;|X;Hv XM HEM|t+x|33QPEPuESP|ExP$ t @t ‰EMx||d }'vjjduu_`RP|x)|6}v.jjd|x_uuRP!`tpEP PEPEPEPEP PEP PEP PdE`Pl PlEhPuuM Ptph{L0 0H3M_^3[UEV0PYu,u9uh|E0YY3^]UVuݖ jݖ(jݖ8Vݞ@jjV^]UUBHujX]ËM V3F0^tHtpuu Rу3]UUBHujX]ËM V3F0^tH t pu Rу 3]UQQS3VW]] 3=uE|LA:tGFu8u'EB}rɃ}sPquYF31u}s POYFS!~Y~3@_^[]USVuWvuu V; ]uu ppVu uVWSHC Nj DMYtkuDMYtuu SEGE _ WHMY3t.EWpP{B tFEwHMWHMYY3_^[]USVuWvuu V; uu ppVuu3@_^[]VWSqB N3USVuWt7vuu V8 uu ssVuu3_^[]ËUSVuW339^~V4oBGYY;~|6HMY_^^^[]UQW}tVe~LSVM3-}NMt0u UYYtWVSA OuuEE;G|^[_UME ;sV1k!3A;r^3u]UM ;MuVuW}3_^u@]3]UE M``]UEHtIHxu2HWz;}&V4S;u A;| APH[^_Ht]Ã`3]Ujju ]UM3ʼnEEHQHQHQPh}LEjPEhEH@u+t;E sE֋+ъ @u jE3M3UdM3ʼnEESVWjE3Y}]3ƙ+ցDyJBjY+3 F|Ѓe3ɋދ3҃|u;u3ɋAA;t;t;M~؉MB|;t;t;M~؉M;t}}ލu3t;|E;} ;uA:F;t:Fuu9}t-}u }tth}LjVG|4E+PE PTYYu jE3EƍP@u+tEÃu:FE+F;u wËU+ъ @uEM_^3[UEHHt&th?'E3]uM uBYY]Vuuu YY^]UVut'WvHMvHM~VHM u_^]UE eeEPuu uEE:VW}SGuj j[Gt;r{j DM3Y;twONONO SN ^FFFDMYFtOSwP'G tPPMYFt<}uuEtpuM2E)VEHMvEHMVHMYY3[9ut uE9utuYu9uu*PEHEEM_E^U3VuMM;u3-F E;SMW3f~j jx TMYY6PMYCWjTMYYC}u]EtXFCHHC{t4uNCuMu xfIEf EMufA{Eu GfFf EfGEF M]E(SHMsHMSHMYYueY_[E^UM3ʼnESVW}EPWj[ j(DMYtWPMYuVHMY3M_^3[xËMjFfYfNjYu fN N N >F `VWHMVHM릍EPWj[ ~j(DMYtWPMYEuSfKu쥥cjXfCjXu fC C C C `SuHMSHM=`Mu.jjjEu %`MPj`MYY39`MUEu]3@]UM3ʼnEES] Vu3ɉHd`tHlu DžlRu DžlWj3Y@󫋅lDHpPSjY _tpPSjY u Dž@}tuEh}Lj PEdhQ@QPStuSh}L`P3hM^3[Uj`jTMYYujX]ËM (3]UE P@uV+WE Wu 6P u vu3_^]ËUE P@u+VWEtt,t$ Wu 6 u vu3_^]ËUEt:t@u8t@8VWtP1YtG?uj WYYu0j WYYu PWYYu:PYtN;w+FFSPDMYtVWS 3[_^]UQQS3VWMM9Mt04 $PQh~Lh@VƃH@u+MQMQPVShuK9Euj XA7HM}Y~LuEuPhl~LwuHM_^[Ë#QS3j[@uj[uj[uj [tYtA A@3a[UQQVW}7(ʅdShKSJX(]X,]t33tthKKt+Kt Ku[`d#؃tH`>HP 6`d#߃tltP@u+3ҋȋ}#ƒt ;U|u;Mvn؆tt t u<+MUxWrM39tuC9u;9luSRQh~LVuLJlfPfTE Et)WZY"uh~LVLJ1YY3[_^UQQMV3W>U};t|<Cu89W t3Gu*QVE\LYYC uQVETLuYYtkuu ELLuQVq3G;;tK9t'h4LVYYuuE,LYuw3҉{ 9Uth}t!0u&9|thLV볋 uE}Lu LVuPh~Lu39C CS3_^UQSVuW>3ɍMEԆ9xt9u 9|;t9HuP;t9KuS9xti;Uu^juu ' EuvE39tC9u;;t19u)R-YEYu@ !C 3Quu EE 3AH K 3_^[UQ} ESVW8|u<} EtԆj uh\L tl N~0Etuu u萃 PMY 8EjuhTL` t8 FNt uu ut u{!juhLL t3FthLW芙YY\u u Num t@'juh,L t( N~ufhhLW6YYLJM<,tAMu<,uAMt&PYt EEuE8b3_^[jXu3Á|t t3@Ã|tÃUS]V(W} }~u ~ u33Ƀ~X$39F `|9~wYvvubNPVTF t/~HV V@~N  VDDFXfPfT'ff Wvu ~ )~jXF _^[]j jTMYYUVut 6HMYVHMY^]UQQMSVW} T(MMIU +]B@Mt/@U;wMuEu Pj EE MEPuu uW$EU];wU+]4t.Wuu jP!t#EE WSPj7Ut ^(V,UEtm];t]M+‹V@DVDVVHVVPV VTǂX0CDf F^N\FX3&FX;Utj7XW2YugEY_^[US]VuF;s6HM&VHMYYjXWt ~ O;v[;w;w э<;r<Wt RLMYDMYu6HM&VHMYYjX~FSu P蘤^ 3_^[]UE P@uVW}+‹Vu W tpP#YtFuj VYYuj VYYu PVYY+S؋EH@u+WuVG u KF;s3[_^]3@UETM ]UVu ujV t džl^]UM@@t-}t'uTU ]Ãu3@3]US]VW;|(t <u%=t=t ǃlW*}YplpF\t P f\Yhu-F(F N,N$VGpOtF8Yt$Pf8YuF(F N,N$GpOtE 3;uO9MuH9u@9pu8ȋڙ+F V$|uhLW蘓YYj4X3_^[]U싁l}%tE< t t u3]3@]USVW3$x@u+PuQ% uvujuhL t3C_^[]UQFXW};ro;vRhLSΒ jXokɉE;wMu~TP+LMYYuhLS菒YYMNj}FTWv`vT~TFT~X 3_US]VWjh$]LV&$ uRj VpYYtBG?tuWh LSӃo398}t}u;hLV%YYu*HM@hLx }hLVYYHMY9.|9s$d`QPQPhL _HL t.`dQPQP@hLd`@hpL;VElLuEhLG}uhdLWR  }Et P$ hTLW#P@u+PuW 3;i 9xt'9uh@LVYYuE LEEE9t M;uEȋ;t9t M;uE̋M;uE؋MЋIM;uE܋;t9t M;uE98t M;uE;ϋuuȋ tuuuuuuuuWQPuEPhLu}HM؆@t t uHMYt @@u<tlu3@u 9E0ejjS uEċI<Q0P"jSta}tF}hhLuYYEu,EwwPhLuEu E܋?ujuHYY}}tDu@9}hLu}YYEuPhEu[E܋}tjhEu XtuSYY{ujV e}j!jS}DEԃ HHfHHjhEu@ PPPVuEtĥLKȂLȂL?#EP3HPujjjjVQ F39t}}`d#ȉ}Et6u-hLVYYuuWhLuO }tu֋rY5jhEuA uuSjjPVu }thLS}YY4E EtM3ɋE Et3QPujjjjVO 8EЋeX}ЍO0PQYjYYthhLS}YYj"dO tdžZjWhІL dž0jvhhL u <~hPCYtGujWh_L衛 t ljWhL聛 tdžIjWh؆L^ ujWhІLJ džjvhhL! FhP艜YuE8*t @EuEPfYtt(0FPVT|}v;|;EvE}|!}vq,;u|q(;uvE}gLugLVq,q(RPQqDh8LWfE$^[3_UE@@SVWt}VfFwWY tTEE;u9]t SuYYEM 3_^[SuYY_WHMSu GVSSW1US]C@VWt=} t7POYt,0$x@u+Pu Q- uvu3_^[]u hLSd3 @UE SVuW3t tރuڅt jSYYE 83_^[]UE \t3;E]3]UE Xt3;E]3]UE t3@]ÍT:uPuYYt3@]3]UE t3@]ÍP:uPuWYYt3@]3]UET]UEP]USVW} XusM S X;uM ;tTj0KYY_F^[]UVu X ;Et Iu3\pPQRX8tTj0JYY^]USVuW}3jSJPjju h~QEPuuu `Qtu6E9Et#t')EEjj6z yjX É3_^[]UhM3ʼnEESVW}E ETjjSqz yhkLS2bYYjjVI]ShLa}fDžPSWuj0j@PVEPEPEPEPhLP$u&EEEE3PhpL`Pu hDLa j3ƅ9t:P@u+=r hL@PPeo H@u+9utHDžqAu+΍qL0 +ي Au3\0 PSPW=a99EtJuFH@u+pPVW`9PjPWzm8t hLgZHHHtFQ PPPPPhL_ j] PPPPPhLj\ PPPPPhLwj[ PPPPPh0L7},LuEPhL]jE3hLhL^YYjXM_^3[h|UM3ʼnEMESVW}Tx3Ƀ8E EH@u+؉|u&vShL\ Džjjru yhkL(]YYjjVDVjj~u hL7u h|L7빨thPLჽjVƅfDžƅ/DPPPVW]b9LjVCjjVu h8LEu h$LGthL7!\YYj8jVCPjPVWt hЏLu<u WxUYY[hL<H3;t09t(P@u+‹؋p@u+ƉƅttSPi s5FttP5Pi PVPW[n;bPjPW4'8t(PPhtLYZF|jfDžƅ^udSPƅh sE55DLSYYY,PuWujt􋅔CuZƅCj^+Ɖ||Ɗ5FD0Ph@LX |)u"jƅC3^T A|3 YYhLX PVPWY>;2j ^tS{XYYPj [SPWC9t h܎LIuPP PPPPPhLW u6P PhpLW{nR RRRRRRRRRRRQPPPPPhLVPu  uj^u7;~3P+VPWwu;thčL\j=YY3YhLBhhL;h8L4;M;A}9Xt,9܆t$h LVǃhLVNYYE9}tS褼Y;p9ltE9}t9 ut9 tE8uWhLV8M 9 t^EhjXuӵYuHMu迵YhLVMYYj8j*뿋E0SnẼYYt|9}t!9 thdLVǃMYY0 HM }ǃl7SNn 3E89u\h4LV>M ]EHM$ LVdžLYY3_^[U`Vu3W9te9xt]>S(j`QEPtE(3WlWV ([;uHMY3_^UM3ʼnEEPQkYƅt,hQPEtPPMY3M3wjUESVW} uǍP@u+XSDMY3ɉuMjXE<%uWvRGPxYtCGPxYt1GEGEjEPEPE}PuEu}t} r)ME1AMGKuE1tE03_^[VHMYjVUQejEPEPuu ut3Vut utYE^U EeeSV0W}ELEVSYYt8k +ȃ}tt[wS}u+E}BE.u4}t.}t(GeE0u}|EM 3@_^[3U0M3ʼnEESEVW3u٫3ɉM<:uC<:t3]ԉMM;tEE̓LWPCEYYuLWPEYYt+E؋M E}EE:3]9}u 9}uu(E9EvEEFE}};l9}tFM;VhLpYYt Dž!VhLjpYYtDžPhLS\fnYM_^3[cUW}3_]UVu t{AYYtd9U|9sKuu Ai+ȃRh0LVDjX5Q(E EtiPVt-YY3^]UM3ʼnEESVW}7EE Et  EDuj؃uhLVDYYj*XM!u;@@thLVCYYjX 39t;]v E hL39$994|EuEPShLEEEj P^)WMQP RE H@u+PuPQà +u džEP@u+؋E3M_^3[daUESV0W39lhp;t&WWWЃ;tvPhlLVB jAXd;t(jVЋShLLVA;t8Sh(LDuWWD膏 uhLV6BYY3_^[]UE EVtYu`d tDXHHt'9M5|9U w.hLVvAYYdž39M|9U rhL3@^]UMS]V3EEEEdEuE@ENE#уt~Hu+F N$3; |;EsE}t2EPuW>EQ'eF F$u)F( F,u!jSeYY~jp@t ShPL7> )dLJ]39FLt9u NXN F$~Nu EF V$; ;FE+FF Et}utjp@zYYt@uv$v vvv60uhLSq=E,)dLJ"v$v vvv6uhpLS:=$F+F EyeEF V$v$v SO 39Eu 9FLu 9Et{9FLtI9uANF#ȃtNX3;| ;NvvvXjWH@E~L}uuv\jW@EfL}ug39A4t9Ev 9l9Et@<0ujW蕼YYtEMaUEx}Cjp@YY0ut&h0LS;E)dLJhLS;E;Hu2F;Lu'hLSm;3@YYMlhpLS;YYj!XE3FhLL0Sǃ0;luh8LSw;YYjP5Ph LS_;j8룋EF\EMQMQEWSP4u79Et$<ulthLS:YY3^[U eS؋G G$uG( G,u jV3YY (u;yXu5LJ6G|#V!YY+EB<t 3҃yX‰UMQh@P ]33ɉ];u ;*E9PY9M949u+hDMYuhԘLV9YYjX\3҉U;}nM< uG B 4u2`d#كt`d  E]B9]|;tEPEPx53ۃ;94tuujV7EG(G(W,;`u"G,;duhLVLJ8YYM;t+!9tw,w(V ~ 3[UQQSVu W}3ɉU ЀMu UM$*<u9htM 9M uQPju3E 3Ƀ} uhLV7YYj7X;t4E u9t&uEPVFP  M9tE tWE~PJY13}Wt&FXt NpNtHFhtONxN|HBu9RP3;|h`LVI6YYuA}Y-w7V@3Ƀ ;39QWVN FPNT#уt2QPvtvp\Xw7t2PheLV66.vtvp\Xw7D2Ph@eLV6j]9$uAFPNT#уt2~pVt;u;t$ u+QPh,LV5j$u!tEx thLV5YYu|Ytj*3MjX3_^[UMVv,W33tuu Qփ \}}3Ru Su 3@*[u&9uu t3G3BO _^]UQQeVuW} SNj ֋9M|9UvƋ+E#+Ӌ9M|9UsƋEiWVRPN3[; |;EsEх|;ve _^USVu39uhLV3YYjXV葳YYE;TWX\ ԆHMhY_u`x`|d9tVIY9tVܸYE;u]Vdž(~6VKVx ;t PVYY;t PVYY!Ԇ!؆E^[]V33ъ F t?u3@B u^ÅtV3F9t. t ?u3tf%2@0+@B:u^U0M3ʼnEe}S] VuW]`t9\|Ph$LV 2 j/X\ džtItHMYPMYujdžEPEPhLS P]PMYE؅thLPMYYu E؉E};/ej?WgYYt;?tj/WYYtj/Wdg3YY;t@EU.8u {/u]M8Auy/u EM8t9Utj9Ute}Mj/W|YYt }uFA{/u ]0j/WfYYj?WfYYtt;stMM؍yAu+ϋDPDMYuuHMYsWuS>M MM9M t&0E4EԆ$ E$EtǼEO 9MuEE9MuEE9 Mu=MEIIItqIttMQMQPuu/3;9u3HMY~L9u uEuPh̚LEuHM93jX3HM#YeMQMQPuu6}03;uO9utH3HMY~L9u uEuPh̚LɃuHM93tEG 3_^[UVutP'.ưV.YY^]U} S]VWutujVhTLZP t\t2PRYtFu>tWV3P- u+!3Fuh0L3$SS 73_^[]ÃuhL3o$S0 'j X;|hL3N$YYUu uhYY@]UEP@u+@VPDMYuxSuPMYuVHM3Wj?S]uZYYEtWjSh F! t0jSh F ujShXL ujTLY3u C/jShLL輵 uE H8/Et0;Ew)jHLY3uE/ H8/Et;Ewt|Q ;|#q9u | 39u …yQ9AtPME~Bpt9Q ;|&y9} |39} …~q>t C؋\UKH M_M^H[USVu3;uEW9]t_uu uH }U ;|HFH;|?3;Ë3;u0F~ VHN \LH `L0HG^1H ;|x;| 3;;} F HNXEF E F^_^[]U}Vu 3M!uu u/F 9E|-F9E |39E ytPVpp F 9E|7F9E |-39E xFtN H NHNH'euFPu uN HM1^]UVW}u F ;>|_^]USVuW}3;u>:tNPu eUYYtG:u8t1GPu ?UYYu8u8t3_^[]UMED:U tH;s3]UQQFF}ËNlESWEyj Z+Ћj _j EX+‰E | j _)EU3Mjd[jhm+ȋ+M#؋‰ELM؋E‰ENRP؋E‰EF ؋E3WjPSȋFڙWj<SQȋFڙWj<SQlȋ_[UdM3ʼnEEeeSVE]]]W]]̉]ĉ]Љ]ԉu}ePKYuFuPHYjY3E}fEPhLV^ tE܍P@u+‰Ee9]u@}ELwEL3E0EPTGYYEG|މ]9]uo9]u/E8L3E0EPGYYu]EG |]9]u;9]ehLEWPFYYu. E؃}DrÉ];u}|}뫋GkjCEPEPWd ;9]uh@LuYYj=j_Ẻ]EE}ЋF8Ev4E̋EY;t.uM]EM}ĉEvEEY;tN 3ɍURURURv SU#PMjSjv0QvPFuHMFYtj&= t= uEPv MP Ftj8XẺF<3_^[U vHMYVHMYu!;_^[]UM 3;u3@]ËEPPP 3]UxWuN u3bpu ju1~uh$Fp{<YYFu2vu ju[uFt P;!~Y_]US] ]VuW3tb@tuSuVYYuDH +N+;w9@FQPEP H +Nf tx|_^[]Ë+P@FPEPI +ǃ FUU u3]ËAI Vu  ^]Uu詑YPu蟑YPh(L2o ]U8M3ʼnEME UVuW}38;u3RqY;ujX;u@LSPVh,L3ۍQ tHMY t!hEYh$LYYhLYxpVQH RhLY79p$tJHMDYYPhȡL4YY39X$;hL3YY;p,;ufp PMYHj/Wnj\Wntt ;wF stpVPMWHMYYj\VDYYuj"VDYYtQƍP@u+DPDMY>t\t"u\@@A9uVhLHMW-P(Q2H,;u ;ujp PMY;j/Wmj\Wmtt ;wF stpVPMWHMYYj\VCYYuj"VCYYtMƍP@u+DPDMY>t\t"u\@@A9uVhLWHMHMX@t#PhLtYY(x '7hLEYYuՅh|LYH(u;tpjQH }@t p0jQHp js hE>YYt%h$Fs 5YYtr%W;tL4s jP3\nQjQ8 uHWhjPUu+ts hdLK j^@$t9w$t$hXLYYuQtVWHMYj^3j^u$hLLHYYt+PHMHM AHHMHMYY3[M_3^(UE3ɉHH0H ]U ESVW}3ۉEE]MwU99}u] SjW EcjXgFjY;M$C 0|9~A|F~A<w#FCE 0] UFFe0jEPV輵 F V$uuB8"ZF; 39F u9F$uFFN$F ;M| ;ErEMQP3YY؋E39u!9uSu jW E3M9ME3)^ F$] )]E9N u 9F$uF] E E_^[Ê< u3FF(F)< !ji< tq< tm9|CtPLMYhLJDMYe  Eu"jWV EzF; N; NCE] U< t< tFCE] UFq3@ujj; EMQP YF(Y>ӿCbCC*CCOC]CzCUEHt9Ht/Ht%HtHtHtE]øIL]øĢL]ø\L]øL]øL]ødL]Ut4= t-= t&= tPVpPuhL63@]3]UM3ʼnEESVW} T3ۉx,j/V}MĉEtp;YYPt<@:u+PDMYE;uj ƍP@:u+PVu z@:u+‹x@:u+ǍD0PDMYE;tpp@:u+ƋEƍH@:uVp+h<FD8PuX}3AjP\M`EM؉TXl@QMQSSSSPh4LEEMSL]]X]]Džhd]]P hL%Yt*hLuuHM EPMPD@PxPXPEPSLPjShuEtPMPE9]tuMP@]]EhܦLY49]teufE EfEEPjEPuWs}|EPuuuWKE;E9]tuMP@]]9]tuMP@]} ] EPjEPuWş}}2}PuTEVuDMYE;qMQuPuWiY9uPEt]uHMYEPMPEPMP$9]t uMP@hLuYY[hLuuHM 9]t uMP@9]uMP@h\LuHMY|PjEPMPEPMPh@LYt$EPMP$|MP@h LD|uhLVM |P@xfEuxuE LХLPhLV 9Xt j EEPSEPMP,hLYtEPMP$hTLEPEEDMYE;uj^h3@PEDMYE;u u࡬MP@ֈEPE EDMYE;uu࡬MP@uSdPhEPMPdhDLYt&u࡬MP@u졬MP@uMP@&EEEPEDMYE;uu࡬MP@u졬MP@u?uuPfuMuMQTMuMuMQ?M$uP@u졬M]]P@uM]]P@u]] EufEEPjEPuW?y}oEP9Xt3jEPu]W u}tJhLuYYMuuuWE;E9]t uMP@EPjEPuW}}uEhPhLu`}tEPEPhLuTEVuDMYE;MQuPuW39u*E9XHPSdPEPMDžhE E]]PhhLYt!9]t u࡬MP@9]u}t4uh|Luj 9]t u࡬MP@9]uuu࡬M}P@u#}tuh|LP Uuu}MP@8]uhL}TLt8LPh Lug 3hLuYYu&hLhLhLVYY9]t uMP@jEhPhLupuHMEPEPh\LuHj^uHMYEPMPEPMP$fjh,Lu uHM 9]t uMP@j^hLuuHM EPMPEPMP$jXM_^3[Uu uh<FY ]UM3ʼnEEVu ~t/~ t)3M3^P(YtuPPPmuhHLP%YYtAPPMYtVFH@u+P]YF PF(Ytu8,`@TjX%UEP@uVu +ƒ>Wtj=XWu腐YYuj~3_^]UM3ʼnEE EԋEEEEEEE EE$VW}EEPM@LVPDtjX^ESXPM]P@SDM3YE;t6E;tL8tHXQuPk uXP7 YYtjX[M_3^ÍXE]ԍtPEPMSSuSjVSP tjC[uHMYjE^wE]uEEE؋EYuEx@:u+PuEEEEȉu]]]EEE]YYEtP|PEPEPSEPSShuESPMP= t%= t;t*= t#EPMPjEPEPMP E@PDMY;uEPMP$uuVEME0E EPMP$EPMPukYUVu6HM&fY^]U eeVu ƍP@u+t!>=tEPEPVG u)MuhPLuYYj=XEH4MH83^UVuFW3;tPMP$vHMY~F;tPMPvHMY~v(?jv4~(HMv0~4HM ~0~,_^]U(VuVYEPMhTLPDtjXDEHSN,PMP@v,DM3YF0;ujXEW;t!8t~ Wu Ph ;~(^(jDMY~;t>3EPvMSSv(SjhTLSP tjCjDMY~;ujm3v,E؉EF0]EEEYE؍EPEPEPvMSSSSShESvP= t= t;t= tj8X$EPvMP uuuv0SAG_[^U8eSVuWjE_v83ۉEЋF4C]̉}Ev,eEEE܋F0]؉}EYYMQMQEFMQP3WMQWWWhEPvMP;tPhLu j8X!uuuv0uFVc_^[UVu tvDHMfDVHMYY^]UQeEU SVW3t=t Nt B@@=t3@i8"u@EUtDNt= t$ t"t,t\uuG B}u3@Ņu9}u3 M3_^[ËU=Mt輣uhYY]jhM395Mu VVjVEMZf9@tu6<@@PEu f9@u܃t@v39@M药uj]YujLY襪uXyjYEM襧MyjYYyj YjgY;tP}YM MP5M5M E9uuP,.E MPQ諢YYËeE܉E}uP EE 谰US]woVW=Mujgh/YYt3@Pj5MEu&j ^9Mt SYu+0*0_^SҰY* 3[]ËU}t-uj5MEuV*XEPg*Y^]ËUQeVEPu u蕰 u9Etv*t m*M^UWVu M};v;r=MtWV;^_u韰ur)$CǺr $C$C$CCCC#ъFGFGr$CI#ъFGr$C#ъr$CIwCdC\CTCLCDC=Mu5jhCE3A;u M$XEEu +tyt tNt(H5MEE;toVEMa5MEE;tNVEM@5MEE;t-VEM5MEE;t VEME}uE8]j,YÃt$t t~~#藮Gj h M3}}؋] KtjY+t"+t+tY+uC[}؅uTMMUw\YpQÃt2t!Ht;#빾MMMM MMEPEE3}9Euj> 9EtPY3Et tuO`MԉG`u>OdMGdu, LM܋ L L9M}Mk W\DEEuwdSUY]}؃}tj脪YSUYt tuEԉG`uEЉGd3褥ËUSVuF Ȁ3ۀu@t9FW>+~,WPV{ YP ;uF yF N _Ff^[]ËUVuu V5Y/V|YtF @tV PZYY3^]jh@M袤3}}jcY}3u;5MM98t^@ tVPVYY3BUMH t/9UuPJYtE9}utP/Yu E܉}F3uࡴM4VYYE}EtE#jͨYj hhMȣ39uu V Y'uYuuYEE EѣuaYjYj hMl3ۉ]3};;u ֪39] ;t܉}WY]G @uoWmYttȃ MPMA$u)ttMPM@$twDM9]u#W EPSu WuEWV袴E E輢uLYøpMáMVj^u;}ƣMjP!YYMujV5MYYMujX^3ҹpMM  M|j^3ҹMWMt;tu1 BM|_3^/=4Mt5MoYËUVupM;r"вMw+Q;N Y VE^]ËUE}PE H Y]ËE PE]ËUEpM;r=вMw` +PY]à PE]ËUME }` Q轥Y]à PE]̋L$WSV|$toqtUL$:tt :t u^[_3Ê:u~at(:uAtf:t3^[_-G^[_Ë^[_jhM]]3;u9M t舧339M ;t3u;;t9M tډuV7YeF @uoV Yttȃ MPMA$u)ttMPM@$te}t:M t2Nx AV賾YEu ;ue G}< uE ECËuVYjhȓM39EuW3} tG @u_WYttȃ MPMA$uttMPM@$uuEWYYeW誯WujuEWV,E3M9MH=Ë} WY; MuU=MV5Mu3cWu95$MtSuJ5Mt@}t:uFY'P;Y;v<8=uWuP tu3_^]ËD8jhMJ39Eu軤3?VuKYY;tjۢYeu!YEE E+jաYj hMМj虢Y3u3};;uej^03ut7E ;t039u;tuY;tS%pjV| 3;u ESVP ;u!E ;t0}EE^WWWWWIjYËUEu 3]Åx;Mr Zދȃ MD@]ËUEuS ]Ë@]ËUhxLEthhLP4Etu]ËUuYuEjYj-YËV臖V讝V!ViV訿VV苿^ËUVu3utу;u r^]ËU=LthLYt uLYhEhlEYYuTVWhD dEhEY;stЃ;r=M_^thM{Yt jjjM3]j h(M:jYe3@97֋5M֋5M9]u9Et]܉]ЉE؋}ԋ]EE}EsEtЃEEE}EsEtЃEE }u) +}O;]rOt V\Yu}}t 3ҋu+WuVYP^ ta;wM+;rP})EVP9YYt)EFKEEAEN +3u N Ej hHM39u t!9ut39u;uz3+uHYuuuu uPEEEuYËUQSV5EW5M5M؉]֋;+GruS؍GY;sH;s;rPuqYYuC;r>Pu[YYt/P4EMu=E׉VףME3_^[ËVjj ǜYYVEMMujX^Ã&3^j hhM贔ieuYEE EДHËUuYH]̋T$ L$ti3D$ur=MtWr1كt +шuʃtt uD$_ËD$ËUVuWuR DF t8VWVVPmyFt P`fYf _^]j hMmM3uu ؚ F @t f EyVYeVZÍT$D$uA3D$u33% D$uÍT$D$ %=u T$uutQ$\$qYatBD$ % D$؋D$% D$t=fl$D$t-LtA:1-@Lٱu Mٛũ=M \$D$%=u<$f$ffd$~D$f(Lf(f(fs4f~fTLffʩuL=|}f=2 fL$D$f.{$T$ ԃT$T$$D$~D$ff(f= |!=2 fTL\fL$D$fШLfVШLfTLf\$D$̍B[Í$d$3D$ST$t :tτtQu WV ؋ ~333ƃu%t%uu^_[3ËB:t6t:t't:tt:tt^_B[ÍB^_[ÍB^_[ÍB^_[̋T$*Zzr b$BB 02CVB$dBu B;L$ t D$ B$Iu@ B!D$BItVWt$z(v_^+UP\$XE&EEEEE+sd;5tSVjPh.DVJ^[t0C Pi tC =02CVu C$ tS CPVsjCӋZzr D$\bb]ËUVux k;0|k0k^]ËUSV}3;uL"W9^$ujW請YYF$;u L_^[]uv$PWVsuSSSSSɊ̋UE3;MtA-rHwj X]ËM]DjY;#]uxMÃu|Mà ËUVMQY0^]Ë HMDMV498t;r;^r9u3B;r,=s%jPQ? t DMDMHM3hhȔM蕂33]ԉ]f]]]39];u%3s3ɋE ;;t۲ @8twtruƈM@8t:t}+߃)}};]r\}t3;v uu+ ;w;Ew[PuV'YP t{tdE+)E$V4YtR}t"MEFKME&E} tu ju "N +3uN j hM;s3u9ut/9ut*9uu-} tu Vu z3@su]Yuuuuu uEEEuYËUuuu juZ]ËUEu@ z3]Ë@ ]ËUEuy3]Ë@ ]jhȕM@r3}uj^0yfWYeg W[Yt.WOYt"WC4MW3YYPMHHE 3qË}WYËU]QU SW}3;u:yeVWYu9_}_jSVv E;W u+G%O+ى]t<MD2t;s: uCB;r]}uxG Wu!U]u+MED0tyjju ;Eu GM 8 uE@;rG @juut y89EwO ttGED0tEE)EEE^_[j hMo39Eunw(u?Yeu*YEE EouYËUVuF uDg}F uVE eYVF YyF ttuFuu VYPM3Ƀ A^]j hMo39Euv?ut tuu?YeVu u EE Enu~Yj h(Mne3uu0u]t t@uׅt@u}G=v뿋}uVYeVVAYYf N t Fj_-E u WuYu MMN  N ~FfE EmuYjHl; hMt MHpu螱شM̃=M\$D$%=u<$f$ffd$uUY=Mt2\$D$%=u<$f$ffd$u $r ÍT$R<$tPf<$t-xLz=@ML MI-zLzu|$u-@L=@M MZ̺L LML<LM=M\$D$%=u<$f$ffd$uUI=Mt2\$D$%=u<$f$ffd$u $ ÍT$R<$tPf<$t-xLz=@M M-zLzOu|$u-@L=@M M蠿Z̃=M\$D$%=u<$f$ffd$uU=Mt2\$D$%=u<$f$ffd$uu $ ÍT$荿R<$tTf<$t-xLz؃=@M M鷿-zLzu|$u-@L=@Mc MlZ̃=M\$D$%=u<$f$ffd$uU=Mt2\$D$%=u<$f$ffd$u $貾 ÍT$]R<$tmf<$t=?s+=@M M}w:D$ % D$u)-JLtҽu|$u-@L=@M M#Z̃=M\$D$%=u<$f$ffd$uU)=Mt2\$D$%=u<$f$ffd$u $b ÍT$ R<$tmf<$tɼ=?s-=@M. M+w8D$ % D$u't肼u|$u-@L=@Mʼ MӻZ̃=M\$D$%=u<$f$ffd$uU9=Mt2\$D$%=u<$f$ffd$u $ ÍT$轻R<$t6f<$t-xL=@M 0Mi&u|$u-JLt뻸=@M 0M诺Z̺QMAQM̃=M\$D$%=u<$f$ffd$z~D$f(`Lf(f(fs4f~fTLffʩtL= |}f=2  fL$D$f.{$T$ ԃT$T$$7D$~D$ff(f=|%=2fTPLXfL$D$LfpLfTPLf\$D$̺LL|z̃=M3\$D$%=u<$f$ffd$~D$f(Lf(f(f(f(fsfs5fs4fT%Lf~fЋL$ fff~=|=2 f \fVft$D$f!D$=~D$tf|f(XffTLf LffTfVĺu fD$D$ÃfD$T$ ԃT$T$$aD$̃ $譸 ÍT$XR<$D$ tQf<$tu=@M @M逸u,u%|$u"u|$u%t-@L=@M& @M/Z̃=M\$D$%=u<$f$ffd$uU)=Mt2\$D$%=u<$f$ffd$u $r ÍT$R<$tLD$ f<$t-xLt^uA=@M< PM9uԩu|$u%t-@L"舶uŃ|$u-L=@Mж PMٵZÃ=M\$D$%=u<$f$ffd$uUI=Mt2\$D$%=u<$f$ffd$u $" ÍT$͵R<$tLD$ f<$t-xLt^uA=@M `Muԩu|$u%t-@L"8uŃ|$u-L=@M `M艴ZÃ=Mtn\$D$%=u<$f$ffd$uA=Mt<\$D$%=u<$f$ffd$u9L9LcUQQW}ufSVVh?bEYYMظ#f;u_QQ$YY~'~uESQQ$jHM EES\$E$jj,WQQ$V]SE^[_ËUQVWVh?EYYM#f;uwQQ$ YY~8~%u.EW\$E$jEEVW\YY4EWE\$E\$E$jj3$D{EEPQQ$EM y +;|y +; = ~1W\$M$\$E$QQE$jjx=~$PQQ$ W\$E\$=}$ EW\$E\$E$jj"=}PQQ$ PQQ$yV]W$E_^ËUYMH]YȋAiCÞ&A%UW}3كE 8t3_ËU4M3ʼnES]VWu} M̋tu#c8]tEԃ`pẼ~EPjP蒠 HtFɍEPEVP ȅtAƉ@t ]܅tHDt>-pMut$ADz]4"A]܀}tEԃ`pE܋M_^3[fËUju u ]ËU SW3j3Y}]9] ubME;tVEEEPSu EPEEBmMxE EPS菍YY^_[̋L$ W|$VStt9u~Ѓ3ƒtGt!tt uσ t$u u\"t=t)uu8˃ttu[^D$_ÈD$[^_ÉtȺ~Ѓ3‹t܄t΄t*tuĉD$[^_f3ҋD$W[^_fD$[^_UV3PPPPPPPPU I t $uI t $s ^̋L$ WVSًt$|$u 't+t/uuatt7uD$[^_tuutu[^D$_Ét~Ѓ3‹t܄t,tt uĉ3҉3t 3uwD$[^_ËU}|)}r!M |Er+EMEMm]x]ËUeVuuUj^0#_ j$hV"E tӋ@ME|@Ws j^0뼃| &AwSWjh3PQGHF+yjd}M؋Ǚ_jh+؋EDAڙRPVG+jQSRPCG}U}M|sGEǀ3UȁEyIAu jdYuEluAU2EȁyIAu jdYuEluEEjSuFWFjFhRPFU}Mu MF3A9B} A9|QIN+jF E Sp0FjY3ShuWVgFjFhRPFSUj_^ 3[^ËUV tuVYY#^]ËUVuW3}}};uj^0\TSj$hV] ;uj^0\(C ;|;r|o@vj^0[_^EPYEP-YEPHYK;|jv`E+EPV}MYYu9E;VdY,E)EEPUVYYYF SVdYY<9Et,VYt!EEF ȋU+]Eڙ+jjYc}uSWVt#u@FPuEuMPUtBF9]w9]vE+}8]tTMapKME9]u 9]w"9]vEj7K8]tE`p3^_[ËUjjuuu uZ]ËVtt;tWj6Y P謄Y_^ËUSW339]~"Vu6u u u G;}|^_[]SSSSSMJ̋USVW}h3SW蘮u  u3<.u1F8t*jPjP uSSSSSIhHLV] 2;} <0u@.t|PVj@u;} u@sh_tcPEVj@@} uQsLt,uCPEVjP{u4,=5E whHLVYYk_^[]3PPPPP=USVuVu ue 3ۅuAF@8tPhEju ug8^[tPh0Eju uE]SSSSSH̋US3ChU] IYE=WxvXQhdL5LjSWFXELEhFSW EH1M0$YYteE0E hdLEE0jSW}L|}uUFP,EtPӅu vP腒YFTtPӅu vTnYEfTfLFP~HZ3PPPPPGuDFP=,E3Y;tPׅu vP%YFT;tPׅu vTYFh^T^L^P^H_[ËUM3ʼnEE SVuW}dE\`<TKXhd}>CuS~uMhhEudQc u't ffGfG`t dC3PPPPPFV_YP;s,VhEYYVX/YYLlVPYYlPSP CTlPWh >t P;r LE@PVWXś%39\tjS\ 9`tjT`袐 huda uh VVVVV3M_^3[ËUM3ʼnEESWph:S\PPPhxPhu3M_3[諟sHxPYYuCHӍxP^PtDYYltCHphD XHAkjPd8PqFxQtLlQP` lXCHPjPPd p\tFdV;t6td@PH@td|-tt#PdHturjvxvPjhȪLjjE3 t<3f!Ex@rh5MxP @Fpu \Fpk VLYt1hlCH"HYXLFh$Mt.p4,Eu4ٌsTьcLYYplY3PPPPPB̋UM3ʼnEESV3ۋWh;t;t PYɋDHDžpt;8L0xC&x_hLLWAYY+ljp;;DžlLpPW6 u6ZY9ptl L~ChFSZ3YY;u ;;lDWSxhPݖuTlh=xxPtYtt?t G? 39thVVVVVq@3xSSShxQP;t\~Ht57xP!YYtxPYu!ptC~39pu9tt3M_^3[jhHM8e}vE@395u|Npe3GWh;@YY؉]܅j >Y}Nleu MXYE} th$Mu YYt=Mj =YE~lSW{Sy Fpu? Mu67hhM{YYhM شM M(Me.]܋u3Gj i<YËuj ]<YSAySyYYE E7ËufpËUSVu M];sTM胹~EPjS{M Xt}tE`pE胸~1]}EPE%PYYtEjE]EY5*3Ɉ]EAEjpUjRQMQVpEP/$oEt M }tMap^[ËU=MuEHw ]juYY]ËUSu M谣]sTM胹~EPjSNzM Xt}tE`pE胸~1]}EPE%P}YYtEjE]EY*3Ɉ]EAEjpUjRQMQhpEP.$kEt M }tMap[ËU=MuEHw]juYY]̋D$ StRT$3ۊ\$ t 2trt2urWߋ_t 2t@u[Ãr 3˿~3σtJ2t#2t2t 2t_B[ÍB_[ÍB_[ÍB_[UV3PPPPPPPPU I t $u t $sF ^ËUSuMz39]u#U";8]tE`p]9] t؋EH;uu u YY3pEju juhQP/ ;u 럃8]tMap[ËUju uP ]j hM23}3;;u蟯j^0m:@3M ;;t39];t3u;;t8u^S2ÉuVY]F tV藞Y^^ ^Vuuu gE 9t33ۋ}uYËUQej@uEu uPEQL$+#ȋ%;r Y$-U}u蝮 肮O9]u\t /t@:u8t)@8t$:t\t /t@:u8t8Pu3@3ËUVW语0設u u u 荭t0$8"t3uju 0jM _^]ËUlM3ʼnESVu3W} ;u97;thTLV92YYtj^00~:u:t8^tP+1Y`/SSSPSVDEhPLV1YYtPhVP;VPPYt tqV@Eve9t JYjSSSjjhDž},ʃG W$GOG(O,P9Yt_ uSSj@SVP:vW :9u9u_ _$xPP -ҋXu'sE3j YC0EN;sр>Xus%j^0$]jb[a E jW|YYt 8 u {tCؙM3Ǚ輙[_^]ËUVuu裙p$3V=@PV #^]jhh@M%}}u 3ۉ]3;;uaG$j0SV u1 ;|;=Mr 뮋MED8tuM!Y]ED8u$豘 MEkEv$48XE%tt;tXEP臘Y볃u fNMN3AfN3fNfN fN ^(^,^ ^$^^u^fSEPSSSE48TE#EFA3fFfF fF fF@fFEPE48PEJFEt $ fF9]u 9]u^ ^$ZEPEP ]ËUSVuuMuU3;u$;t Г8]tE`p3uM ;u;uW}9_umRQVĽ 8]tPMapGJD;t=3;tEAJF:u.^;t RSV> 8]tE`pE_^[F3A:t;uވڋUjuu u]ËU eWjY3}_u9E tV6YEIuuM;wEuEuu PUËUVuEPju hDv^]UWVu M};v;r=MtWV;^_uur)$`qDǺr $tpD$pqD$pDpDpDpD#ъFGFGr$`qDI#ъFGr$`qD#ъr$`qDIWqDDqD9ur9w}v1E"t MMEt e]MuE_^tMEtEM؃ىEM}tẼ`pEU[ËU3Puu u9MuhlMP=]̋D$L$ ȋL$ u D$S؋D$d$؋D$[WVS3D$ }GT$ڃD$T$D$ }GT$ڃD$T$ uL$D$3؋D$A؋L$T$D$ ud$ȋD$r;T$wr;D$vN3ҋOu؃[^_UE8csmu*xu$@= t=!t="t=@u23]h wD\E3ËU3M; Lt @r3]ËL]ËUM3ʼnESVuWV3Y;ljYjYu =dM6hLhMW! hMVSfMhEuhLSV t 3PPPPPV@Y=u Fd.=u Fd=u Fd=uFdvdjY~d`QY^`[_^]Ã=Mu(LV5MW3u<=tGV+YtujGWYY=Mtˋ5MS3VN+>=YXt"jSoYYt?VSPM. uG>u5M9\%M'M3Y[_^5M\%M3PPPPP^̋UQMS3VU 9Et ]EE>"u39E"FE<tBU PF-Yt} t M E FU Mt2}u t utBe>< t< uFN>}t EE3C3FA>\t>"u&u}t F8"u 339EEtIt\BuU tU}u< tK< tGt=Pt#HYt M E FM E  %YtFU FVtBU ME^[t ËU S3VW9MuIhMVSM`EM5,M;tE8uuUEPSS} E =?sJMsB;r6PY;t)UEPWV}E HM5M3_^[ËU SVtE3;u3wf93tf90uf90uW=pEVVV+V@PSVVE׉E;t8PYE;t*VVuPuSVVׅu u,YYuSlEE SlE3_^[ËULVEPEj@j ^VYY3;uM5M;s6Hf@ Hf@ @! H3H/5M@P;rSWf9ME;EþE;|9M}kMj@j ZYYtQM ;s1H```3f@ f@ @/@΍P;r҃9M|M3~rEt\tWM tMu PXEt=4MEEFhF P|EFEGE;|3ۋ5Mt tNqFujX CPdEtBt>WXEt3%>uN@ uNhF P|Et,F N@Ch5MxE3_[^ÃVMMW;stЃ;r_^ËVMMW;stЃ;r_^jEEV5MEu5MEV5ME^áMtP5MEЃ MMtPE Mjh`MhLEuF\PLf3G~~pƆCƆKCFhMj Yevh0EE>j Y}E FluhMFlvlDYE3Guj pYj gYËVWXE5MЋuNhj% YYt:V5M5MEЅtjVYYEN VTY3WE_^ËVuj$jY^jhMuF$tPTYF,tPTYF4tPsTYFt~t WWM&YM|ܾM_t ~uPӃM|^[ËUE4ŠME]j hM3G}39MuPjhb_YYu4M9tmjBY;uNw 3Pj XY]9u+hW|EuWBLYw ] >W'LYE Ej )YËUEV4ŠM>uP#YujMaY6E^]ËUE@M]ËU(M3ʼnES]WtSFYjLjPQe0 ffffffEMDž0IM MEj\EPEuu tSQYM_3[ZËVjVj V8EPE^ËU5@MEt]uuuu u3PPPPPËUVW3uIYu'9DMvVE;DMvuʋ_^]ËUVW3ju u u'9DMvVE;DMvuË_^]ËUVW3u u_YYu,9E t'9DMvVE;DMvu_^]ËUVW3uu u u,9Et'9DMvVE;DMvu_^]ËUM3ʼnEE VuW34809}u3;us8scSML8$$?tu'MuRs 7sD8 tjjjVVQZYDF@l39H P4E3;`;t 8?PE4 3,9E#@?g $3 ǃx8tP4UM`8jEPKPYt:4+M3@;jDSP C@jSDP n3PPjMQjDQP C@pE=j,PVEP$4`E @089,j,PjEP$E 4`E,08<t<u!33Ƀ @D<t<uRDYf;DI8t)j XPDYf;D80E9@8T4D83ɋD8?D49M3+4H;Ms&CA u 0 @F@FrՋH+j(PVHP$4`EC(8;;+4;El%?49MH@+4jH^;MsCΉ u0j [f @@fƁ@rH+j(PVHP$4`Ei(8;a+4;EGK4,9Mu,@+4jH^;Ms;,,΃ uj [f@@fƁ@r3VVhU QH++PPVhpE;j(P+P5P$4`Et (; XED;\,+48;E ?Q(Qu448`Et(D8 XED8ulDt-j^9DuXm `m0?DdmY1$D@t48u3$m m 8+0[M_3^KRjhЗM)]ul l x;Mrl l oҋYjhMU]uk x;Mrk ڋ^^N 3_@[3^]ËU}t'Vu F tVpHf f&fY^]A @tyt$Ix  QPc YYu ËUQC @VEt {uE >'} ~0EM E>u?*u˰?~} Ճ?uE^ËUM3ʼnES] Vu3W}uZliu+]i*t `p7 F @u^VPYPMttȃ MA$uttȃM@$q3;g C39y B@Dž W @9} DžjugucDžW9~~=]VYt Dž5EGPPSP5MЋtuPS5MYYguuPS5MYY;-uCSDž*snHHXDž'Dž2Qƅ0Dž t@tGGG@t3҉@t|sځu39} Dž9~ u!u t-RPWSW0؋9~N뽍E+Ftbt΀90tW0@?If90tu+(u MI8t@u+@t5t ƅ-t ƅ+ tƅ Dž++ u% O0tP2YYt.u%˰0Otヽtu~qPjEPPiu69t.EPYYu#P]YY|2t) Ot߃ti3Ytrt `pM_^3[RCÐDD>DDDD9DiDjhM3ۉ]jY]j_};=M}TM9tE@ tP]MYtE|(M PEM42YMGE EjxYËUVuu"]F @t F F u Vj^YFvvVeDYPOd FF uQV;DYt0V/DYt$WV"DV= uE 8u}4$pW3%#+ESYx;r F+ F-ڋ0;|$;rSQRP0FU;u |drjjdRP0UF;u | rjj RP0UF]0F}tE`p3[_^ËUSVWuwٍMNc>u#AMj^0}tE`p}v׀}t;u u3?-f0?-u-sGV^@PVSg0} ~QV^@PVSCEy&߀}u9} |} } Wj0Sg; }tE`p3_^[ËU,M3ʼnEEVW} j^VMQMQp0u)L0lS]uL0S;t 3Ƀ}-+uMQMQP3}-PtuEjVSN[M_3^1ËU,M3ʼnEEVu Wj_WMQMQp0uhK89MtS]3K}-<0u +ȍEPuQW8tWEH;|-;E}(t GuGuEjuuuEjPuuu[M_3^0ËUEet_EtZfuu uuu u']ÃatAtu uuuu u0u uuuu uou uuuu uo]ËUjuuuuu uZ]ËVhh3V t VVVVVl^ËUQVu Vp1E F YuI N /@t I"S3ۨt^NF F F ^] u,E* ;t 9*@;u u 0YuVJYF WF>HN+IN;~WPu & EM F yM ttMPM@ tjSSQ#ƒt%FM3GWEPu E9}t N E%_[^ËU}upH=]uj5ME]fQSuƒt7$ffAfA fA0fA@fAPfA`fApHuЅt7tIfIHut3tIJutAHu[XËۃ+3RӃtAJutIKuZUUVuF ttvf 3YFF^]ËUMS3Vu E]]]F> t tjVhL| u~F> t>=unF> tjhLV u ?jhLV u  jh̹LV uF> t>tEhuE SuP5t3"MEMH 3ɉHHHM H_^[jhpM 33}jY]3u;5MM9t[@ uHuAFwFPYM4VO&YYM@ t PV&YYF둋}cj8Y M;tNhM P|EMu4YM PEM<}_ ;tg ___OE 5Ë}jYSVWT$D$L$URPQQh`Dd5M3ĉD$d%D$0XL$,3p t;T$4t;v.4v\ H {uhCB#CT#d_^[ËL$At3D$H3D(Uhp pp> ]D$T$UL$)qqq( ]UVWS33333[_^]Ëj"33333USVWjRhDQr_^[]Ul$RQt$ ]-t"t t Ht3øøøøËVWh3FWP03ȋ~~~  ~M F+ο@Ou@Nu_^ËUM3ʼnESWPvE3@;rƅ t0;w+@P j R%0 Cujv vPWPjj蹻3SvWPWPWv SDSvWPWPhv S蛽$3EtLtL @;rRDž3)ЍZ w LQ w L QA;rƋM_3[%j hM_e MGptltwhuj ~*Ywj Yewhu;5(Mt6tV,EuMtVY(MGh5(MuV0EE뎋uj YËUS3SM0MuME8]tEMapE,MD;FG;v}>uЋuE}urlj{CijC C4MZf1f0JuL@;v~0C@IuCC Ss3ȋ {95MTM_^3[x"jhMVMX}_huqE;CWh Y؅Fwh#SuYYEuvh,EuFh=MtPY^hS=0EFp Mj wYeCMCMC M3E}fLCf EM@3E=} L M@3E=}(M@5(M,Eu(M=MtPY(MSE0j Y%u MtSY;eEÃ=MujVYM3ËUSV50EW}W֋tP֋tP֋tP֋tP֍_PE{$Mt tPփ{t CtPփMu֋P_^[]ËUW}SV5,EW֋tP֋tP֋tP֋tP֍_PE{$Mt tPփ{t CtPփMu֋P^[_]ËUSVu3W;to=Mth;t^9uZ;t9uPYY;t9uP襋YYYY;tD9u@-P+P+P=(Mt9uP.`YY~PE$Mt;t 9uP;Y9_tG;t 9uP$YMuVY_^[]ËUW} t;Et4V0;t(W8jYtV>YuMtVsY^3_]j hИM޻ MFpt"~lt͸pluj "Yj tYe5hMlVYYYEEj mYuËUSuM+)]C=wE苀Xu]}EPE%PG}YYtEjE]EY 3Ɉ]EAEjppEPQEPEjPH u8EtE`p3E#E }tMap[j EM3U$\$fD$f=0Lf@LfTfs,ffVf%%Y\ЁuT$t1 # fnfs f @LfT$^ʺ #f0LfWfTfvfɁf%=uefL$ fT$ fnfT PLfs4ffffvf%=t#fL$ f%tLLfL$ f%GfL$ f%+XĺfT$f~fs f~ҁ ¹f LfLYɺHfd$fT$ f0LfWfTfvf%=f~u fs f~?uf0LfWfTfvf%=uUffd$% уtf%=?rf%=?sLXºcf~fs f~ f@Lt:f~%=w%rwfD$D$fLfD$T$ ԃT$T$$i D$Ã~(=<VЃW?&=VЃ €WXX LfY\ LfY\f( Lf(5`LfYfXfpYXXf%Lfnʁƒ fW?fYT$Yfs-fpDf(=pLXfYXffYYfYfXfYYfpYfpYYfnfs-fnfvfXXfTXfWfvf\XfTf_\XXÃN^YYXYXf%=fD$D$^XYYXf%=fD$D$fLfnYfs-fVtfLYLefLYTfpDfYf%@+-p< Ё=r ɀfnfs-fD$D$fd$f?f3%-K$$ƅp u; ƅp2+at@u tF t2t>-Lƅpݽ`aAuƅp-L uS uN uu tƅp-Lu t Xݽ`au-L tƅp-Lƅp u-L-Lٛݽ`aAuݽ`aݽ`ٛu Lٛt øVtV$$vEft^t̀zuf\?f?f^٭^\L剕lݽ`ƅpa$؃#zuf\?f?f^٭^\L剕lݽ`ƅpɊaݽ`ɊaŊ$׊$ ؃#۽bۭbi@tƅpƅpTL۽bۭbi@t ƅpƅp۽bۭbi@t ۽bۭbi@t ƅpƅp-@Lpƅp tUEEEEE UE]MEMEMEMPQR Ef}tmËT$fT$l$étpLËB%=tËB D$B  D$ $,$ BËD$%=tËD$f<$t,$Zf$f=tf tf t Z,$ZÃ$D$%$D$%t==t_f$f=t*f u!f ttZmZ,$ZLLs LLLv L떋UQQEQQ$\YYuLEQQ$>EYYDz1EQ LQ]E$EYYDzjX3@3ËUEV339Eu:9UuzzMAE9Mu@9Uu;z AEu MM3F9E u(9Uu}UwUAEt^X9M uU9UuPEQQ$YUYzMu!UAuuME^]ËU(3EE9Mt5ME^EMV;jZ+IIItN  EElEMM u]M]Q]Y#"EܬEMM u]M]QE]YEEܬEE܄EMuM ]]?UE܄EWE܀EΉUE܀E?ElEqtWItHIt9It tEEEEElEMuuElEcEEEE(L $YDE܀EE܄EEܬEEEEEtEܤEhEpE\EHEEܴEE4EMuMM ]]M]QEYu "!E^ÐDDDDDDhDDID@DDDDUQQSVV5MNWEYYMظ#QQ$f;uUMYY~-~u#ESQQ$j TtVSWEYYfESE\$E$j jAt]EYEYDzVSVEYY" uES\$E$j jT^[USVWUjjhDu]_^[]ËL$At2D$H3UhP(RP$R]D$T$SVWD$UPjhDd5M3PD$dD$(Xp t:|$,t;t$,v-4v L$ H |uhDID_뷋L$d _^[3d yDuQ R 9QuSQM SQML$ KCk UQPXY]Y[j hMeEEE3=ËeeEEUES3VW9]u;u9] u3_^[];t} ;wAj^09]uҋU;uك}u+ B:t"Ou+A:tOtMu9]u;u}uM jP\Xxj"Y낋USWuM33M;u f8]tE`p3fVu9^uu QEYY8]tLMapCD0tAt 9E uy 9E uAu8UtE`p^_[ËUju uD ]ËUVuW;F8tMuu} "X} StIj"[:tA:tGFMu,u-Ft":tGFMtu>t FuF8t[E+_#^]ËUV39uui0Oj^0UE uutFOut+BtOuuj"Y3_^]j,hM軟3ۉ]3M;;ukQbq1E%?@u5-M#3;;tE ]EjXEu EPEPEPEuXEPY};] MǃDT$" D$ E 豤u؃ ]E MƃDT$" D$ EEPvYEuE@u;9Eu6σMD ΃MD Et6σMD΃MDuW臡uV~P3ۋ}W}Y3ۋ}u؃tVhYSSSSS輤σM\uE9]t'uԋ5 EuE8p3gËUS] trtmVjSEuE PSEt45XEփu  PYu S EEtM ^Q []ËUSV3;u1j^0W9]wj^0u39]A9Mw j"ۋM "wɋ9]t 3C-N؋3u vW0ACt;]r;]rIIG;r3_^[] U} Eu yjj juuM ]ËUM Ejuu]%Ejh8M耛3}jDY}3u;5M}bM98t=@ t5PVYYEM@ t9xt P@YE}F3uࡴM4VYYE E2jܟYËUS39]u3>VWuxpVYY;tuVW} u SSSSSӡ3_^[]ËU0S3EV]܈]]E ]t ]E E]EPrYEuE@u9EtME+ùtCHt(Ht j^0胡MEt EuE@UEjY+t7+t*+t+t@u9UEEE E]E#¹W;3t(;t$;t=tT=u-ETEKEB=t4=t$;t)j^0衠_^[EEEEt M#MxE@tMMMt } t M tM螞;u!V 9.`E=EjuuEPuuu ׉E;upM#;u+Et%ejuEuPuuu ׉E;u76MD0 XEPYEeuXEuD6MD0 XEVzYu EuA 렃uM@ uMu62ЃMYYMLЃMD$ MeHMu~EtojS6 ;u8tO6|pjEP6E^ u}uǙRP6诶 ;tjj6U ;tE(@@}uE#u M EE#;tD=t)=@t"=t)=@t"=t=@uEM#;u EEE3E@}E#=@=tq;yE;nvv+[E3HHGEjjWW6 tWWW6#ƒ;jEP6 ;wtj}uXEE;iWjWW6脣 JWWW6o#;E%=u6unYj^0u_=uWj6k ;E>WW6Q Ej[+PD=P6O ;݃ MD$2M0 MD$M ʀ}u!Etȃ MD M#;u~Etxu EjuEjPuE%Pu E;u4XEPȃ MD 6ڗY6 MEVSSSSS虚jh`MQ3}3u;;uj^0輚Y39};t9}tE%@tʉ}uuu uEP]EEE;t3u9}t(9}t MD 6vYËUjuuuuu !]ËU9EuFjP;M u+@YYu3]ËE6u 7 Q讚 tՉ&3@]ËUEP=EYu߃]Jx A RoYËUSU؃tPYu[]ËUM3ʼnEMEVu W3|\PDž$^0l;u;t@ @SurPYPMttȃ MA$u&ttȃM@$t huƅ[t4PYt?\ttYt\P,YYGPYu <%k 8GX 3/THdXYcsZkƅ{(3GPYtdHk DЉdN*tpFItLut{O6uG84u(8]u ]FE /F<-uqtm]tfF:s{{:{s,{*ЋσdzDGJu苝L{D2ȊЋDL<]cD@b+u.du t ƅs\t ؉l0\t؉lxt_XtZLxDžTt&HtdusDžLo.tt\SFYYj0[\tlH؉ltdd}sDžLxF@xGrtt\PYY;c4cZt@3f@ƅ{l-u ƅY+u.du t ƅs\tx؉l(<sLxt]LptTPgYLou88<Kjj <8hu0PYtk8<SYlTCЙH8f>D[GDd<%u8GuG\tGlD;uwP EYt%\tGD;u7tlu?%uNDxnuB4lt\P YYt\l YY0u PYlu*4u 8[ut% apt `p4[M_3^ËUMhFYMAt I AI AAAAa]ËUUVujXEU;u  }S3;|;5Mr 襈NWY;#ẺTM=`M=TMhhM趬Yu;tt8tpXM;t!PV#YYAXM;tP4YVk@PQYYXM;VVjY@P5XMm ;SSSSSPQXM;t PޛYXMhME;3A TMMk-uEFV{YiE<+t<0|<9F3ۋujMYÀ>:u8FV{Yk<E<9F<0}>:uFV{YE<9F<0}9]t]E;tjVj@w}t Gu0u0VHËU e} SVW}%yH@Eu jd[ult M ME +_jd_FjEÙU}[+ЉUGEim%Ek+E;Ut}}u jd[ult E M E M;~D?%yH@u jd[ult 4M4Muk<M k<M$iM(}u5XM \M=TM_^[ÍEP5dM hMYuDEihMyhM\& dM\&9hM| )hMdM=`M3PPPPPUM̋U VE3PuPY9uXWS3C;TMu ;`M95TMNM HMPLMPJMPf95@MuDMVPFMPRS FMPVVRVBMScM M$PMPMPf95MuMVPMPwSMPVVwVMV$TjXjYE ]k}jXE EVVVVVQRSSjYEVVVVVuwSVjYH XMdMW;};|";;~;}[^;|;;~;}3Gk<Gk<i;u 3;\M 3;hMVVVVV~KjhM6D395\Mu*jIYu95\Mu \MEBDjHYj h MCjIYe}EE EDjHYËUEuV#KjX]Ë tM3]ËUEu)JjX]Ë xM3]ËUEuJjX]Ë pM3]øtMøxMøpMøMSVD$ uL$D$3؋D$ Aȋ\$T$D$ ud$ȋD$r;T$wr;D$ vN3ҋ^[UE VW33};u@ J88tS];t ;t8uIEu8Su u^Eɾ8j/u *YYhFEWP ;thWWWWW I9}UjSIYY;<hVuV ; >V5b|0Y<\uj\VYY;t,hPESV, SEjP4_ Pj?SEjP_ Pj@SEjP_ PjASEjP^P PjBSEjP^ PjCSEjP^ Pj(SEjP^ Pj)SEjP^P PjuEjPt^ Pj uEjP[^ PhuEjP?^ Ph uEjP#^ EPPj1SEjP^ Pj2SEjP] Pj3SEjP] Pj4SEjP]P Pj5SEjP] Pj6SEjP] Pj7SEjPs] Pj*SEjP\]P Pj+SEjPB] Pj,SEjP+] Pj-SEjP] Pj.SEjP\P Pj/SEjP\ Pj0SEjP\ PjDSEjP\ PjESEjP\P PjFSEjP\ PjGSEjPm\ PjHSEjPV\ PjISEjP?\P PjJSEjP%\ PjKSEjP\ PjLSEjP[ PjMSEjP[P PjNSEjP[ PjOSjEP[ Pj8SEjP[ $Pj9SEjP[P (Pj:SEjPg[ ,Pj;SEjPP[ 0PjSEjP[ <Pj?SEjPZ @Pj@SEjPZ DPjASEjPZP HPjBSEjPZ LPjCSEjPZ PPj(SEjP{Z TPj)Sj[ESPbZP XPjuESPGZ \Pj uESP/Z`Vhu ESPZ< _^[ËUVucv$vv v vv6v v$v(݆v,Նv0͆v4ņv轆v8赆v<譆@v@袆vD蚆vH蒆vL芆vP肆vTzvXrv\jv`bvdZvhRvlJvpBvt:vx2v|*@څυą蹅讅装蘅荅肅w@i^SH=2'ڄτĄ@ 趄諄蠄蕄芄 $t(i,^0S4H8=<2@'DH@LPTX\׃`̃^]ËUSVu~ W(MtBhdj9YYu3@IƋRtWGW~YYLJ;t P,E3_^[]ËUVutY;MtP,YF;MtPYF;MtPYF0;MtPYv4;5MtVY^]ËUSVuW3u}9~u9~u}}MejPj8YY;u3@jYjH83YE;u SsYыu89~j 8YE;u3FSJuBYYD8v>SjVEjPTCPjVEjPT CPjVEjPT C0PjVEjPTP C4PjVEjPT tS{YkC0|9 0@8u>;uNF>u塈MMCMCMC0M}C4Mu3@Mt=,EtP׋tPׅuYYEE3_^[ËUVuF ;MtP΀YF;MtP輀YF;MtP誀YF;MtP蘀YF;MtP膀YF ;MtPtYF$;MtPbYF8;MtPPYF<;ĴMtP>YF@;ȴMtP,YFD;̴MtPYFH;дMtPYvL;5ԴMtVY^]ËUSVuW3}u}9~u9~u}}MjPj5YY;u3@jd5YE;u SY89~4jA5YE;uSnufY҉8v8C PjVEjPRCPjVEjPR CPjVEjPQ CPjVEjPQP CPjVEjPQ C PjPVEjPQ C$PjQVEjPQ C(PjVEjPQP C)PjVjEPrQ C*PjTVEjP^Q C+PjUVEjPJQ C,PjVVEjP6QP C-PjWVEjPQ C.PjRVEjP Q C/PjSVEjPP C8PjVEjPPP CujYME IuKIKI0K0@4MC43@39}tM;tP,E;t#P,Eu||YYEE3_^[ËULM3ʼnES3VuW]ԉ]]]؉]܉u]9^F9u PF0hPESP Oj1jWE&2jWE2jWE2jhE2$E9]9]v;n9]e9]\Eԉ3M܈@=|EPvE2}(EEЃ~.8]t)E:t x M G;~8XuڋESSvPhu܉EjS MESvWQW@PhvS"$ESvWPEW@PhvS"$bE}3҃}fU؉Mč_ZMMȈ~U8]tPMM:tDI҉M;(HMEfM̋M 9M~MM8YuhQPzjPWzEjQPz$;tKP,Eu@-Py+Py+PyyEEEĉEEȉEЉunyYouayuYyuQyuIy3ۃCˋ;tP,Edž jMdžnMdž(pMdž3M_^3[)$ȋAl;hMt MQpuk@3̋T$L$u<:u. t&:au% t:Au t:au uҋ3Ðt:u ttf:u t:au t눋U3S3@9] |FVWt>E Ù+‹E<7E0YYu M9 yNu ^;] ~_^3Ʌ[]ËUQtP>tKhyMVYYt:hyMVYYujEPh wEt)EVXYEjEPh wEu3Ã}uEËU3fMf;xMt r3@]3]ËV3 AB<w A<wtЊ uڋ^3 BA|Z~aw@ËU|M3ʼnEVW}!׋jxEP%PWEu !@AEPYYuWYtЃM_3^rUQVjEP%h PEu3);ut!}tE 0WVDY;_t3@^ËU|M3ʼnESVW} ׍EjxEPF%PWӅu f3@cEPvYYjxEPF%PWӅtEP6YYu N~RFuOF t,PEP6\ u6N~CY;F u!~VuWYt V~N#;jxEPF%PWӅEP6Y3Yu0NF9^t FH9^ t<6>CY;F u/Vj9^u49^ t/EP6YYuVSYYtN9^u~FЃM_^3[FU|M3ʼnEVW}׍jxEPF%PWEu!F@\EP61YYu 9Fu1Vj~u0~ t*EP6 YYuVP?YYt N~~FЃM_3^膃6Bv@FBf@~YYFtjXjhaEF EFt tuf6A@YFtjXjhcEF EFufËUSVWEu O@_t8tSjh8xM/ gt[8tVt8t SWj@h0vM tft;t RIt0;t+S@Yj@h`EGEGugGEGGuƃ#uPEjwEE tfOffOfHfp]th5Ef9u h yMj@SC t3PPPPPY&j@Shwօt,j@C@Phwօtj jSu3@3_^[]ËUVW}ǃHHlH!HM ESj Z20;1tt0+t3ۅÍt+pY+t3ۅÍt pY+t3ۅÍtpY+t3ۅÍt3p;qtvpY+t3ۅÍtpY+t3ۅÍtpY+t3ۅÍtepY+t3ۅÍt3Bp;qtvpY+t3ۅÍtp Y +t3ۅÍtp Y +t3ۅÍtp Y +t3ۅÍt3p ;q tvp Y +t3ۅÍtp Y +t3ۅÍttpY+t3ۅÍtUpY+t3ۅÍt32p;qtvYp+t3ۅÍt pY+t3ۅÍtpY+t3ۅÍtpY+t3ۅÍt3p;qtvpY+t3ۅÍtpY+t3ۅÍtdpY+t3ۅÍtEpY+t3ۅÍt3"p;qtvpY+t3ۅÍtpY+t3ۅÍtpY+t3ۅÍtpY+t3ۅÍt3p;qtjpY+t3ۅÍtuwpY+t3ۅÍtu\pY+t3ۅÍtuApY+t3ۅÍt3u"+;σ${EP;QtiQ+t3҅tupQ+t3҅tupQ+t3҅tupQ+t3҅t3uP;QtuQ+t3҅t\pQ+t3҅t=pQ+t3҅tpQ+t3҅t3P;QtuQ+t3҅tpQ+t3҅tpQ+t3҅tpQ+t3҅t3tP;QtuQ+t3҅tNpQ+t3҅t/pQ+t3҅tpQ+t3҅t3P;QtvQp+t3҅tpQ+t3҅tpQ+t3҅tpQ+t3҅t3eP;QtuQ+t3҅t?pQ+t3҅t pQ+t3҅tpQ+t3҅t3P;QtmQ+t3҅Tu6pQ+t3҅TupQ+t3҅Tt@I+t3ɅD 3u3[ P;QtuQ+t3҅t5pQ+t3҅tpQ+t3҅tpQ+t3҅t3P;QtuQ+t3҅tpQ+t3҅tpQ+t3҅tppQ+t3҅t3MP;QtuQ+t3҅t'pQ+t3҅tpQ+t3҅tpQ+t3҅t3P;QtuQ+t3҅tpQ+t3҅tpQ+t3҅tbpQ+t3҅t3?P;QtuQ+t3҅tpQ+t3҅tpQ+t3҅tpQ+t3҅t3P;QtvQp+t3҅tpQ+t3҅trpQ+t3҅tSpQ+t3҅t30P;QtuQ+t3҅t pQ+t3҅tpQ+t3҅tpQ+t3҅t3I@+83ɅD (P;QtuQ+t3҅tcpQ+t3҅tDpQ+t3҅t%pQ+t3҅t3P;QtuQ+t3҅tpQ+t3҅tpQ+t3҅tpQ+t3҅t3{P;QtuQ+t3҅tUpQ+t3҅t6pQ+t3҅tpQ+t3҅t3P;QtuQ+t3҅tpQ+t3҅tpQ+t3҅tpQ+t3҅t3mP;QtuQ+t3҅tGpQ+t3҅t(pQ+t3҅t pQ+t3҅t3P;QtvQp+t3҅tQp+t3҅tQp+t3҅tQp+t3҅t3^P;QtuQ+t3҅t8pQ+t3҅tpQ+t3҅tpQ+t3҅t3fPf;QfQp+3҅TP;QtvQp+t3҅tzpQ+t3҅t[pQ+t3҅t<pQ+t3҅t3P;QtuQ+t3҅tpQ+t3҅tpQ+t3҅tpQ+t3҅t3P;QtuQ+t3҅tlpQ+t3҅tMpQ+t3҅t.pQ+t3҅t3 P;QtuQ+t3҅tpQ+t3҅tpQ+t3҅tpQ+t3҅t3P;QtvQp+t3҅t]pQ+t3҅t>pQ+t3҅tpQ+t3҅t3P;QtuQ+t3҅tpQ+t3҅tpQ+t3҅tpQ+t3҅t3uP;QtuQ+t3҅tOpQ+t3҅t0pQ+t3҅tpQ+t3҅t3pQ+3҅TcMu +t3҅DAV+t3҅DAV+t3҅DAN+3ɅD Mu +t3҅DudAV+t3҅DuIAN뤋Mu +t3҅Du ANxEM  g3_^]ËoErEvEvzEnE4rEvEyEmEqE~uEhyEwmE%qEtExElEpEptEYxEilEpEsEwEkEoEbsEKwEkkE oErEvEUQQM3ʼnES3VW]9]u E@E5E39] SSuuPu֋;u3~<w4D?=w;tPFZY;t ؅t?PjSt WSuujuօtuPSu EESźEYe_^[M3jËUuMZvu$Euuuuu P}tMapËUM3ʼnEUS3VW;~EI8t@;u+H;}@E]9]$u E@E$5E39](SSuuPu$֋};u3R~Cj3Xr7D?=w.;tPXY;t E]9]tWuuuju$օ5ESSWuuu ։E;Mt)E ;9EPuWuuu };~Bj3Xr6D?;wt;thP1XY;t 3;t?uWuuuu օt"SS9] uSSu uuWSu$pEEW觸Yu螸EYe_^[M3hËUuM3tu(Eu$u uuuuu P$}tMapËU,M3ʼnEESVW}ىE܉U~?I8t@u+}u~*΋I8t@u+u}3|e}u@Et;ujX3C;~;~jEPuEt~-}r}Et؊PtыM܊ :r:v8u뺅~4}r}EtPtM :r:u8uw5EjjWuj u֋؉]ԅ~@j3Xr4D;w/ątPUYt Ee}Suuujuօjjuuj u֋؅tx~?j3Xr3D;wątPoUYt 3t1SWuujuօtSWuuu uEEWYuEYe_^[M3eËUuMqu$Uu Muuuu b}tMapËUEVu ~:WuN\t/uyt u u@@% j.V aYYtGhiMV$?YYt3hiMV?YYt"h iMV?YYthhMV>YYu@8  _^]ËU@M3ʼnES] Vu3ƔW]ȉẺEĉEFLC }};};} MH+;E}E%yH@u jd[ul]ȃ}}sM%MyH@u jdYulu~EpEPYEPYEP-Y+jd[jhmF+FD؉UЋƙFRP؋E‰EЋEԙ؋E3WjPSȋEڙWj<SQrȋEڙWj<SQ\MEڙڋEԉEEډuH} EEEEE܉Mt} u}tEP詼YtEęڋNj3PPPPP-} ЋM_^3[tbËUM3ʼnESVW=EPh׋~AFjPYYu| 3Džt S׋3tf{:u arzwx l| tSzQYM_^3[aËUSu MJm]vaȈEE]Du}tE`p[jpMjQjMQhp EP$tEMEDt À}tMap[ËUjuKYY]ËUSVuMlu39^uu uYYM;u O{8]tE`p3i9] t8tKWE (D7t:uP:QtP8t :t@8u8uD0tA8tA8u_#8]tMap^[ËUju u) ]ËU M3ʼnEEu3@0@j:fEXfEj\XfE3fEEPEtu3M3_ËUQQS]t-SYu)Jz,z 3W} t&Ey3Eet@]fE :.E fE.V5LEEPWuEPօtft;E|Yy"Z;E~EjuNYYuty |y(EPWuEPօt ;E}XEP`yY3^_[j h@Mqj:Yeu uj EE Ej-YËUEVWxY;MsQ1uAWL@PWV3_^[]ËUQM AS%V#WE A %ut;t<($3;u;uEfM PB<U UE  ɁPtM _^fH[ËU0M3ʼnEES]VEWEPEP"YYEPjj uЋf"u܉CEECEPuV@ $uM_s ^3[kH3PPPPPWVU33D$ }GET$ڃD$T$D$ }GT$ڃD$T$ u(L$D$3؋D$d$ȋd$G؋L$T$D$ ud$ȋD$r;T$wr;D$v N+D$T$3+D$T$My؃ʋӋًȋOu؃]^_̀@s sË3Ҁ33ËUEM %#Vut$t jj+YYaj^0Pu t p+g+YY3^]ËUSuMR39]u8]tE`p3E9Xu&uu u_ 8]Map9]u&1a8]tE`pfW} ;u&a8]tE`p7VM MEDMte9]uD]fU:u]Tf EfMf;pr f;pwfp1f;pr+f;pw%fpU At ʉMfuGDMtG9]u]XM:tf GMf;Hr f;HwfH1f;Hr+f;Hw%fHU At ʉMfMf;u!f;t 9]8]tE`p3^_[H8]tMapUjuu u]ËU}u3WuMtP}u'uu u& }MapS]u#_8]tE`p_Vu u$^}tE`p2 MCD8t=}u 3D8tY}tE`p3^[_Êu3 f CFD:t }u3Mtf Ff;uft}pH}tMap닋Ujuu u]ËSQQUkl$M3ʼnECVs HWxtRHtCHt4Ht%HtFHHtHDž|9Dž|"Dž|Dž| Dž|Q~W|蚍 uICtt teMF]MWNQP|xPEP*hx蚒>YYt=PMu VRYu6YM_3^:B][ËUQQE]EËUSVW3jSSu]]QE#ƒUtYjSSu5#ʃtAu }+;SjlEPEEu>\ 3\_^[hu*YYE| ;rPuu t6+xӅuϋuuuYYujlEPE3[8u [ u;q|;skSuu u:#ƒDuYPpEHE#‰Uu)R[ Z[XEu#uSuuu#ƒ3U8M3ʼnEEM MH SفMȋHMH?WMEu'339\u @|33}jXeVu}䥥=\MOGW]ԉEyJBtj3Y+@MЅE؃҅T|u@|nǙjY#yOGe+3BL9}99}r"9Ut+eLz};rsEHUMyщM܋MЃjY!E@;} |+3}tCXM+ \M;} 3}𫫫 ; +Eԍuȍ}𥙃¥yJBeeE )U׋]\3#ωMԋM u؉3uE}u|ӋjMZ+;|1tdJy5\MNFVEyJBjY+3B\Mԅ҅T|u@|fƙjY#yNFe3+BL1<;r;sE9MtLr3;rs3G1HyދMԃ!E@} jY|+3 `MAQyJBeeE )U׋]\3#ωMԋM u؉3uE}u|ӋjMZ+;|1tdJyj3XS `M;TM3}𫫫M‹yJBeeE )U׋]\3#ωMԋM u؉3uE}u|ӋjMZ+;|1tdJyhMTM3@hMe‹yJBeeE )U֋M|#ΉMԋM }؉|}ԋME}}|ЋjMZ+;|1tdJy3^jY+ `MMɁ ً dM ]@u M̋UY uM̉M_3[;ËU8M3ʼnEEM MH SفMȋHMH?WMEu'339\u @|33}jXeVu}䥥=tMOGW]ԉEyJBtj3Y+@MЅE؃҅T|u@|nǙjY#yOGe+3BL9}99}r"9Ut+eLz};rsEHUMyщM܋MЃjY!E@;} |+3}tCpM+ tM;} 3}𫫫 ; +Eԍuȍ}𥙃¥yJBeeE )U׋]\3#ωMԋM u؉3uE}u|ӋjMZ+;|1tdJy5tMNFVEyJBjY+3B\Mԅ҅T|u@|fƙjY#yNFe3+BL1<;r;sE9MtLr3;rs3G1HyދMԃ!E@} jY|+3 xMAQyJBeeE )U׋]\3#ωMԋM u؉3uE}u|ӋjMZ+;|1tdJyj3XS xM;lM3}𫫫M‹yJBeeE )U׋]\3#ωMԋM u؉3uE}u|ӋjMZ+;|1tdJyMlM3@Me‹yJBeeE )U֋M|#ΉMԋM }؉|}ԋME}}|ЋjMZ+;|1tdJy3^jY+ xMMɁ ً |M ]@u M̋UY uM̉M_3[5ËU|M3ʼnEE3V3EE FWE}MuMMMMMMM9M$uP3<UU< t < t< t< uBS0B $EHπwjYJߋM$ :ujY+tHHt |jYE뤃ejY뛍HωuvM$ :uj<+t"<-t:t> > _PROMPT2_PROMPT''return %s =stdinerror calling 'print' (%s)print-malloc() failed realloc() failed %s %s OKUnable to open file.wb$Lua: Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio $ $Authors: R. Ierusalimschy, L. H. de Figueiredo & W. Celes $ $URL: www.lua.org $ no calling environmentno value?yieldwrapstatusresumecreatedeadnormalsuspendedrunningxpcallunpacktypetostringtonumbersetmetatablesetfenvselectrawsetrawgetrawequalpcallnextloadstringloadloadfilegetmetatablegetfenvgcinfoerrordofilecollectgarbageassertsetstepmulsetpausestepcountcollectrestartstop8E0E(E EE EEE19@E6@E8@E2@E5@Ey4@E 3@E7@E8@E7@E6@E:@E1@|EC5@tEt5@lE5@dE:@\E4@LEI3@@E1@4E;@,E6@$Ex9@E:@EEEEE>@E=@E[?@E<@E ?@EB?@'tostring' must return a string to 'print' Abase out of range__metatablecannot change a protected metatablenil or table expectedno function environment for tail call at level %dfinvalid levellevel must be non-negative'setfenv' cannot change environment of given objectP?reader function must return a stringtoo many nested functions=(load)%sassertion failed!too many results to unpackindex out of rangenilfalsetrue%s: %p__tostringboolean or proxy expectedcoroutine expectedtoo many results to resumecannot resume %s coroutinetoo many arguments to resumeLua function expectednewproxy__modekvpairsipairs_VERSIONLua 5.1_Gcoroutinecontrol structure too longfunction or expression too complexconstant table overflowcode size overflowsetupvaluesetlocalsethookgetupvaluegetregistrygetlocalgetinfogethooktail returnlinereturncallhLEDE%sflnSulevel out of rangeexternal hook=(debug command)cont lua_debug> ? in function <%s:%d> in main chunk in function '%s'%d:%s:Snl ...stack traceback:(*temporary)LuamainC=[C]tail=(tail call)upvalueglobalfieldlocalmethod%s:%d: %sattempt to %s a %s valueattempt to %s %s '%s' (a %s value)concatenateperform arithmetic onattempt to compare %s with %sattempt to compare two %s valuesnot enough memoryerror in error handlingattempt to yield across metamethod/C-call boundarystack overflowC stack overflowcannot resume non-suspended coroutinemathosiotablepackageEk@@,E @$E A E8@E@E@E@~=<=>===.....whileuntilthenrepeatornotiniffunctionforelseifelsedobreakandEEEExEE`EtEhEdE`EE\E\EXEPEDEHEhE@E8E4E0E,E(E$E EE EEElexical element too long%cchar(%d)%s near '%s'chunk has too many linesmalformed number+-Eeunfinished long commentunfinished long stringnesting of [[...]] is deprecatedunfinished stringescape sequence too largeinvalid long string delimiter.tantanhsqrtsinsinhrandomseedrandomradpowmodfminmaxloglog10ldexpfrexpfmodfloorexpdegcoscoshceilatanatan2asinacosabsE@EA@E@E@Ej@Eѥ@E@Et@E@E_@E@E!@Eԧ@E @E6@E @|E@xEC@pE_@lEϦ@hE@`E@TE@LEK@HE"@@E@8E@4EƤ@9RFߑ??interval is emptywrong number of arguments@hugepi-DT! @memory allocation error: block too bigmoduleseeallloadlibpE]@hEc@`Ef@DE@|@ @@@unable to get ModuleFileName!system error %d _LOADLIBLOADLIB: %s%sinit no file '%s''package.%s' must be a string\error loading module '%s' from file '%s': %spathluaopen_%s_cpath no module '%s' in file '%s' no field package.preload['%s']'package.preload' must be a tablepreloadmodule '%s' not found:%s'package.loaders' must be a tableloadersloop or previous error loading module '%s'_LOADED'module' not called from a Lua function_PACKAGE_NAME_Mname conflict for module '%s';;;;loadedconfig\ ; ? ! -LUA_CPATH.\?.dll;!\?.dll;!\loadall.dllLUA_PATH.\?.lua;!\lua\?.lua;!\lua\?\init.lua;!\?.lua;!\?\init.lua%%p(null)"][string " VARARGCLOSURECLOSESETLISTTFORLOOPFORPREPFORLOOPRETURNTAILCALLCALLTESTSETTESTLELTEQJMPCONCATLENNOTUNMPOWMODDIVMULSUBADDSELFNEWTABLESETTABLESETUPVALSETGLOBALGETTABLEGETGLOBALGETUPVALLOADNILLOADBOOLLOADKMOVEEEEEEEEEE|EpEhEdE`E\EXETEPELEHEDE@Ej@E^@E@E@unable to generate a unique filename@@field '%s' missing in date tableisdstydaywdayyearmonthdayhoursec*t '%s' expectedfunction at line %d has more than %d %smain function has more than %d %s'%s' expected (to close '%s' at line %d)too many local variableslocal variablesupvalueschunk has too many syntax levelsitems in a constructor or '...' expectedselfambiguous syntax (function call x new statement)function arguments expectedunexpected symbolcannot use '...' outside a vararg functionvariables in assignmentsyntax errorno loop to break(for step)(for limit)(for index)(for control)(for state)(for generator)'=' or 'in' expecteduppersubreversereplowerlengsubgmatchgfindformatfinddumpcharbyte0F@(F@ F@Fs@F@F@Fs@FJ@F@Fn@E@F@F@F?@F @string slice too longinvalid valueunable to dump given functioninvalid capture indexinvalid pattern capturemalformed pattern (ends with '%%')malformed pattern (missing ']')unbalanced patterntoo many capturesmissing '[' after '%%f' in patternunfinished capture^$*+?.([%-'string.gfind' was renamed to 'string.gmatch'invalid replacement value (a %s)string/function/table expected\000\rinvalid format (width or precision too long)invalid format (repeated flags)-+ #0invalid option '%%%c' to 'format'invalid key to 'next'table overflowtable index is NaNtable index is nilsortsetninsertmaxngetnforeachiforeachconcatF AFAxFApFAhFA`F`AEAXF2APFJ A'setn' is obsoletewrong number of arguments to 'insert'invalid value (%s) at index %d in table for 'concat'invalid order function for sorting__call__concat__le__lt__len__unm__pow__mod__div__mul__sub__add__eq__newindexupvalprotothreadnumberuserdataboolean\E$FFFE$EhEFFFFEFE0EFFFFFFFFFFFFF%s: %s in precompiled chunkunexpected endbad integerbad constantbad codecode too deepbad header=?binary stringloop in gettableindexloop in settablestring length overflow'for' step must be a number'for' limit must be a number'for' initial value must be a numberget length of%s:%d: Slstack overflow (%s)cannot %s %s: %s@%sreopenrbPANIC: unprotected error in call to Lua API (%s) _SCRIPT_DIR_SCRIPTbad argument #%d to '%s' (%s)calling '%s' on bad self (%s)nbad argument #%d (%s)%s expected, got %svalue expected: No such file or directorycannot open invalid option '%s'unable to switch to directory '%s'unable to set mode %o on '%s', errno %d : %sunable to write to '%s'Unable to compile '%s': %s(error with no message)unable to copy file to '%s'kernel32GetNativeSystemInfoWindowsWindows 8.1Windows Server 2012 R2Windows 8Windows Server 2012Windows 7Windows Server 2008 R2Windows Server 2008Windows VistaWindows Server 2003 R2Windows Server 2003Windows Home ServerWindows XP Professional x64Windows XPWindows 2000descriptionrevisionminorversionmajorversionIsWow64Process/$/premakeunable to create directory '%s'unable to fetch real path of '%s', errno %d : %sunable to remove directory '%s'sizemtime'%s' was not found'%s' could not be accessedAn unknown error %d occured while accessing '%s'%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02Xunable to write file to '%s'../**./normalizeWildcards expansion too big.extractdownloadgetwritelnnewstartswithsha1hashendswithcompilewritefile_ifnotequaluuidstatrmdirrealpathpathsearchmkdirmatchstartmatchnextmatchnamematchisfilematchdonelocateislinkisfilegetversiongetcwdisdir_is64bitcopyfilechmodchdirwildcardstranslatejoinisabsolutegetrelativegetabsolutepromptmatches_delete_compileF,@F@F<@xF@lF2NA`FDOATFzQALFQA FTA@FoVA4FWA,FA F BAFZBA F(?A FEAA FBA FCA FCA FDA FEA FDA F,EA FnDA FKFA FSGA| FGAt FUHAl FHAd F{IAL FKAD F=A8 F_A0 F[`A( FcA FcA F@E@ F@4EA@E@ Fp@ Fs@ FlhA_WORKING_DIR_USER_HOME_DIR~USERPROFILEHOME_OSwindows_PREMAKE_URLhttps://github.com/premake/premake-core/wiki_PREMAKE_COPYRIGHTCopyright (C) 2002-2016 Jason Perkins and the Premake Project_PREMAKE_VERSION5.0.0-alpha8_COPYRIGHTCopyright (C) 1994-2008 Lua.org, PUC-RioziphttpbufferedcriteriaPATH;/usr/local/share/premake;/usr/share/premake/.premakePREMAKE_PATH;_ARGV--scripts=/scripts=_premake_mainError: %s _PREMAKE_COMMANDsrc/_premake_main.lua0123456789ABCDEFError creating file: %s Writing data to %s failed %d bytes were written %d bytes were attempted to be written File may be corrupt Failed to create symbolic link [%s->%s] %s/%s%s does not exist src/_modules.luasrc/_manifest.luaxcode/xcode_project.luaxcode/xcode_common.luaxcode/xcode4_workspace.luaxcode/xcode.luaxcode/_preload.luamonodevelop/monodevelop_cproj.luamonodevelop/monodevelop.luamonodevelop/_preload.luad/tools/ldc.luad/tools/gdc.luad/tools/dmd.luad/actions/vstudio.luad/actions/monodev.luad/actions/gmake.luad/d.luad/_preload.luacodelite/codelite_project.luacodelite/codelite_workspace.luacodelite/codelite.luacodelite/_preload.luasrc/_premake_init.luasrc/actions/clean/_clean.luasrc/actions/vstudio/vs2015.luasrc/actions/vstudio/vs2013.luasrc/actions/vstudio/vs2012.luasrc/actions/vstudio/vs2010_rules_xml.luasrc/actions/vstudio/vs2010_rules_targets.luasrc/actions/vstudio/vs2010_rules_props.luasrc/actions/vstudio/vs2010_vcxproj_filters.luasrc/actions/vstudio/vs2010_vcxproj_user.luasrc/actions/vstudio/vs2010_vcxproj.luasrc/actions/vstudio/vs2010.luasrc/actions/vstudio/vs2005_csproj_user.luasrc/actions/vstudio/vs2005_csproj.luasrc/actions/vstudio/vs2005_solution.luasrc/actions/vstudio/vs200x_vcproj_user.luasrc/actions/vstudio/vs200x_vcproj.luasrc/actions/vstudio/vs2008.luasrc/actions/vstudio/vs2005.luasrc/actions/vstudio/_vstudio.luasrc/actions/make/make_makefile.luasrc/actions/make/make_utility.luasrc/actions/make/make_csharp.luasrc/actions/make/make_cpp.luasrc/actions/make/make_workspace.luasrc/actions/make/_make.luasrc/tools/clang.luasrc/tools/snc.luasrc/tools/msc.luasrc/tools/gcc.luasrc/tools/dotnet.luasrc/base/help.luasrc/base/premake.luasrc/base/validation.luasrc/base/oven.luasrc/base/rule.luasrc/base/fileconfig.luasrc/base/config.luasrc/base/project.luasrc/base/group.luasrc/base/workspace.luasrc/base/global.luasrc/base/api.luasrc/base/action.luasrc/base/option.luasrc/base/container.luasrc/base/context.luasrc/base/configset.luasrc/base/detoken.luasrc/base/criteria.luasrc/base/field.luasrc/base/semver.luasrc/base/globals.luasrc/base/tree.luasrc/base/tools.luasrc/base/io.luasrc/base/os.luasrc/base/path.luasrc/base/table.luasrc/base/string.luasrc/base/_foundation.luapremake = premake or {} premake._VERSION = _PREMAKE_VERSION package.loaded["premake"] = premake premake.modules = {} premake.extensions = premake.modules local semver = dofile('semver.lua') local p = premake local _warnings = {} local _aliases = {} premake.C = "C" premake.C7 = "c7" premake.CLANG = "clang" premake.CONSOLEAPP = "ConsoleApp" premake.CPP = "C++" premake.CSHARP = "C#" premake.GCC = "gcc" premake.HAIKU = "haiku" premake.LINUX = "linux" premake.MACOSX = "macosx" premake.MAKEFILE = "Makefile" premake.MBCS = "MBCS" premake.NONE = "None" premake.DEFAULT = "Default" premake.ON = "On" premake.OFF = "Off" premake.POSIX = "posix" premake.PS3 = "ps3" premake.SHAREDLIB = "SharedLib" premake.STATICLIB = "StaticLib" premake.UNICODE = "Unicode" premake.UNIVERSAL = "universal" premake.UTILITY = "Utility" premake.WINDOWEDAPP = "WindowedApp" premake.WINDOWS = "windows" premake.X86 = "x86" premake.X86_64 = "x86_64" premake.XBOX360 = "xbox360" function p.alias(scope, canonical, alias) scope, canonical = p.resolveAlias(scope, canonical) if not scope[canonical] then error("unable to alias '" .. canonical .. "'; no such function", 2) end _aliases[scope] = _aliases[scope] or {} _aliases[scope][alias] = canonical scope[alias] = function(...) return scope[canonical](...) end end function premake.callArray(funcs, ...) if type(funcs) == "function" then funcs = funcs(...) end for i = 1, #funcs do funcs[i](...) end end function premake.callarray(namespace, array, ...) local n = #array for i = 1, n do local fn = namespace[array[i]] if not fn then error(string.format("Unable to find function '%s'", array[i])) end fn(...) end end function p.checkVersion(version, checks) if not version then return false end local function eq(a, b) return a == b end local function le(a, b) return a <= b end local function lt(a, b) return a < b end local function ge(a, b) return a >= b end local function gt(a, b) return a > b end local function compat(a, b) return a ^ b end version = semver(version) checks = string.explode(checks, " ", true) for i = 1, #checks do local check = checks[i] local func if check:startswith(">=") then func = ge check = check:sub(3) elseif check:startswith(">") then func = gt check = check:sub(2) elseif check:startswith("<=") then func = le check = check:sub(3) elseif check:startswith("<") then func = lt check = check:sub(2) elseif check:startswith("=") then func = eq check = check:sub(2) elseif check:startswith("^") then func = compat check = check:sub(2) else func = ge end check = semver(check) if not func(version, check) then return false end end return true end function premake.clearWarnings() _warnings = {} end function premake.error(message, ...) error(string.format("** Error: " .. message, ...), 0) end function premake.findProjectScript(fname) return os.locate(fname, fname .. ".lua", path.join(fname, "premake5.lua"), path.join(fname, "premake4.lua")) end function iif(condition, trueValue, falseValue) if condition then return trueValue else return falseValue end end function premake.override(scope, name, repl) scope, name = p.resolveAlias(scope, name) local original = scope[name] if not original then error("unable to override '" .. name .. "'; no such function", 2) end scope[name] = function(...) return repl(original, ...) end if scope == premake.main then table.replace(premake.main.elements, original, scope[name]) end end function p.resolveAlias(scope, name) local aliases = _aliases[scope] if aliases then while aliases[name] do name = aliases[name] end end return scope, name end function premake.warn(message, ...) message = string.format(message, ...) if _OPTIONS.fatal then error(message) else io.stderr:write(string.format("** Warning: " .. message .. "\n", ...)) end end function premake.warnOnce(key, message, ...) if not _warnings[key] then _warnings[key] = true premake.warn(message, ...) end end function printf(msg, ...) print(string.format(msg, ...)) end function verbosef(msg, ...) if _OPTIONS.verbose then print(string.format(msg, ...)) end end function string.capitalized(self) return self:gsub("^%l", string.upper) end function string.contains(s, match) return string.find(s, match, 1, true) ~= nil end function string.explode(s, pattern, plain, maxTokens) if (pattern == '') then return false end local pos = 0 local arr = { } for st,sp in function() return s:find(pattern, pos, plain) end do table.insert(arr, s:sub(pos, st-1)) pos = sp + 1 if maxTokens ~= nil and maxTokens > 0 then maxTokens = maxTokens - 1 if maxTokens == 0 then break end end end table.insert(arr, s:sub(pos)) return arr end function string.findlast(s, pattern, plain) local curr = 0 repeat local next = s:find(pattern, curr + 1, plain) if (next) then curr = next end until (not next) if (curr > 0) then return curr end end function string.lines(s) local trailing, n = s:gsub('.-\n', '') if #trailing > 0 then n = n + 1 end return n end function string:plural() if self:endswith("y") then return self:sub(1, #self - 1) .. "ies" else return self .. "s" end end function table.arraycopy(object) local result = {} for i, value in ipairs(object) do result[i] = value end return result end function table.contains(t, value) for _,v in pairs(t) do if (v == value) then return true end end return false end function table.deepcopy(object) local seen = {} local function copy(object) if type(object) ~= "table" then return object elseif seen[object] then return seen[object] end local clone = {} seen[object] = clone for key, value in pairs(object) do clone[key] = copy(value) end return clone end return copy(object) end function table.extract(arr, fname) local result = { } for _,v in ipairs(arr) do table.insert(result, v[fname]) end return result end function table.filter(arr, fn) local result = { } table.foreachi(arr, function(val) if fn(val) then table.insert(result, val) end end) return result end function table.flatten(arr) local result = {} local function flatten(arr) local n = #arr for i = 1, n do local v = arr[i] if type(v) == "table" then flatten(v) elseif v then table.insert(result, v) end end end flatten(arr) return result end function table.foreachi(arr, func) if arr then local n = #arr for i = 1, n do local v = arr[i] if v then func(v) end end end end function table.fold(list1, list2) local result = {} for _, item1 in ipairs(list1 or {}) do if list2 and #list2 > 0 then for _, item2 in ipairs(list2) do table.insert(result, { item1, item2 }) end else table.insert(result, { item1 }) end end return result end function table.implode(arr, before, after, between) local result = "" for _,v in ipairs(arr) do if (result ~= "" and between) then result = result .. between end result = result .. before .. v .. after end return result end function table.indexof(tbl, obj) for k, v in pairs(tbl) do if v == obj then return k end end end function table.insertafter(tbl, after, value) local i = table.indexof(tbl, after) if i then table.insert(tbl, i + 1, value) else table.insert(tbl, value) end end function table.insertflat(tbl, values) if values == nil then return elseif type(values) == "table" then for _, value in ipairs(values) do table.insertflat(tbl, value) end else table.insert(tbl, values) end return tbl end function table.insertkeyed(tbl, pos, value) if value == nil then value = pos pos = #tbl + 1 end table.insert(tbl, pos, value) tbl[value] = value end function table.insertsorted(tbl, value, fn) if value == nil then return else fn = fn or function(a, b) return a < b end local minindex = 1 local maxindex = #tbl + 1 while minindex < maxindex do local index = minindex + bit32.arshift(maxindex - minindex, 1) local test = tbl[index] if fn(value, test) then maxindex = index else minindex = index + 1 if not fn(test, value) then break end end end table.insert(tbl, minindex, value) end return tbl end function table.isempty(t) return next(t) == nil end function table.join(...) local result = { } local arg = {...} for _,t in ipairs(arg) do if type(t) == "table" then for _,v in ipairs(t) do table.insert(result, v) end else table.insert(result, t) end end return result end function table.keys(tbl) local keys = {} for k, _ in pairs(tbl) do table.insert(keys, k) end return keys end function table.merge(...) local result = {} local arg = {...} for _,t in ipairs(arg) do if type(t) == "table" then for k,v in pairs(t) do if type(result[k]) == "table" and type(v) == "table" then result[k] = table.merge(result[k], v) else result[k] = v end end else error("invalid value") end end return result end function table.replace(self, value, replacement) for i = 1, #self do if self[i] == value then self[i] = replacement end end end function table.translate(arr, translation) if not translation then return {} end local result = {} for _, value in ipairs(arr) do local tvalue if type(translation) == "function" then tvalue = translation(value) else tvalue = translation[value] end if (tvalue) then table.insert(result, tvalue) end end return result end function table.tostring(tab, recurse, indent) local res = '' if not indent then indent = 0 end local format_value = function(k, v, i) formatting = string.rep("\t", i) if k then if type(k) == "table" then k = '[table]' end formatting = formatting .. k .. ": " end if not v then return formatting .. '(nil)' elseif type(v) == "table" then if recurse then return formatting .. '\n' .. table.tostring(v, recurse, i+1) else return formatting .. "" end elseif type(v) == "function" then return formatting .. tostring(v) elseif type(v) == "userdata" then return formatting .. "" elseif type(v) == "boolean" then if v then return formatting .. 'true' else return formatting .. 'false' end else return formatting .. v end end if type(tab) == "table" then local first = true for k, v in pairs(tab) do if not first then res = res .. '\n' end res = res .. format_value(k, v, indent) first = false end else res = res .. format_value(nil, tab, indent) end return res end function table.unique(tab) local elems = { } local result = { } table.foreachi(tab, function(elem) if not elems[elem] then table.insert(result, elem) elems[elem] = true end end) return result end function table.filterempty(dirs) return table.translate(dirs, function(val) if val and #val > 0 then return val else return nil end end) end function path.appendExtension(p, ext) if not ext or ext == "" then return p end local endquote if p:endswith('"') then p = p:sub(1, -2) endquote = '"' end if not path.hasextension(p, ext) then p = p .. ext end if endquote then p = p .. endquote end return p end path.appendextension = path.appendExtension function path.getbasename(p) local name = path.getname(p) local i = name:findlast(".", true) if (i) then return name:sub(1, i - 1) else return name end end function path.getdirectory(p) local i = p:findlast("/", true) if (i) then if i > 1 then i = i - 1 end return p:sub(1, i) else return "." end end function path.getdrive(p) local ch1 = p:sub(1,1) local ch2 = p:sub(2,2) if ch2 == ":" then return ch1 end end function path.getextension(p) local i = p:findlast(".", true) if (i) then return p:sub(i) else return "" end end function path.getname(p) local i = p:findlast("[/\\]") if (i) then return p:sub(i + 1) else return p end end function path.hasextension(fname, extensions) local fext = path.getextension(fname):lower() if type(extensions) == "table" then for _, extension in pairs(extensions) do if fext == extension then return true end end return false else return (fext == extensions) end end function path.iscfile(fname) return path.hasextension(fname, { ".c", ".s", ".m" }) end function path.iscppfile(fname) return path.hasextension(fname, { ".cc", ".cpp", ".cxx", ".c", ".s", ".m", ".mm" }) end function path.iscppheader(fname) return path.hasextension(fname, { ".h", ".hh", ".hpp", ".hxx" }) end function path.isframework(fname) return path.hasextension(fname, ".framework") end function path.islinkable(fname) return path.hasextension(fname, { ".o", ".obj", ".a", ".lib", ".so" }) end function path.isobjectfile(fname) return path.hasextension(fname, { ".o", ".obj" }) end function path.isresourcefile(fname) return path.hasextension(fname, ".rc") end function path.isidlfile(fname) return path.hasextension(fname, ".idl") end function path.rebase(p, oldbase, newbase) p = path.getabsolute(path.join(oldbase, p)) p = path.getrelative(newbase, p) return p end function path.replaceextension(p, newext) local ext = path.getextension(p) if not ext then return p end if not newext:findlast(".", true) then newext = "."..newext end return p:match("^(.*)"..ext.."$")..newext end premake.override(os, "execute", function(base, cmd) cmd = path.normalize(cmd) cmd = os.translateCommands(cmd) return base(cmd) end) function os.executef(cmd, ...) cmd = string.format(cmd, ...) return os.execute(cmd) end local function parse_ld_so_conf(conf_file) local first, last local dirs = { } for line in io.lines(conf_file) do first = line:find("#", 1, true) if first ~= nil then line = line:sub(1, first - 1) end if line ~= "" then first, last = line:find("include%s+") if first ~= nil then local include_glob = line:sub(last + 1) local includes = os.matchfiles(include_glob) for _, v in ipairs(includes) do dirs = table.join(dirs, parse_ld_so_conf(v)) end else table.insert(dirs, line) end end end return dirs end function os.findlib(libname, libdirs) local path, formats if os.is("windows") then formats = { "%s.dll", "%s" } path = os.getenv("PATH") or "" elseif os.is("haiku") then formats = { "lib%s.so", "%s.so" } path = os.getenv("LIBRARY_PATH") or "" else if os.is("macosx") then formats = { "lib%s.dylib", "%s.dylib" } path = os.getenv("DYLD_LIBRARY_PATH") or "" else formats = { "lib%s.so", "%s.so" } path = os.getenv("LD_LIBRARY_PATH") or "" for _, prefix in ipairs({"", "/opt"}) do local conf_file = prefix .. "/etc/ld.so.conf" if os.isfile(conf_file) then for _, v in ipairs(parse_ld_so_conf(conf_file)) do if (#path > 0) then path = path .. ":" .. v else path = v end end end end end table.insert(formats, "%s") path = path or "" local archpath = "/lib:/usr/lib:/usr/local/lib" if os.is64bit() and not os.is("macosx") then archpath = "/lib64:/usr/lib64/:usr/local/lib64" .. ":" .. archpath end if (#path > 0) then path = path .. ":" .. archpath else path = archpath end end local userpath = "" if type(libdirs) == "string" then userpath = libdirs elseif type(libdirs) == "table" then userpath = table.implode(libdirs, "", "", ":") end if (#userpath > 0) then if (#path > 0) then path = userpath .. ":" .. path else path = userpath end end for _, fmt in ipairs(formats) do local name = string.format(fmt, libname) local result = os.pathsearch(name, path) if result then return result end end end function os.get() return _OPTIONS.os or _OS end function os.is(id) return (os.get():lower() == id:lower()) end premake.override(os, "isdir", function(base, p) p = path.normalize(p) return base(p) end) premake.override(os, "isfile", function(base, p) p = path.normalize(p) return base(p) end) local _is64bit local _64BitHostTypes = { "x86_64", "ia64", "amd64", "ppc64", "powerpc64", "sparc64" } function os.is64bit() if _is64bit ~= nil then return _is64bit end _is64bit = false if (os._is64bit()) then _is64bit = true else local arch if _OS == "windows" then arch = os.getenv("PROCESSOR_ARCHITECTURE") elseif _OS == "macosx" then arch = os.outputof("echo $HOSTTYPE") else arch = os.outputof("uname -m") end arch = arch:lower() for _, hosttype in ipairs(_64BitHostTypes) do if arch:find(hosttype) then _is64bit = true end end end return _is64bit end function os.match(mask) mask = path.normalize(mask) local starpos = mask:find("%*") local before = path.getdirectory(starpos and mask:sub(1, starpos - 1) or mask) local slashpos = starpos and mask:find("/", starpos) local after = slashpos and mask:sub(slashpos + 1) local recurse = starpos and mask:sub(starpos + 1, starpos + 1) == '*' and (starpos == 1 or mask:sub(starpos - 1, starpos - 1) == '/') local results = { } if recurse then local submask = mask:sub(1, starpos) .. mask:sub(starpos + 2) results = os.match(submask) local pattern = mask:sub(1, starpos) local m = os.matchstart(pattern) while os.matchnext(m) do if not os.matchisfile(m) then local matchpath = path.join(before, os.matchname(m), mask:sub(starpos)) results = table.join(results, os.match(matchpath, after)) end end os.matchdone(m) else local pattern = mask:sub(1, slashpos and slashpos - 1) local m = os.matchstart(pattern) while os.matchnext(m) do if not (slashpos and os.matchisfile(m)) then local matchpath = path.join(before, matchpath, os.matchname(m)) if after then results = table.join(results, os.match(path.join(matchpath, after))) else table.insert(results, matchpath) end end end os.matchdone(m) end return results end function os.matchdirs(mask) local results = os.match(mask) for i = #results, 1, -1 do if not os.isdir(results[i]) then table.remove(results, i) end end return results end function os.matchfiles(mask) local results = os.match(mask) for i = #results, 1, -1 do if not os.isfile(results[i]) then table.remove(results, i) end end return results end local builtin_mkdir = os.mkdir function os.mkdir(p) p = path.normalize(p) local dir = iif(p:startswith("/"), "/", "") for part in p:gmatch("[^/]+") do dir = dir .. part if (part ~= "" and not path.isabsolute(part) and not os.isdir(dir)) then local ok, err = builtin_mkdir(dir) if (not ok) then return nil, err end end dir = dir .. "/" end return true end function os.outputof(cmd) cmd = path.normalize(cmd) local pipe = io.popen(cmd) local result = pipe:read('*a') local b, exitcode = pipe:close() if not b then exitcode = -1 end if result then result = string.gsub(result, "[\r\n]+$", "") end return result, exitcode end local builtin_remove = os.remove function os.remove(f) if type(f) == "string" then local p = os.matchfiles(f) for _, v in pairs(p) do local ok, err = builtin_remove(v) if not ok then return ok, err end end elseif type(f) == "table" then for _, v in pairs(f) do local ok, err = os.remove(v) if not ok then return ok, err end end end end local builtin_rmdir = os.rmdir function os.rmdir(p) local dirs = os.matchdirs(p .. "/*") for _, dname in ipairs(dirs) do os.rmdir(dname) end local files = os.matchfiles(p .. "/*") for _, fname in ipairs(files) do os.remove(fname) end builtin_rmdir(p) end premake.override(os, "stat", function(base, p) p = path.normalize(p) return base(p) end) os.commandTokens = { _ = { chdir = function(v) return "cd " .. v end, copy = function(v) return "cp -rf " .. v end, delete = function(v) return "rm -f " .. v end, echo = function(v) return "echo " .. v end, mkdir = function(v) return "mkdir -p " .. v end, move = function(v) return "mv -f " .. v end, rmdir = function(v) return "rm -rf " .. v end, touch = function(v) return "touch " .. v end, }, windows = { chdir = function(v) return "chdir " .. path.translate(v) end, copy = function(v) v = path.translate(v) local src = string.match(v, '^".-"') or string.match(v, '^.- ') or v src = string.match(src, '^.*%S') return "IF EXIST " .. src .. "\\ (xcopy /Q /E /Y /I " .. v .. " > nul) ELSE (xcopy /Q /Y /I " .. v .. " > nul)" end, delete = function(v) return "del " .. path.translate(v) end, echo = function(v) return "echo " .. v end, mkdir = function(v) return "mkdir " .. path.translate(v) end, move = function(v) return "move /Y " .. path.translate(v) end, rmdir = function(v) return "rmdir /S /Q " .. path.translate(v) end, touch = function(v) v = path.translate(v) return string.format("type nul >> %s && copy /b %s+,, %s", v, v, v) end, } } function os.translateCommands(cmd, map) map = map or os.get() if type(map) == "string" then map = os.commandTokens[map] or os.commandTokens["_"] end local processOne = function(cmd) local token = cmd:match("^{.+}") if token then token = token:sub(2, #token - 1):lower() local args = cmd:sub(#token + 4) local func = map[token] or os.commandTokens["_"][token] if func then cmd = func(args) end end return cmd end if type(cmd) == "table" then local result = {} for i = 1, #cmd do result[i] = processOne(cmd[i]) end return result else return processOne(cmd) end end os._uuids = {} local builtin_uuid = os.uuid function os.uuid(name) local id = builtin_uuid(name) if name then if os._uuids[id] and os._uuids[id] ~= name then premake.warnOnce(id, "UUID clash between %s and %s", os._uuids[id], name) end os._uuids[id] = name end return id end premake.override(io, "open", function(base, fname, mode) if mode and (mode:find("w") or mode:find("a")) then local dir = path.getdirectory(fname) ok, err = os.mkdir(dir) if not ok then error(err, 0) end end return base(fname, mode) end) local p = premake p.tools = {} function p.tools.canonical(identifier) local parts if identifier:startswith("v") then -- TODO: this should be deprecated? parts = { "msc", identifier } else parts = identifier:explode("-", true, 1) if parts[2] ~= nil then if parts[1] == "msc" and tonumber(parts[2]:sub(1,3)) ~= nil then parts[2] = "v" .. parts[2] end if parts[2]:startswith("llvm-vs") then parts[2] = "LLVM-" .. parts[2]:sub(6) end end end return p.tools[parts[1]], parts[2] end premake.tree = {} local tree = premake.tree function tree.new(n) local t = { name = n, children = {} } return t end function tree.add(tr, p, extraFields) if p == "." or p == "/" then return tr end local parentnode = tree.add(tr, path.getdirectory(p), extraFields) local childname = path.getname(p) local childnode = parentnode.children[childname] if not childnode or childnode.path ~= p then childnode = tree.insert(parentnode, tree.new(childname)) childnode.path = p if extraFields then for k,v in pairs(extraFields) do childnode[k] = v end end end return childnode end function tree.insert(parent, child) table.insert(parent.children, child) if child.name then parent.children[child.name] = child end child.parent = parent return child end function tree.getlocalpath(node) if node.parent.path then return node.name elseif node.cfg then return node.cfg.name else return node.path end end function tree.hasbranches(tr) local n = #tr.children if n > 0 then for i = 1, n do if #tr.children[i].children > 0 then return true end end end return false end function tree.isparent(n, child) local p = child.parent while p do if p == n then return true end p = p.parent end return false end function tree.remove(node) local children = node.parent.children for i = 1, #children do if children[i] == node then table.remove(children, i) end end node.children = {} end function tree.sort(tr, fn) if not fn then fn = function(a,b) return a.name < b.name end end tree.traverse(tr, { onnode = function(node) table.sort(node.children, fn) end }, true) end function tree.traverse(t, fn, includeroot, initialdepth) local donode, dochildren donode = function(node, fn, depth) if node.isremoved then return end if fn.onnode then fn.onnode(node, depth) end if #node.children > 0 then if fn.onbranchenter then fn.onbranchenter(node, depth) end if fn.onbranch then fn.onbranch(node, depth) end dochildren(node, fn, depth + 1) if fn.onbranchexit then fn.onbranchexit(node, depth) end else if fn.onleaf then fn.onleaf(node, depth) end end end dochildren = function(parent, fn, depth) local i = 1 while i <= #parent.children do local node = parent.children[i] donode(node, fn, depth) if node == parent.children[i] then i = i + 1 end end end if not initialdepth then initialdepth = 0 end if includeroot then donode(t, fn, initialdepth) else dochildren(t, fn, initialdepth) end end function tree.trimroot(tr) local trimmed while #tr.children == 1 do local node = tr.children[1] if #node.children == 0 or node.trim == false then break end trimmed = true local numChildren = #node.children for i = 1, numChildren do local child = node.children[i] child.parent = node.parent tr.children[i] = child end end local dotdot local count = #tr.children repeat dotdot = false for i = 1, count do local node = tr.children[i] if node.name == ".." and #node.children == 1 then local child = node.children[1] child.parent = node.parent tr.children[i] = child trimmed = true dotdot = true end end until not dotdot if trimmed then tree.traverse(tr, { onnode = function(node) if node.parent.path then node.path = path.join(node.parent.path, node.name) else node.path = node.name end end }, false) end end function dofileopt(fname) if type(fname) == "string" then fname = {fname} end for i = 1, #fname do local found = os.locate(fname[i]) if not found then found = os.locate(fname[i] .. ".lua") end if found then dofile(found) return true end end end io._includedFiles = {} function include(fname) local fullPath = premake.findProjectScript(fname) fname = fullPath or fname if not io._includedFiles[fname] then io._includedFiles[fname] = true return dofile(fname) end end premake.override(_G, "require", function(base, modname, versions) local result, mod = pcall(base,modname) if not result then error( mod, 3 ) end if mod and versions and not premake.checkVersion(mod._VERSION, versions) then error(string.format("module %s %s does not meet version criteria %s", modname, mod._VERSION or "(none)", versions), 3) end return mod end) local semver = { _VERSION = '1.2.0', _DESCRIPTION = 'semver for Lua', _URL = 'https://github.com/kikito/semver.lua', _LICENSE = [[ MIT LICENSE Copyright (c) 2015 Enrique García Cota Permission is hereby granted, free of charge, to any person obtaining a copy of tother 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 tother 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. ]] } local function checkPositiveInteger(number, name) assert(number >= 0, name .. ' must be a valid positive number') assert(math.floor(number) == number, name .. ' must be an integer') end local function present(value) return value and value ~= '' end local function splitByDot(str) str = str or "" local t, count = {}, 0 str:gsub("([^%.]+)", function(c) count = count + 1 t[count] = c end) return t end local function parsePrereleaseAndBuildWithSign(str) local prereleaseWithSign, buildWithSign = str:match("^(-[^+]+)(+.+)$") if not (prereleaseWithSign and buildWithSign) then prereleaseWithSign = str:match("^(-.+)$") buildWithSign = str:match("^(+.+)$") end assert(prereleaseWithSign or buildWithSign, ("The parameter %q must begin with + or - to denote a prerelease or a build"):format(str)) return prereleaseWithSign, buildWithSign end local function parsePrerelease(prereleaseWithSign) if prereleaseWithSign then local prerelease = prereleaseWithSign:match("^-(%w[%.%w-]*)$") assert(prerelease, ("The prerelease %q is not a slash followed by alphanumerics, dots and slashes"):format(prereleaseWithSign)) return prerelease end end local function parseBuild(buildWithSign) if buildWithSign then local build = buildWithSign:match("^%+(%w[%.%w-]*)$") assert(build, ("The build %q is not a + sign followed by alphanumerics, dots and slashes"):format(buildWithSign)) return build end end local function parsePrereleaseAndBuild(str) if not present(str) then return nil, nil end local prereleaseWithSign, buildWithSign = parsePrereleaseAndBuildWithSign(str) local prerelease = parsePrerelease(prereleaseWithSign) local build = parseBuild(buildWithSign) return prerelease, build end local function parseVersion(str) local sMajor, sMinor, sPatch, sPrereleaseAndBuild = str:match("^(%d+)%.?(%d*)%.?(%d*)(.-)$") assert(type(sMajor) == 'string', ("Could not extract version number(s) from %q"):format(str)) local major, minor, patch = tonumber(sMajor), tonumber(sMinor), tonumber(sPatch) local prerelease, build = parsePrereleaseAndBuild(sPrereleaseAndBuild) return major, minor, patch, prerelease, build end local function compare(a,b) return a == b and 0 or a < b and -1 or 1 end local function compareIds(myId, otherId) if myId == otherId then return 0 elseif not myId then return -1 elseif not otherId then return 1 end local selfNumber, otherNumber = tonumber(myId), tonumber(otherId) if selfNumber and otherNumber then -- numerical comparison return compare(selfNumber, otherNumber) -- numericals are always smaller than alphanums elseif selfNumber then return -1 elseif otherNumber then return 1 else return compare(myId, otherId) -- alphanumerical comparison end end local function smallerIdList(myIds, otherIds) local myLength = #myIds local comparison for i=1, myLength do comparison = compareIds(myIds[i], otherIds[i]) if comparison ~= 0 then return comparison == -1 end -- if comparison == 0, continue loop end return myLength < #otherIds end local function smallerPrerelease(mine, other) if mine == other or not mine then return false elseif not other then return true end return smallerIdList(splitByDot(mine), splitByDot(other)) end local methods = {} function methods:nextMajor() return semver(self.major + 1, 0, 0) end function methods:nextMinor() return semver(self.major, self.minor + 1, 0) end function methods:nextPatch() return semver(self.major, self.minor, self.patch + 1) end local mt = { __index = methods } function mt:__eq(other) return self.major == other.major and self.minor == other.minor and self.patch == other.patch and self.prerelease == other.prerelease -- notice that build is ignored for precedence in semver 2.0.0 end function mt:__lt(other) if self.major ~= other.major then return self.major < other.major end if self.minor ~= other.minor then return self.minor < other.minor end if self.patch ~= other.patch then return self.patch < other.patch end return smallerPrerelease(self.prerelease, other.prerelease) -- notice that build is ignored for precedence in semver 2.0.0 end function mt:__pow(other) return self.major == other.major and self.minor <= other.minor end function mt:__tostring() local buffer = { ("%d.%d.%d"):format(self.major, self.minor, self.patch) } if self.prerelease then table.insert(buffer, "-" .. self.prerelease) end if self.build then table.insert(buffer, "+" .. self.build) end return table.concat(buffer) end local function new(major, minor, patch, prerelease, build) assert(major, "At least one parameter is needed") if type(major) == 'string' then major,minor,patch,prerelease,build = parseVersion(major) end patch = patch or 0 minor = minor or 0 checkPositiveInteger(major, "major") checkPositiveInteger(minor, "minor") checkPositiveInteger(patch, "patch") local result = {major=major, minor=minor, patch=patch, prerelease=prerelease, build=build} return setmetatable(result, mt) end setmetatable(semver, { __call = function(_, ...) return new(...) end }) semver._VERSION= semver(semver._VERSION) return semver premake.field = {} local field = premake.field field._list = {} field._loweredList = {} field._sortedList = nil field._kinds = {} premake.fields = field._list field._accessors = {} function field.new(f) if f.kind:startswith("key-") then f.kind = f.kind:sub(5) f.keyed = true end if f.kind:endswith("-list") then f.kind = f.kind:sub(1, -6) f.list = true end local kind = f.kind if kind == "object" or kind == "array" then kind = "table" end if f.list then kind = "list:" .. kind end if f.keyed then kind = "keyed:" .. kind end f._kind = kind if type(f.scope) == "table" then f.scopes = f.scope else f.scopes = { f.scope } end if not field.accessor(f, "store") then return nil, "invalid field kind '" .. f._kind .. "'" end field._list[f.name] = f field._loweredList[f.name:lower()] = f field._sortedList = nil return f end function field.unregister(f) field._list[f.name] = nil field._loweredList[f.name:lower()] = nil field._sortedList = nil end function field.each() local index return function () index = next(field._list, index) return field._list[index] end end function field.eachOrdered() if not field._sortedList then local keys = table.keys(field._list) table.sort(keys) field._sortedList = {} for i = 1, #keys do field._sortedList[i] = field._list[keys[i]] end end local i = 0 return function () i = i + 1 return field._sortedList[i] end end function field.kind(tag, settings) if settings then field._kinds[tag] = settings end return field._kinds[tag] end function field.accessor(f, method) field._accessors[method] = field._accessors[method] or {} local cache = field._accessors[method] local function accessorForKind(kind) if kind == "" then return nil end if cache[kind] then return cache[kind] end local thisKind = kind:match('(.-):') or kind local nextKind = kind:sub(#thisKind + 2) local functions = field._kinds[thisKind] if not functions then return nil, "Invalid field kind '" .. thisKind .. "'" end local processor = functions[method] if not processor then return nil end local nextAccessor = accessorForKind(nextKind) accessor = function(f, current, value) return processor(f, current, value, nextAccessor) end cache[kind] = accessor return accessor end return accessorForKind(f._kind) end function field.compare(f, a, b) local processor = field.accessor(f, "compare") if processor then return processor(f, a, b) else return (a == b) end end function field.get(name) return field._list[name] or field._loweredList[name:lower()] end function field.merge(f, current, value) local processor = field.accessor(f, "merge") if processor then return processor(f, current, value) else return value end end function field.merges(f) return (field.accessor(f, "merge") ~= nil) end function field.property(f, tag) local kinds = string.explode(f._kind, ":", true) for i, kind in ipairs(kinds) do local value = field._kinds[kind][tag] if value ~= nil then return value end end end function field.override(fieldName, accessorName, func) local kind = field.kind(fieldName) premake.override(kind, accessorName, func) field._accessors = {} end function field.remove(f, current, value) local processor = field.accessor(f, "remove") if processor then return processor(f, current, value) else return value end end function field.removes(f) return (field.accessor(f, "merge") ~= nil and field.accessor(f, "remove") ~= nil) end function field.store(f, current, value) local processor = field.accessor(f, "store") if processor then return processor(f, current, value) else return value end end function field.translate(f, value) local processor = field.accessor(f, "translate") if processor then return processor(f, value, nil)[1] else return value end end function field.translates(f) return (field.accessor(f, "translate") ~= nil) end local p = premake p.criteria = criteria -- criteria namespace is defined in C host local criteria = p.criteria criteria._validPrefixes = { _action = true, action = true, architecture = true, configurations = true, files = true, kind = true, language = true, _options = true, options = true, platforms = true, system = true, } function criteria.new(terms, unprefixed) terms = table.flatten(terms) local patterns = {} for i, term in ipairs(terms) do term = term:lower() local pattern = {} local prefix = iif(unprefixed, nil, "configurations") local words = term:explode(" or ") for _, word in ipairs(words) do word, prefix = criteria._word(word, prefix) if prefix and not criteria._validPrefixes[prefix] then return nil, string.format("Invalid field prefix '%s'", prefix) end if prefix then local fld = p.field.get(prefix) if fld and fld.aliases then word[1] = fld.aliases[word[1]] or word[1] end end table.insert(pattern, word) end table.insert(patterns, pattern) end local crit = {} crit.patterns = patterns crit.data = criteria._compile(patterns) return crit end function criteria._word(word, prefix) local wildcard local assertion = true while (true) do if word:startswith("not ") then assertion = not assertion word = word:sub(5) else local i = word:find(":", 1, true) if prefix and i then prefix = word:sub(1, i - 1) word = word:sub(i + 1) else wildcard = (word:find("*", 1, true) ~= nil) if wildcard then word = path.wildcards(word) end break end end end return { word, prefix, assertion, wildcard }, prefix end function criteria.allowPrefix(prefix) criteria._validPrefixes[prefix:lower()] = true end premake.detoken = {} local p = premake local detoken = p.detoken function detoken.expand(value, environ, field, basedir) field = field or {} local varMap = {} if field.pathVars then local action = p.action.current() if action then varMap = action.pathVars or {} end end setmetatable(environ, {__index = _G}) function expandtoken(token, e) local func, err = loadstring("return " .. token) if not func then return nil, "load error: " .. err end setfenv(func, e) local success, result = pcall(func) if not success then err = result result = nil else err = nil end local isAbs = false if result ~= nil then isAbs = path.isabsolute(result) if isAbs and not field.paths and basedir then result = path.getrelative(basedir, result) end end if varMap[token] then err = nil result = varMap[token] if type(result) == "function" then success, result = pcall(result, e) if not success then return nil, result end end if (type(result) == "table") then isAbs = result.absolute result = result.token else isAbs = path.isabsolute(result) end end if result ~= nil and isAbs and field.paths then result = "\0" .. result end return result, err end function expandvalue(value, e) if type(value) ~= "string" then return value end local count repeat value, count = value:gsub("%%{(.-)}", function(token) local result, err = expandtoken(token:gsub("\\", "\\\\"), e) if err then error(err .. " in token: " .. token, 0) end if not result then error("Token returned nil, it may not exist: " .. token, 0) end return result end) until count == 0 if field.paths then local i, j repeat i, j = value:find("\0") if i then value = value:sub(i + 1) end until not i end return value end function recurse(value, e) if type(value) == "table" then local res_table = {} for k, v in pairs(value) do if tonumber(k) ~= nil then res_table[k] = recurse(v, e) else local nk = recurse(k, e); res_table[nk] = recurse(v, e) end end return res_table else return expandvalue(value, e) end end return recurse(value, environ) end local p = premake p.configset = {} local configset = p.configset local criteria = p.criteria function configset.new(parent) local cset = {} cset.parent = parent cset.blocks = {} cset.current = nil cset.compiled = false return cset end function configset.fetch(cset, field, filter, ctx, origin) filter = filter or {} ctx = ctx or {} if p.field.merges(field) then return configset._fetchMerged(cset, field, filter, ctx, origin) else return configset._fetchDirect(cset, field, filter, ctx, origin) end end function configset._fetchDirect(cset, field, filter, ctx, origin) if origin and origin ~= cset and not origin.compiled then return configset._fetchDirect(origin, field, filter, ctx, origin) end local abspath = filter.files local basedir local key = field.name local blocks = cset.blocks local n = #blocks for i = n, 1, -1 do local block = blocks[i] if not origin or block._origin == origin then local value = block[key] if value ~= nil and abspath and not cset.compiled and block._basedir and block._basedir ~= basedir then basedir = block._basedir filter.files = path.getrelative(basedir, abspath) end if value ~= nil and (cset.compiled or criteria.matches(block._criteria, filter)) then if type(value) == "table" then value = table.deepcopy(value) end if field.tokens and ctx.environ then value = p.detoken.expand(value, ctx.environ, field, ctx._basedir) end return value end end end filter.files = abspath if cset.parent then return configset._fetchDirect(cset.parent, field, filter, ctx, origin) end end function configset._fetchMerged(cset, field, filter, ctx, origin) if origin and origin ~= cset and not origin.compiled then return configset._fetchMerged(origin, field, filter, ctx, origin) end local result = {} local function remove(patterns) for _, pattern in ipairs(patterns) do if field.tokens and ctx.environ then pattern = p.detoken.expand(pattern, ctx.environ, field, ctx._basedir) end pattern = path.wildcards(pattern):lower() local j = 1 while j <= #result do local value = result[j]:lower() if value:match(pattern) == value then result[result[j]] = nil table.remove(result, j) else j = j + 1 end end end end if cset.parent then result = configset._fetchMerged(cset.parent, field, filter, ctx, origin) end local abspath = filter.files local basedir local key = field.name local blocks = cset.blocks local n = #blocks for i = 1, n do local block = blocks[i] if not origin or block._origin == origin then if abspath and block._basedir and block._basedir ~= basedir and not cset.compiled then basedir = block._basedir filter.files = path.getrelative(basedir, abspath) end if cset.compiled or criteria.matches(block._criteria, filter) then if block._removes and block._removes[key] then remove(block._removes[key]) end local value = block[key] if type(value) == "table" then value = table.deepcopy(value) end if value then if field.tokens and ctx.environ then value = p.detoken.expand(value, ctx.environ, field, ctx._basedir) end if field and p.field.translates(field) then value = p.field.translate(field, value) end result = p.field.merge(field, result, value) end end end end filter.files = abspath return result end function configset.metatable(cset) return { __newindex = function(tbl, key, value) local f = p.field.get(key) if f then local status, err = configset.store(cset, f, value) if err then error(err, 2) end else rawset(tbl, key, value) return value end end, __index = function(tbl, key) local f = p.field.get(key) if f then return configset.fetch(cset, f) else return nil end end } end function configset.addblock(cset, terms, basedir) configset.addFilter(cset, terms, basedir, true) return cset.current end function configset.addFilter(cset, terms, basedir, unprefixed) local crit, err = criteria.new(terms, unprefixed) if not crit then return nil, err end local block = {} block._criteria = crit block._origin = cset if basedir then block._basedir = basedir:lower() end table.insert(cset.blocks, block) cset.current = block return true end function configset.getFilter(cset) return { _criteria = cset.current._criteria, _basedir = cset.current._basedir } end function configset.setFilter(cset, filter) local block = {} block._criteria = filter._criteria block._basedir = filter._basedir block._origin = cset table.insert(cset.blocks, block) cset.current = block; end function configset.store(cset, field, value) if not cset.current then configset.addblock(cset, {}) end local key = field.name local current = cset.current local status, result = pcall(function () current[key] = p.field.store(field, current[key], value) end) if not status then if type(result) == "table" then result = result.msg end return nil, result end return true end function configset.remove(cset, field, values) local block = {} block._basedir = cset.current._basedir block._criteria = cset.current._criteria block._origin = cset table.insert(cset.blocks, block) cset.current = block values = p.field.remove(field, {}, values) current = cset.current current._removes = {} current._removes[field.name] = values end function configset.empty(cset) return (#cset.blocks == 0) end function configset.compile(cset, filter) local result if cset.parent then result = configset.compile(cset.parent, filter) else result = configset.new() end local blocks = cset.blocks local n = #blocks local abspath = filter.files local basedir for i = 1, n do local block = blocks[i] if block._origin == cset then block._origin = result end if abspath and block._basedir and block._basedir ~= basedir then basedir = block._basedir filter.files = path.getrelative(basedir, abspath) end if criteria.matches(block._criteria, filter) then table.insert(result.blocks, block) end end filter.files = abspath result.compiled = true return result end local p = premake p.context = {} local context = p.context local configset = p.configset function context.new(cfgset, environ) local ctx = {} ctx._cfgset = cfgset ctx.environ = environ or {} ctx.terms = {} ctx._basedir = os.getcwd() setmetatable(ctx, context.__mt) return ctx end function context.addFilter(ctx, key, value) if type(value) == "table" then for i = 1, #value do value[i] = value[i]:lower() end elseif value then value = value:lower() end ctx.terms[key:lower()] = value end function context.copyFilters(ctx, src) ctx.terms = table.deepcopy(src.terms) end function context.mergeFilters(ctx, src) local function mergeTable(dest, src) for k,v in pairs(src) do if type(v) == "table" then if type(dest[k]) == "table" then dest[k] = mergeTable(dest[k], v) else dest[k] = table.deepcopy(v) end else dest[k] = v end end end mergeTable(ctx.terms, src.terms) end function context.basedir(ctx, basedir) ctx._basedir = basedir or ctx._basedir return ctx._basedir end function context.compile(ctx) ctx._cfgset = configset.compile(ctx._cfgset, ctx.terms) end function context.empty(ctx) return configset.empty(ctx._cfgset) end function context.fetchvalue(ctx, key, onlylocal) if not onlylocal then local value = rawget(ctx, key) if value ~= nil then return value end end local field = p.field.get(key) if not field then return nil end local value = configset.fetch(ctx._cfgset, field, ctx.terms, ctx, onlylocal and ctx._cfgset) if value then ctx[key] = value end return value end context.__mt = { __index = context.fetchvalue } local p = premake p.container = {} local container = p.container container.classes = {} function container.newClass(name, parent, extraScopes) local class = p.configset.new(parent) class.name = name class.pluralName = name:plural() class.containedClasses = {} class.extraScopes = extraScopes if parent then table.insert(parent.containedClasses, class) end container.classes[name] = class return class end function container.new(class, name) local self = p.configset.new() setmetatable(self, p.configset.metatable(self)) self.class = class self.name = name self.filename = name self.script = _SCRIPT self.basedir = os.getcwd() self.external = false for childClass in container.eachChildClass(class) do self[childClass.pluralName] = {} end return self end function container.addChild(self, child) local children = self[child.class.pluralName] table.insert(children, child) children[child.name] = child child.parent = self child[self.class.name] = self if self.class.alias then child[self.class.alias] = self end end function container.bake(self) if self._isBaked then return self end self._isBaked = true local ctx = p.context.new(self) for key, value in pairs(self) do ctx[key] = value end local parent = self.parent ctx[parent.class.name] = parent for class in container.eachChildClass(self.class) do for child in container.eachChild(self, class) do child.parent = ctx child[self.class.name] = ctx end end if type(self.class.bake) == "function" then self.class.bake(ctx) end return ctx end function container.bakeChildren(self) for class in container.eachChildClass(self.class) do local children = self[class.pluralName] for i = 1, #children do local ctx = container.bake(children[i]) children[i] = ctx children[ctx.name] = ctx end end end function container.classCanContain(class, scope) if type(scope) == "table" then for i = 1, #scope do if container.classCanContain(class, scope[i]) then return true end end return false end for child in container.eachChildClass(class) do if (container.classCanContain(child, scope)) then return true end end if class.name == scope or class.alias == scope then return true end if class.extraScopes and table.contains(class.extraScopes, scope) then return true end return false end function container.classIsA(class, scope) while class do if class.name == scope or class.alias == scope then return true end class = class.parent end return false end function container.eachChildClass(class) local children = class.containedClasses local i = 0 return function () i = i + 1 if i <= #children then return children[i] end end end function container.eachChild(self, class) local children = self[class.pluralName] local i = 0 return function () i = i + 1 if i <= #children then return children[i] end end end function container.getChild(self, class, name) local children = self[class.pluralName] return children[name] end function container.getClass(name) return container.classes[name] end function container.hasChild(self, class, func) for child in container.eachChild(self, class) do if func(child) then return true end end end function container.validate(self) if type(self.class.validate) == "function" then self.class.validate(self) end end function container.validateChildren(self) for class in container.eachChildClass(self.class) do local children = self[class.pluralName] for i = 1, #children do container.validate(children[i]) end end end premake.option = {} local m = premake.option local _OPTIONS_metatable = { __index = function(tbl, key) if type(key) == "string" then key = key:lower() end return rawget(tbl, key) end, __newindex = function(tbl, key, value) if type(key) == "string" then key = key:lower() end rawset(tbl, key, value) end } _OPTIONS = {} setmetatable(_OPTIONS, _OPTIONS_metatable) for i, arg in ipairs(_ARGV) do local key, value local i = arg:find("=", 1, true) if i then key = arg:sub(1, i - 1) value = arg:sub(i + 1) else key = arg value = "" end if key:startswith("/") then _OPTIONS[key:sub(2)] = value elseif key:startswith("--") then _OPTIONS[key:sub(3)] = value end end m.list = {} function m.add(opt) local missing for _, field in ipairs({ "description", "trigger" }) do if (not opt[field]) then missing = field end end if (missing) then error("option needs a " .. missing, 3) end premake.option.list[opt.trigger:lower()] = opt if opt.default and not _OPTIONS[opt.trigger] then _OPTIONS[opt.trigger] = opt.default end end function m.get(name) return premake.option.list[name] end function m.each() local keys = { } for _, option in pairs(premake.option.list) do table.insert(keys, option.trigger) end table.sort(keys) local i = 0 return function() i = i + 1 return premake.option.list[keys[i]] end end function m.validate(values) for key, value in pairs(values) do local opt = premake.option.get(key) if (not opt) then return false, "invalid option '" .. key .. "'" end if (opt.value and value == "") then return false, "no value specified for option '" .. key .. "'" end if opt.allowed then local found = false for _, match in ipairs(opt.allowed) do if match[1] == value then found = true break end end if not found then return false, string.format("invalid value '%s' for option '%s'", value, key) end end end return true end local p = premake p.action = {} local action = premake.action _ACTION = nil _ARGS = {} for i, arg in ipairs(_ARGV) do if not arg:startswith("/") and not arg:startswith("--") then if not _ACTION then _ACTION = arg else table.insert(_ARGS, arg) _ARGS[arg] = arg end end end action._list = {} function action.add(act) local missing for _, field in ipairs({"description", "trigger"}) do if not act[field] then missing = field end end if missing then local name = act.trigger or "" error(string.format('action "%s" needs a %s', name, missing), 3) end action._list[act.trigger] = act end function action.call(name) local a = action._list[name] if a.onStart then a.onStart() end for wks in p.global.eachWorkspace() do local onWorkspace = a.onWorkspace or a.onSolution or a.onsolution if onWorkspace and not wks.external then onWorkspace(wks) end for prj in p.workspace.eachproject(wks) do local onProject = a.onProject or a.onproject if onProject and not prj.external then onProject(prj) end end end for rule in p.global.eachRule() do local onRule = a.onRule or a.onrule if onRule and not rule.external then onRule(rule) end end if a.execute then a.execute() end if a.onEnd then a.onEnd() end end function action.current() return action.get(_ACTION) end function action.get(name) if name and name:endswith("ng") then name = name:sub(1, -3) end return action._list[name] end function action.each() local keys = { } for _, act in pairs(action._list) do table.insert(keys, act.trigger) end table.sort(keys) local i = 0 return function() i = i + 1 return action._list[keys[i]] end end function action.isConfigurable(self) if not self then self = action.current() or {} end if self.onSolution or self.onsolution then return true end if self.onProject or self.onproject then return true end return false end function action.set(name) _ACTION = name local act = action.get(name) if act then _OS = act.os or _OS end if act and act.module then require(act.module) end end function action.supports(feature) if not feature then return true end local self = action.current() if not self then return false end if not self.valid_languages and not self.valid_kinds then return true end if self.valid_languages then if table.contains(self.valid_languages, feature) then return true end end if self.valid_kinds then if table.contains(self.valid_kinds, feature) then return true end end return false end function premake.action.supportsconfig(action, cfg) if not action then return false end if action.supportsconfig then return action.supportsconfig(cfg) end return true end local p = premake p.api = {} local api = premake.api local configset = p.configset api.scope = {} function api.container(containerName, parentContainer, extraScopes) local class, err = p.container.newClass(containerName, parentContainer, extraScopes) if not class then error(err, 2) end _G[containerName] = function(name) local c = api._setContainer(class, name) if api._isIncludingExternal then c.external = true end return c end _G["external" .. containerName] = function(name) local c = _G[containerName](name) c.external = true return c end p.alias(_G, "external" .. containerName, "external" .. containerName:capitalized()) return class end function includeexternal(fname) local fullPath = premake.findProjectScript(fname) api._isIncludingExternal = true fname = fullPath or fname dofile(fname) api._isIncludingExternal = nil end p.alias(_G, "includeexternal", "includeExternal") function api.rootContainer() return api.scope.global end function api._setContainer(class, name) local instance if name == "*" then return api._setContainer(class.parent) end if not name then instance = api.scope[class.name] if not instance then error("no " .. class.name .. " in scope", 3) end end local parent if not instance and class.parent then parent = api.scope[class.parent.name] if not parent then error("no " .. class.parent.name .. " in scope", 3) end instance = p.container.getChild(parent, class, name) end if instance then configset.addFilter(instance, {}, os.getcwd()) end if not instance then instance = class.new(name) if parent then p.container.addChild(parent, instance) end end api._clearContainerChildren(class) if not class.placeholder then api.scope.current = instance end while instance do api.scope[instance.class.name] = instance if instance.class.alias then api.scope[instance.class.alias] = instance end instance = instance.parent end return api.scope.current end function api._clearContainerChildren(class) for childClass in p.container.eachChildClass(class) do api.scope[childClass.name] = nil if childClass.alias then api.scope[childClass.alias] = nil end api._clearContainerChildren(childClass) end end function api.register(field) local name = field.name if not name then error("missing name", 2) end if rawget(_G, name) then error("name '" .. name .. "' in use", 2) end field, err = premake.field.new(field) if not field then error(err) end field.paths = premake.field.property(field, "paths") if type(field.allowed) == "table" then for i, item in ipairs(field.allowed) do field.allowed[item:lower()] = item end end if type(field.aliases) == "table" then local keys = table.keys(field.aliases) for i, key in ipairs(keys) do field.aliases[key:lower()] = field.aliases[key] end end _G[name] = function(value) return api.storeField(field, value) end if premake.field.removes(field) then _G["remove" .. name] = function(value) return api.remove(field, value) end end return field end function api.unregister(field) if type(field) == "string" then field = premake.field.get(field) end premake.field.unregister(field) _G[field.name] = nil _G["remove" .. field.name] = nil end function api.alias(original, alias) p.alias(_G, original, alias) if _G["remove" .. original] then p.alias(_G, "remove" .. original, "remove" .. alias) end end function api.addAllowed(fieldName, value) local field = premake.field.get(fieldName) if not field then error("No such field: " .. fieldName, 2) end if type(value) == "table" then for i, item in ipairs(value) do api.addAllowed(fieldName, item) end else field.allowed = field.allowed or {} table.insert(field.allowed, value) field.allowed[value:lower()] = value end end function api.addAliases(fieldName, value) local field = premake.field.get(fieldName) if not field then error("No such field: " .. fieldName, 2) end field.aliases = field.aliases or {} for k, v in pairs(value) do field.aliases[k] = v field.aliases[k:lower()] = v end end function api.deprecateField(name, message, handler) premake.fields[name].deprecated = { handler = handler, message = message } end function api.deprecateValue(name, value, message, addHandler, removeHandler) if type(value) == "table" then for _, v in pairs(value) do api.deprecateValue(name, v, message, addHandler, removeHandler) end else local field = premake.fields[name] field.deprecated = field.deprecated or {} field.deprecated[value] = { add = addHandler, remove = removeHandler, message = message } end end function api.deprecations(value) value = value:lower() if not table.contains({ "on", "off", "error"}, value) then error("Invalid value: " .. value, 2) end api._deprecations = value:lower() end api._deprecations = "on" function api.target(field) if p.container.classCanContain(api.scope.current.class, field.scope) then return api.scope.current end return nil end function api.storeField(field, value) if value == nil then return end if field.deprecated and type(field.deprecated.handler) == "function" then field.deprecated.handler(value) if field.deprecated.message and api._deprecations ~= "off" then premake.warnOnce(field.name, "the field %s has been deprecated.\n %s", field.name, field.deprecated.message) if api._deprecations == "error" then error("deprecation errors enabled", 3) end end end local target = api.target(field) if not target then local err = string.format("unable to set %s in %s scope, should be %s", field.name, api.scope.current.class.name, table.concat(field.scopes, ", ")) error(err, 3) end local status, err = configset.store(target, field, value) if err then error(err, 3) end end function api.remove(field, value) if value == nil then return end local target = api.target(field) if not target then local err = string.format("unable to remove %s from %s scope, should be %s", field.name, api.scope.current.class.name, table.concat(field.scopes, ", ")) error(err, 3) end local hasDeprecatedValues = (type(field.deprecated) == "table") local removes = {} function check(value) if field.deprecated[value] then local handler = field.deprecated[value] if handler.remove then handler.remove(value) end if handler.message and api._deprecations ~= "off" then local key = field.name .. "_" .. value premake.warnOnce(key, "the %s value %s has been deprecated.\n %s", field.name, value, handler.message) if api._deprecations == "error" then error { msg="deprecation errors enabled" } end end end end local function recurse(value) if type(value) == "table" then table.foreachi(value, recurse) elseif hasDeprecatedValues and value:contains("*") then local current = configset.fetch(target, field) local mask = path.wildcards(value) for _, item in ipairs(current) do if item:match(mask) == item then recurse(item) end end table.insert(removes, value) else local value, err, additional = api.checkValue(field, value) if err then error { msg=err } end if field.deprecated then check(value) end table.insert(removes, value) if additional then table.insert(removes, additional) end end end local ok, err = pcall(function () recurse(value) end) if not ok then if type(err) == "table" then err = err.msg end error(err, 3) end configset.remove(target, field, removes) end function api.checkValue(field, value, kind) if not field.allowed then return value end local canonical, result local lowerValue = value:lower() if field.aliases then canonical = field.aliases[lowerValue] end if not canonical then if type(field.allowed) == "function" then canonical = field.allowed(value, kind or "string") else canonical = field.allowed[lowerValue] end end if not canonical then return nil, "invalid value '" .. value .. "' for " .. field.name end if field.deprecated and field.deprecated[canonical] then local handler = field.deprecated[canonical] handler.add(canonical) if handler.message and api._deprecations ~= "off" then local key = field.name .. "_" .. value premake.warnOnce(key, "the %s value %s has been deprecated.\n %s", field.name, canonical, handler.message) if api._deprecations == "error" then return nil, "deprecation errors enabled" end end end return canonical end function api.reset() for containerClass in p.container.eachChildClass(p.global) do api.scope.global[containerClass.pluralName] = {} end end premake.field.kind("array", { store = function(field, current, value, processor) if type(value) ~= "table" then value = { value } end for i, item in ipairs(value) do value[i] = processor(field, nil, value[i]) end return value end, compare = function(field, a, b, processor) if a == nil or b == nil or #a ~= #b then return false end for i = 1, #a do if not processor(field, a[i], b[i]) then return false end end return true end }) premake.field.kind("boolean", { store = function(field, current, value, processor) local mapping = { ["false"] = false, ["no"] = false, ["off"] = false, ["on"] = true, ["true"] = true, ["yes"] = true, } if type(value) == "string" then value = mapping[value:lower()] if value == nil then error { msg="expected boolean; got " .. value } end return value end if type(value) == "boolean" then return value end if type(value) == "number" then return (value ~= 0) end return (value ~= nil) end, compare = function(field, a, b, processor) return (a == b) end }) premake.field.kind("directory", { paths = true, store = function(field, current, value, processor) return path.getabsolute(value) end, remove = function(field, current, value, processor) return path.getabsolute(value) end, compare = function(field, a, b, processor) return (a == b) end, translate = function(field, current, _, processor) if current:find("*") then return os.matchdirs(current) end return { current } end }) premake.field.kind("file", { paths = true, store = function(field, current, value, processor) return path.getabsolute(value) end, remove = function(field, current, value, processor) return path.getabsolute(value) end, compare = function(field, a, b, processor) return (a == b) end, translate = function(field, current, _, processor) if current:find("*") then return os.matchfiles(current) end return { current } end }) premake.field.kind("function", { store = function(field, current, value, processor) local t = type(value) if t ~= "function" then error { msg="expected function; got " .. t } end return value end, compare = function(field, a, b, processor) return (a == b) end }) premake.field.kind("integer", { store = function(field, current, value, processor) local t = type(value) if t ~= "number" then error { msg="expected number; got " .. t } end if math.floor(value) ~= value then error { msg="expected integer; got " .. tostring(value) } end return value end, compare = function(field, a, b, processor) return (a == b) end }) local function storeKeyed(field, current, value, processor) current = current or {} for k, v in pairs(value) do if processor then v = processor(field, current[k], v) end current[k] = v end return current end local function mergeKeyed(field, current, value, processor) value = value or {} for k, v in pairs(value) do current[k] = v end return current end premake.field.kind("keyed", { store = storeKeyed, merge = mergeKeyed, compare = function(field, a, b, processor) if a == nil or b == nil then return false end for k in pairs(a) do if not processor(field, a[k], b[k]) then return false end end return true end, translate = function(field, current, _, processor) if not processor then return { current } end for k, v in pairs(current) do current[k] = processor(field, v, nil)[1] end return { current } end }) local function storeListItem(current, item) if current[item] then table.remove(current, table.indexof(current, item)) end table.insert(current, item) current[item] = item end local function storeList(field, current, value, processor) if type(value) == "table" then if #value > 0 then for i = 1, #value do current = storeList(field, current, value[i], processor) end return current end if table.isempty(value) then return current end end current = current or {} if processor then value = processor(field, nil, value) end if type(value) == "table" then if #value > 0 then for i = 1, #value do storeListItem(current, value[i]) end elseif not table.isempty(value) then storeListItem(current, value) end elseif value then storeListItem(current, value) end return current end local function mergeList(field, current, value, processor) value = value or {} for i = 1, #value do storeListItem(current, value[i]) end return current end premake.field.kind("list", { store = storeList, remove = storeList, merge = mergeList, compare = function(field, a, b, processor) if a == nil or b == nil or #a ~= #b then return false end for i = 1, #a do if not processor(field, a[i], b[i]) then return false end end return true end, translate = function(field, current, _, processor) if not processor then return { current } end local ret = {} for _, value in ipairs(current) do for _, processed in ipairs(processor(field, value, nil)) do table.insert(ret, processed) end end return { ret } end }) premake.field.kind("mixed", { paths = true, store = function(field, current, value, processor) if type(value) == "string" and value:find('/', nil, true) then if string.sub(value, 1, 2) ~= "%{" then value = path.getabsolute(value) end end return value end, compare = function(field, a, b, processor) return (a == b) end }) premake.field.kind("number", { store = function(field, current, value, processor) local t = type(value) if t ~= "number" then error { msg="expected number; got " .. t } end return value end, compare = function(field, a, b, processor) return (a == b) end }) premake.field.kind("path", { paths = true, store = function(field, current, value, processor) if string.sub(value, 1, 2) == "%{" then return value end return path.getabsolute(value) end, compare = function(field, a, b, processor) return (a == b) end }) premake.field.kind("string", { store = function(field, current, value, processor) if type(value) == "table" then error { msg="expected string; got table" } end if value ~= nil then local err value, err = api.checkValue(field, value) if err then error { msg=err } end end return value end, compare = function(field, a, b, processor) return (a == b) end }) premake.field.kind("table", { store = function(field, current, value, processor) if type(value) ~= "table" then value = { value } end return value end, compare = function(field, a, b, processor) return true end }) function configuration(terms) if terms then if (type(terms) == "table" and #terms == 1 and terms[1] == "*") or (terms == "*") then terms = nil end configset.addblock(api.scope.current, {terms}, os.getcwd()) end return api.scope.current end function filter(terms) if terms then if (type(terms) == "table" and #terms == 1 and terms[1] == "*") or (terms == "*") then terms = nil end local ok, err = configset.addFilter(api.scope.current, {terms}, os.getcwd()) if not ok then error(err, 2) end end end function newaction(a) premake.action.add(a) end function newoption(opt) premake.option.add(opt) end local p = premake p.global = p.api.container("global") local global = p.global function global.new(name) return p.container.new(p.global, name) end function global.eachRule() local root = p.api.rootContainer() return p.container.eachChild(root, p.rule) end function global.eachWorkspace() local root = p.api.rootContainer() return p.container.eachChild(root, p.workspace) end p.alias(global, "eachWorkspace", "eachSolution") function global.getRule(key) local root = p.api.rootContainer() return root.rules[key] end function global.getRuleForFile(fname, rules) local ext = path.getextension(fname):lower() for rule in global.eachRule() do if not rules or table.contains(rules, rule.name) then if rule.fileextension == ext then return rule end end end end function global.getWorkspace(key) local root = p.api.rootContainer() return root.workspaces[key] end p.alias(global, "getWorkspace", "getSolution") local p = premake p.workspace = p.api.container("workspace", p.global) local workspace = p.workspace p.solution = workspace workspace.alias = "solution" p.alias(_G, "workspace", "solution") p.alias(_G, "externalworkspace", "externalsolution") function workspace.new(name) local wks = p.container.new(workspace, name) return wks end function workspace.eachconfig(self) self = p.oven.bakeWorkspace(self) local i = 0 return function() i = i + 1 if i > #self.configs then return nil else return self.configs[i] end end end function workspace.eachproject(self) local i = 0 return function () i = i + 1 if i <= #self.projects then return p.workspace.getproject(self, i) end end end function workspace.findproject(self, name) name = name:lower() for _, prj in ipairs(self.projects) do if name == prj.name:lower() then return prj end end return nil end function workspace.grouptree(self) if self.grouptree then return self.grouptree end local tr = p.tree.new() for prj in workspace.eachproject(self) do local prjpath = path.join(prj.group, prj.name) local node = p.tree.add(tr, prjpath) node.project = prj end p.tree.traverse(tr, { onnode = function(node) node.uuid = os.uuid(node.path) end }) self.grouptree = tr return tr end function workspace.getproject(self, idx) self = p.oven.bakeWorkspace(self) return self.projects[idx] end function workspace.hasProject(self, func) return p.container.hasChild(self, p.project, func) end function workspace.getrelative(self, filename) if type(filename) == "table" then local result = {} for i, name in ipairs(filename) do if name and #name > 0 then table.insert(result, workspace.getrelative(self, name)) end end return result else if filename then return path.getrelative(self.location, filename) end end end local p = premake p.group = p.api.container("group", p.workspace) local group = p.group group.placeholder = true function group.new(name) return p.container.new(group, name) end local p = premake p.project = p.api.container("project", p.workspace, { "config" }) local project = p.project local tree = p.tree external = externalproject function project.new(name) local prj = p.container.new(project, name) prj.uuid = os.uuid(name) if p.api.scope.group then prj.group = p.api.scope.group.name else prj.group = "" end return prj end function project.eachconfig(prj) local configs = prj._cfglist local count = #configs local seen = {} local i = 0 return function () i = i + 1 if i <= count then local cfg = project.getconfig(prj, configs[i][1], configs[i][2]) if not seen[cfg] then seen[cfg] = true return cfg else i = i + 1 end end end end function project.findClosestMatch(prj, buildcfg, platform) buildcfg = project.mapconfig(prj, buildcfg)[1] platform = project.mapconfig(prj, platform)[1] if not table.contains(prj.configurations, buildcfg) then buildcfg = prj.configurations[1] end if not table.contains(prj.platforms, platform) then platform = prj.platforms[1] end return project.getconfig(prj, buildcfg, platform) end function project.getconfig(prj, buildcfg, platform) if not buildcfg then return prj end local pairing = project.mapconfig(prj, buildcfg, platform) buildcfg = pairing[1] platform = pairing[2] local key = (buildcfg or "*") .. (platform or "") return prj.configs[key] end function project.getdependencies(prj, mode) if not prj.dependencies then prj.dependencies = {} end local m = mode or 'all' local result = prj.dependencies[m] if result then return result end local function add_to_project_list(cfg, depproj, result) local dep = p.workspace.findproject(cfg.workspace, depproj) if dep and not table.contains(result, dep) then table.insert(result, dep) end end local linkOnly = m == 'linkOnly' local depsOnly = m == 'dependOnly' result = {} for cfg in project.eachconfig(prj) do if not depsOnly then for _, link in ipairs(cfg.links) do if link ~= prj.name then add_to_project_list(cfg, link, result) end end end if not linkOnly then for _, depproj in ipairs(cfg.dependson) do add_to_project_list(cfg, depproj, result) end end end prj.dependencies[m] = result return result end function project.getfirstconfig(prj) local iter = project.eachconfig(prj) local first = iter() return first end function project.getrelative(prj, filename) if type(filename) == "table" then local result = {} for i, name in ipairs(filename) do result[i] = project.getrelative(prj, name) end return result else if filename then return path.getrelative(prj.location, filename) end end end function project.getsourcetree(prj, sorter) if prj._.sourcetree then return prj._.sourcetree end local tr = tree.new(prj.name) table.foreachi(prj._.files, function(fcfg) local flags if fcfg.vpath ~= fcfg.relpath then flags = { trim = false } end local parent = tree.add(tr, path.getdirectory(fcfg.vpath), flags) local node = tree.insert(parent, tree.new(path.getname(fcfg.vpath))) setmetatable(node, { __index = fcfg }) end) tree.trimroot(tr) tree.sort(tr, sorter) prj._.sourcetree = tr return tr end function project.getvpath(prj, abspath) local vpath = abspath local fname = path.getname(abspath) local max = abspath:len() - fname:len() for _, vpaths in ipairs(prj.vpaths) do for replacement, patterns in pairs(vpaths) do for _, pattern in ipairs(patterns) do local i = abspath:find(path.wildcards(pattern)) if i == 1 then i = pattern:find("*", 1, true) or (pattern:len() + 1) local leaf if i < max then leaf = abspath:sub(i) else leaf = fname end if leaf:startswith("/") then leaf = leaf:sub(2) end local stem = "" if replacement:len() > 0 then stem, stars = replacement:gsub("%*", "") if stars == 0 then leaf = path.getname(leaf) end else leaf = path.getname(leaf) end vpath = path.join(stem, leaf) return vpath end end end end return vpath end function project.hasConfig(prj, func) for cfg in project.eachconfig(prj) do if func(cfg) then return true end end end function project.hasfile(prj, filename) return (prj._.files[filename] ~= nil) end function project.isc(prj) return prj.language == premake.C end function project.iscpp(prj) return prj.language == premake.C or prj.language == premake.CPP end function project.isdotnet(prj) return prj.language == premake.CSHARP end function project.isnative(prj) return project.iscpp(prj) end function project.mapconfig(prj, buildcfg, platform) local pairing = { buildcfg, platform } local testpattern = function(pattern, pairing, i) local j = 1 while i <= #pairing and j <= #pattern do if pairing[i] ~= pattern[j] then return false end i = i + 1 j = j + 1 end return true end local maps = prj.configmap or {} for mi = 1, #maps do for pattern, replacements in pairs(maps[mi]) do if type(pattern) ~= "table" then pattern = { pattern } end for i = 1, #pairing do if testpattern(pattern, pairing, i) then if #pattern == 1 and #replacements == 1 then pairing[i] = replacements[1] else pairing = { replacements[1], replacements[2] } end end end end end return pairing end local p = premake p.config = {} local project = p.project local config = p.config function config.buildtargetinfo(cfg, kind, field) local basedir = cfg.project.location local targetdir if cfg.platform then targetdir = path.join(basedir, 'bin', cfg.platform, cfg.buildcfg) else targetdir = path.join(basedir, 'bin', cfg.buildcfg) end local directory = cfg[field.."dir"] or cfg.targetdir or targetdir local basename = cfg[field.."name"] or cfg.targetname or cfg.project.name local prefix = cfg[field.."prefix"] or cfg.targetprefix or "" local suffix = cfg[field.."suffix"] or cfg.targetsuffix or "" local extension = cfg[field.."extension"] or cfg.targetextension or "" local bundlename = "" local bundlepath = "" if cfg.system == premake.MACOSX and kind == premake.WINDOWEDAPP then bundlename = basename .. ".app" bundlepath = path.join(bundlename, "Contents/MacOS") end local info = {} info.directory = directory info.basename = basename .. suffix info.name = prefix .. info.basename .. extension info.extension = extension info.abspath = path.join(directory, info.name) info.fullpath = info.abspath info.bundlename = bundlename info.bundlepath = path.join(directory, bundlepath) info.prefix = prefix info.suffix = suffix return info end function config.canLink(cfg, target, linkage) if type(target) ~= "string" then if target.kind ~= "SharedLib" and target.kind ~= "StaticLib" then return false end local cfgManaged = project.isdotnet(cfg.project) or (cfg.clr ~= p.OFF) local tgtManaged = project.isdotnet(target.project) or (target.clr ~= p.OFF) return (cfgManaged == tgtManaged) end if project.isdotnet(cfg.project) then return true end local isManaged = (path.getextension(target) == ".dll") if isManaged and cfg.clr == p.OFF then return false end return (isManaged) == (linkage == "managed") end function config.canLinkIncremental(cfg) if cfg.kind == "StaticLib" or config.isOptimizedBuild(cfg) or cfg.flags.NoIncrementalLink then return false end return true end function config.findfile(cfg, ext) for _, fname in ipairs(cfg.files) do if fname:endswith(ext) then return project.getrelative(cfg.project, fname) end end end function config.getlinkinfo(cfg) local kind = cfg.kind if project.iscpp(cfg.project) then if cfg.system == premake.WINDOWS and kind == premake.SHAREDLIB and not cfg.flags.NoImportLib then kind = premake.STATICLIB end end return config.buildtargetinfo(cfg, kind, "implib") end function config.getlinks(cfg, kind, part, linkage) local result = {} if part == "directory" then table.foreachi(cfg.libdirs, function(dir) table.insert(result, project.getrelative(cfg.project, dir)) end) end for i = 1, #cfg.links do local link = cfg.links[i] local item local prj = p.workspace.findproject(cfg.workspace, link) if prj and kind ~= "system" then local prjcfg = project.getconfig(prj, cfg.buildcfg, cfg.platform) if prjcfg and (kind == "dependencies" or config.canLink(cfg, prjcfg)) then if part == "object" then item = prjcfg else item = project.getrelative(cfg.project, prjcfg.linktarget.fullpath) end end elseif not prj and (kind == "system" or kind == "all") then if config.canLink(cfg, link, linkage) then item = link if item:find("/", nil, true) then item = project.getrelative(cfg.project, item) end end end if item and item ~= cfg then if part == "directory" then item = path.getdirectory(item) if item == "." then item = nil end elseif part == "name" then item = path.getname(item) elseif part == "basename" then item = path.getbasename(item) elseif type(part) == "function" then part(link, item) end end if item and not table.contains(result, item) then table.insert(result, item) end end return result end function config.getruntime(cfg) local linkage = iif(cfg.flags.StaticRuntime, "Static", "Shared") if not cfg.runtime then return linkage .. iif(config.isDebugBuild(cfg), "Debug", "Release") else return linkage .. cfg.runtime end end function config.gettargetinfo(cfg) return config.buildtargetinfo(cfg, cfg.kind, "target") end function config.hasFile(self, testfn) local files = self.files for i = 1, #files do if testfn(files[i]) then return true end end return false end function config.isCopyLocal(cfg, linkname, default) if cfg.flags.NoCopyLocal then return false end if #cfg.copylocal > 0 then return table.contains(cfg.copylocal, linkname) end return default end function config.isDebugBuild(cfg) return cfg.flags.Symbols and not config.isOptimizedBuild(cfg) end function config.isOptimizedBuild(cfg) return cfg.optimize ~= nil and cfg.optimize ~= p.OFF and cfg.optimize ~= "Debug" end function config.linksToProject(cfg, prjName) prjName = prjName:lower() local n = #cfg.links for i = 1,n do if cfg.links[i]:lower() == prjName then return true end end end function config.mapFlags(cfg, mappings) local flags = {} local function add(replacement) if type(replacement) == "function" then replacement = replacement(cfg) end table.insertflat(flags, replacement) end for field in p.field.eachOrdered() do local map = mappings[field.name] if map then local values = cfg[field.name] if type(values) ~= "table" then values = { values } end local foundValue = false table.foreachi(values, function(value) local replacement = map[value] if replacement ~= nil then foundValue = true add(replacement) end end) if not foundValue then add(map._) end for key, replacement in pairs(map) do if #key > 1 and key:startswith("_") then key = key:sub(2) if values[key] == nil then add(replacement) end end end end end return flags end function config.normalize(cfg) if cfg and cfg.config ~= nil then return cfg.config, cfg else return cfg, nil end end function config.toolset(cfg) if cfg.toolset then return p.tools.canonical(cfg.toolset) end end premake.fileconfig = {} local p = premake local fileconfig = p.fileconfig local context = p.context local project = p.project fileconfig.fcfg_mt = {} fileconfig.fsub_mt = {} function fileconfig.new(fname, prj) local environ = { } local fcfg = context.new(prj, environ) context.copyFilters(fcfg, prj) context.addFilter(fcfg, "files", fname:lower()) for key, value in pairs(prj.environ) do environ[key] = value end environ.file = fcfg context.compile(fcfg) fcfg.project = prj fcfg.configs = {} fcfg.abspath = fname context.basedir(fcfg, prj.location) setmetatable(fcfg, fileconfig.fcfg_mt) local vpath = project.getvpath(prj, fname) if vpath ~= fcfg.abspath then fcfg.vpath = vpath end return fcfg end function fileconfig.addconfig(fcfg, cfg) local prj = cfg.project local environ = {} local fsub = context.new(prj, environ) context.copyFilters(fsub, cfg) context.mergeFilters(fsub, fcfg) fcfg.configs[cfg] = fsub for key, value in pairs(cfg.environ) do environ[key] = value end for key, value in pairs(fcfg.environ) do environ[key] = value end context.compile(fsub) fsub.abspath = fcfg.abspath fsub.vpath = fcfg.vpath fsub.config = cfg fsub.project = prj context.basedir(fsub, prj.location) setmetatable(fsub, fileconfig.fsub_mt) end function fileconfig.getconfig(fcfg, cfg) return fcfg.configs[cfg] end function fileconfig.hasCustomBuildRule(fcfg) return fcfg and (#fcfg.buildcommands > 0) and (#fcfg.buildoutputs > 0) end function fileconfig.hasFileSettings(fcfg) for key, field in pairs(premake.fields) do if field.scopes[1] == "config" then local value = fcfg[field.name] if value then if type(value) == "table" then if #value > 0 then return true end else return true end end end end return false end local fcfg_mt = fileconfig.fcfg_mt fcfg_mt.__index = function(fcfg, key) if type(fcfg_mt[key]) == "function" then return fcfg_mt[key](fcfg) end return context.__mt.__index(fcfg, key) end fileconfig.fsub_mt.__index = function(fsub, key) if type(fcfg_mt[key]) == "function" then return fcfg_mt[key](fsub) end return context.__mt.__index(fsub, key) end function fcfg_mt.basename(fcfg) return path.getbasename(fcfg.abspath) end function fcfg_mt.directory(fcfg) return path.getdirectory(fcfg.abspath) end function fcfg_mt.name(fcfg) return path.getname(fcfg.abspath) end function fcfg_mt.objname(fcfg) if fcfg.sequence ~= nil and fcfg.sequence > 0 then return fcfg.basename .. fcfg.sequence else return fcfg.basename end end function fcfg_mt.path(fcfg) return fcfg.relpath end function fcfg_mt.relpath(fcfg) return project.getrelative(fcfg.project, fcfg.abspath) end function fcfg_mt.vpath(fcfg) return fcfg.relpath end local p = premake p.rule = p.api.container("rule", p.global) local rule = p.rule function rule.new(name) local self = p.container.new(rule, name) _G[name .. "Vars"] = function(vars) rule.setVars(self, vars) end local lowerName = name:gsub("^%u+", string.lower) _G[lowerName .. "Vars"] = _G[name .. "Vars"] return self end function rule.eachProperty(self) local props = self.propertydefinition local i = 0 return function () i = i + 1 if i <= #props then return props[i] end end end function rule.getProperty(self, name) local props = self.propertydefinition for i = 1, #props do local prop = props[i] if prop.name == name then return prop end end end function rule.getPropertyField(self, prop) if prop._field then return prop._field end local kind = prop.kind or "string" if kind == "list" then kind = "list:string" end local fld = p.field.new { name = "_rule_" .. self.name .. "_" .. prop.name, scope = "config", kind = kind, tokens = true, } prop._field = fld return fld end function rule.getPropertyString(self, prop, value) if type(value) == "table" then local sep = prop.separator or " " return table.concat(value, sep) end if prop.values then local i = table.indexof(prop.values, value) return tostring(i) end value = tostring(value) if #value > 0 then return value else return nil end end function rule.setVars(self, vars) for key, value in pairs(vars) do local prop = rule.getProperty(self, key) if not prop then error (string.format("rule '%s' does not have property '%s'", self.name, key)) end local fld = rule.getPropertyField(self, prop) p.api.storeField(fld, value) end end local p = premake p.oven = {} local oven = p.oven local context = p.context p.oven.bubbledFields = { configmap = true, vpaths = true } function oven.bake() p.container.bakeChildren(p.api.rootContainer()) end function oven.bakeWorkspace(wks) return p.container.bake(wks) end p.alias(oven, "bakeWorkspace", "bakeSolution") function p.workspace.bake(self) context.addFilter(self, "_ACTION", _ACTION) context.addFilter(self, "action", _ACTION) self.system = self.system or p.action.current().os or os.get() context.addFilter(self, "system", self.system) local options = {} for key, value in pairs(_OPTIONS) do local term = key if value ~= "" then term = term .. "=" .. value end table.insert(options, term) end context.addFilter(self, "_OPTIONS", options) context.addFilter(self, "options", options) self.environ = { wks = self, sln = self, } context.compile(self) self.location = self.location or self.basedir context.basedir(self, self.location) p.container.bakeChildren(self) oven.bakeObjDirs(self) self.configs = oven.bakeConfigs(self) end function p.project.bake(self) verbosef(' Baking %s...', self.name) self.solution = self.workspace local wks = self.workspace context.copyFilters(self, wks) self.system = self.system or p.action.current().os or os.get() context.addFilter(self, "system", self.system) context.addFilter(self, "architecture", self.architecture) context.addFilter(self, "kind", self.kind) self.project = self self.environ = { wks = wks, sln = wks, prj = self, } context.compile(self) p.container.bakeChildren(self) self.location = self.location or wks.location or self.basedir context.basedir(self, self.location) local cfgs = table.fold(self.configurations or {}, self.platforms or {}) oven.bubbleFields(self, self, cfgs) self._cfglist = oven.bakeConfigList(self, cfgs) self.system = nil self.configs = {} for _, pairing in ipairs(self._cfglist) do local buildcfg = pairing[1] local platform = pairing[2] local cfg = oven.bakeConfig(wks, self, buildcfg, platform) if premake.action.supportsconfig(premake.action.current(), cfg) then self.configs[(buildcfg or "*") .. (platform or "")] = cfg end end self._ = {} self._.files = oven.bakeFiles(self) if p.project.iscpp(self) then oven.assignObjectSequences(self) end end function p.rule.bake(r) table.sort(r.propertydefinition, function (a, b) return a.name < b.name end) end function oven.bakeObjDirs(wks) local function getobjdirs(cfg) local objdir = cfg.objdir or "obj" local i = objdir:find("!", 1, true) if i then cfg.objdir = objdir:sub(1, i - 1) .. objdir:sub(i + 1) return nil end local dirs = {} local dir = path.getabsolute(path.join(cfg.project.location, objdir)) table.insert(dirs, dir) if cfg.platform then dir = path.join(dir, cfg.platform) table.insert(dirs, dir) end dir = path.join(dir, cfg.buildcfg) table.insert(dirs, dir) dir = path.join(dir, cfg.project.name) table.insert(dirs, dir) return dirs end local counts = {} local configs = {} for prj in p.workspace.eachproject(wks) do for cfg in p.project.eachconfig(prj) do local dirs = getobjdirs(cfg) if dirs then configs[cfg] = dirs for _, dir in ipairs(dirs or {}) do counts[dir] = (counts[dir] or 0) + 1 end end end end for cfg, dirs in pairs(configs) do for _, dir in ipairs(dirs) do if counts[dir] == 1 then cfg.objdir = dir break end end end end function oven.bakeConfigs(wks) local buildcfgs = wks.configurations or {} local platforms = wks.platforms or {} local configs = {} local pairings = table.fold(buildcfgs, platforms) for _, pairing in ipairs(pairings) do local cfg = oven.bakeConfig(wks, nil, pairing[1], pairing[2]) if premake.action.supportsconfig(premake.action.current(), cfg) then table.insert(configs, cfg) end end return configs end function oven.bubbleFields(ctx, cset, cfgs) local configurations = {} local platforms = {} for _, cfg in ipairs(cfgs) do if cfg[1] then table.insert(configurations, cfg[1]:lower()) end if cfg[2] then table.insert(platforms, cfg[2]:lower()) end end local terms = table.deepcopy(ctx.terms) terms.configurations = configurations terms.platforms = platforms for key in pairs(oven.bubbledFields) do local field = p.field.get(key) if not field then ctx[key] = rawget(ctx, key) else local value = p.configset.fetch(cset, field, terms, ctx) if value then ctx[key] = value end end end end function oven.bakeConfigList(ctx, cfgs) for i, cfg in ipairs(cfgs) do cfgs[i] = p.project.mapconfig(ctx, cfg[1], cfg[2]) end local buildcfgs = {} local platforms = {} for _, pairing in ipairs(cfgs) do local buildcfg = pairing[1] local platform = pairing[2] if not table.contains(buildcfgs, buildcfg) then table.insert(buildcfgs, buildcfg) end if platform and not table.contains(platforms, platform) then table.insert(platforms, platform) end end return table.fold(buildcfgs, platforms) end function oven.bakeConfig(wks, prj, buildcfg, platform, extraFilters) local system = p.action.current().os or os.get() local architecture = nil if platform then system = p.api.checkValue(p.fields.system, platform) or system architecture = p.api.checkValue(p.fields.architecture, platform) or architecture end local environ = { wks = wks, sln = wks, prj = prj, } local ctx = context.new(prj or wks, environ) ctx.project = prj ctx.workspace = wks ctx.solution = wks ctx.buildcfg = buildcfg ctx.platform = platform ctx.action = _ACTION environ.cfg = ctx context.copyFilters(ctx, wks) context.addFilter(ctx, "configurations", buildcfg) context.addFilter(ctx, "platforms", platform) if prj then context.addFilter(ctx, "language", prj.language) end ctx.system = ctx.system or system context.addFilter(ctx, "system", ctx.system) ctx.architecture = ctx.architecture or architecture context.addFilter(ctx, "architecture", ctx.architecture) context.addFilter(ctx, "kind", ctx.kind) if extraFilters then for k, v in pairs(extraFilters) do context.addFilter(ctx, k, v) end end context.compile(ctx) ctx.location = ctx.location or prj and prj.location context.basedir(ctx, ctx.location) oven.finishConfig(ctx) return ctx end function oven.bakeFiles(prj) local files = {} for cfg in p.project.eachconfig(prj) do table.foreachi(cfg.files, function(fname) if not files[fname] then local fcfg = p.fileconfig.new(fname, prj) files[fname] = fcfg table.insert(files, fcfg) end p.fileconfig.addconfig(files[fname], cfg) end) end table.sort(files, function(a,b) return a.vpath < b.vpath end) return files end function oven.assignObjectSequences(prj) local bases = {} table.foreachi(prj._.files, function(file) if not path.iscppfile(file.abspath) then return end if not bases[file.basename] then bases[file.basename] = {} end local sequences = bases[file.basename] for cfg in p.project.eachconfig(prj) do local fcfg = p.fileconfig.getconfig(file, cfg) if fcfg ~= nil and not fcfg.flags.ExcludeFromBuild then fcfg.sequence = sequences[cfg] or 0 sequences[cfg] = fcfg.sequence + 1 end end file.sequence = sequences[prj] or 0 sequences[prj] = file.sequence + 1 end) end function oven.finishConfig(cfg) cfg.longname = table.concat({ cfg.buildcfg, cfg.platform }, "|") cfg.shortname = table.concat({ cfg.buildcfg, cfg.platform }, " ") cfg.shortname = cfg.shortname:gsub(" ", "_"):lower() cfg.name = cfg.longname if cfg.project and cfg.kind then cfg.buildtarget = p.config.gettargetinfo(cfg) cfg.buildtarget.relpath = p.project.getrelative(cfg.project, cfg.buildtarget.abspath) cfg.linktarget = p.config.getlinkinfo(cfg) cfg.linktarget.relpath = p.project.getrelative(cfg.project, cfg.linktarget.abspath) end end premake.validation = {} local m = premake.validation local p = premake m.elements = {} m.elements.global = function(glb) return { } end function p.global.validate(self) p.callArray(m.elements.global, self) p.container.validateChildren(self) end m.elements.workspace = function(wks) return { m.workspaceHasConfigs, m.uniqueProjectIds, } end function p.workspace.validate(self) p.callArray(m.elements.workspace, self) p.container.validateChildren(self) end m.elements.project = function(prj) return { m.projectHasLanguage, m.actionSupportsLanguage, m.actionSupportsKind, m.projectRulesExist, m.projectValuesInScope, } end function p.project.validate(self) p.callArray(m.elements.project, self) for cfg in p.project.eachconfig(self) do p.config.validate(cfg) end end m.elements.config = function(cfg) return { m.configHasKind, m.configSupportsKind, m.configValuesInScope, } end function p.config.validate(self) p.callArray(m.elements.config, self) end m.elements.rule = function(rule) return { } end function p.rule.validate(self) p.callArray(m.elements.rule, self) end function p.config.validateScopes(self, container, expected) for f in p.field.each() do local scope for i = 1, #f.scopes do if f.scopes[i] == "config" or p.container.classIsA(container.class, f.scopes[i]) then scope = f.scopes[i] break end end local okay = (not scope or scope == "config") okay = okay or scope == expected okay = okay or p.oven.bubbledFields[f.name] okay = okay or p.field.compare(f, self[scope][f.name], self[f.name]) if not okay then local key = "validate." .. f.name p.warnOnce(key, "'%s' on %s '%s' differs from %s '%s'; may be set out of scope", f.name, expected, self.name, scope, self[scope].name) end end end function m.actionSupportsKind(prj) if not p.action.supports(prj.kind) then p.warn("unsupported kind '%s' used for project '%s'", prj.kind, prj.name) end end function m.actionSupportsLanguage(prj) if not p.action.supports(prj.language) then p.warn("unsupported language '%s' used for project '%s'", prj.language, prj.name) end end function m.configHasKind(cfg) if not cfg.kind then p.error("project '%s' needs a kind in configuration '%s'", cfg.project.name, cfg.name) end end function m.configSupportsKind(cfg) if (cfg.kind == p.MAKEFILE or cfg.kind == p.NONE) and not p.project.iscpp(cfg.project) then p.error("project '%s' uses %s kind in configuration '%s'; language must be C++", cfg.project.name, cfg.kind, cfg.name) end end function m.configValuesInScope(cfg) p.config.validateScopes(cfg, cfg.project, "config") end function m.projectHasLanguage(prj) if not prj.language then p.error("project '%s' does not have a language", prj.name) end end function m.projectRulesExist(prj) for i = 1, #prj.rules do local rule = prj.rules[i] if not p.global.getRule(rule) then p.error("project '%s' uses missing rule '%s'", prj.name, rule) end end end function m.projectValuesInScope(prj) p.config.validateScopes(prj, prj, "project") end function m.uniqueProjectIds(wks) local uuids = {} for prj in p.workspace.eachproject(wks) do if uuids[prj.uuid] then p.error("projects '%s' and '%s' have the same UUID", uuids[prj.uuid], prj.name) end uuids[prj.uuid] = prj.name end end function m.workspaceHasConfigs(wks) if not wks.configurations or #wks.configurations == 0 then p.error("workspace '%s' does not contain any configurations", wks.name) end end local p = premake local _captured local _esc = function(v) return v end local _eol = "\n" local _indentString = "\t" local _indentLevel = 0 global("root") function premake.capture(fn) local old = _captured _captured = buffered.new() fn() local captured = premake.captured() buffered.close(_captured) _captured = old return captured end function premake.captured() if _captured then return buffered.tostring(_captured) else return "" end end function premake.eol(s) _eol = s or _eol return _eol end function premake.esc(value) if type(value) == "table" then local result = {} local n = #value for i = 1, n do table.insert(result, premake.esc(value[i])) end return result end return _esc(value or "") end function premake.escaper(func) _esc = func if not _esc then _esc = function (value) return value end end end function premake.generate(obj, ext, callback) local output = premake.capture(function () _indentLevel = 0 callback(obj) _indentLevel = 0 end) local fn = premake.filename(obj, ext) local dir = path.getdirectory(fn) ok, err = os.mkdir(dir) if not ok then error(err, 0) end local f, err = os.writefile_ifnotequal(output, fn); if (f < 0) then error(err, 0) elseif (f > 0) then printf("Generated %s...", path.getrelative(os.getcwd(), fn)) end end function premake.filename(obj, ext) local fname = obj.location or obj.basedir if ext and not ext:startswith(".") then fname = path.join(fname, ext) else fname = path.join(fname, obj.filename) if ext then fname = fname .. ext end end return path.getabsolute(fname) end function premake.indent(s, i) _indentString = s or "\t" _indentLevel = i or 0 end function premake.out(s) if not _captured then io.write(s) else buffered.write(_captured, s) end end function premake.outln(s) premake.out(s) premake.out(_eol or "\n") end function premake.pop(i, ...) if i == nil or type(i) == "number" then _indentLevel = _indentLevel - (i or 1) else _indentLevel = _indentLevel - 1 premake.w(i, ...) end end function premake.push(i, ...) if i == nil or type(i) == "number" then _indentLevel = _indentLevel + (i or 1) else premake.w(i, ...) _indentLevel = _indentLevel + 1 end end function premake.quoted(value) local q = value:find(" ", 1, true) if not q then q = value:find("$%(.-%)", 1) end if q then value = '"' .. value .. '"' end return value end function p.utf8() p.out('\239\187\191') end function premake.w(...) if select("#", ...) > 0 then premake.outln(string.rep(_indentString or "\t", _indentLevel) .. string.format(...)) else premake.outln(''); end end function premake.x(msg, ...) local arg = {...} for i = 1, #arg do arg[i] = premake.esc(arg[i]) end premake.w(msg, unpack(arg)) end function premake.xmlUtf8(upper) local encoding = iif(upper, "UTF-8", "utf-8") premake.w('', encoding) end function _p(i, ...) if type(i) == "number" then _indentLevel = i premake.w(...) else _indentLevel = 0 premake.w(i, ...) end end function _x(i, ...) local arg = {...} for i = 2, #arg do arg[i] = premake.esc(arg[i]) end _p(i, unpack(arg)) end function premake.showhelp() printf("Premake %s, a build script generator", _PREMAKE_VERSION) printf(_PREMAKE_COPYRIGHT) printf("%s %s", _VERSION, _COPYRIGHT) printf("") printf("Usage: premake5 [options] action [arguments]") printf("") local categories = {} for option in premake.option.each() do local cat = "OPTIONS - General" if option.category then cat = "OPTIONS - " .. option.category; end if categories[cat] then table.insert(categories[cat], option) else categories[cat] = {option} end end for k, options in pairs(categories) do printf(k) printf("") for _, option in ipairs(options) do local trigger = option.trigger local description = option.description if (option.value) then trigger = trigger .. "=" .. option.value end if (option.allowed) then description = description .. "; one of:" end printf(" --%-15s %s", trigger, description) if (option.allowed) then for _, value in ipairs(option.allowed) do printf(" %-14s %s", value[1], value[2]) end end printf("") end printf("") end printf("ACTIONS") printf("") for action in premake.action.each() do printf(" %-17s %s", action.trigger, action.description) end printf("") printf("For additional information, see http://industriousone.com/premake") end premake.tools.dotnet = {} local dotnet = premake.tools.dotnet local project = premake.project local config = premake.config function dotnet.fileinfo(fcfg) local info = {} local fname = fcfg.abspath local ext = path.getextension(fname):lower() if fcfg.buildaction == "Compile" or ext == ".cs" then info.action = "Compile" elseif fcfg.buildaction == "Embed" or ext == ".resx" then info.action = "EmbeddedResource" elseif fcfg.buildaction == "Copy" or ext == ".asax" or ext == ".aspx" then info.action = "Content" elseif fcfg.buildaction == "Resource" then info.action = "Resource" elseif ext == ".xaml" then if fcfg.buildaction == "Application" or path.getbasename(fname) == "App" then info.action = "ApplicationDefinition" else info.action = "Page" end else info.action = "None" end if info.action == "Compile" and fname:endswith(".cs") then if fname:endswith(".Designer.cs") then local basename = fname:sub(1, -13) local testname = basename .. ".resx" if project.hasfile(fcfg.project, testname) then info.AutoGen = "True" info.DependentUpon = testname end testname = basename .. ".settings" if project.hasfile(fcfg.project, testname) then info.AutoGen = "True" info.DependentUpon = testname info.DesignTimeSharedInput = "True" end testname = basename .. ".cs" if project.hasfile(fcfg.project, testname) then info.AutoGen = nil info.SubType = "Dependency" info.DependentUpon = testname end elseif fname:endswith(".xaml.cs") then info.SubType = "Code" info.DependentUpon = fname:sub(1, -4) else local basename = fname:sub(1, -4) testname = basename .. ".Designer.cs" if project.hasfile(fcfg.project, testname) then info.SubType = "Form" end end if fcfg.buildaction == "Component" or fcfg.buildaction == "Form" or fcfg.buildaction == "UserControl" then info.SubType = fcfg.buildaction end if fcfg.flags and fcfg.flags.Component then info.SubType = "Component" end end if info.action == "Content" then info.CopyToOutputDirectory = "PreserveNewest" end if info.action == "EmbeddedResource" and fname:endswith(".resx") then local basename = fname:sub(1, -6) local testname = basename .. ".cs" if project.hasfile(fcfg.project, testname) then info.DependentUpon = testname if project.hasfile(fcfg.project, basename .. ".Designer.cs") then info.SubType = "DesignerType" end else testname = basename .. ".Designer.cs" if project.hasfile(fcfg.project, testname) then info.SubType = "Designer" info.Generator = "ResXFileCodeGenerator" info.LastGenOutput = path.getname(testname) end end end if info.action == "None" and fname:endswith(".settings") then local testname = fname:sub(1, -10) .. ".Designer.cs" if project.hasfile(fcfg.project, testname) then info.Generator = "SettingsSingleFileGenerator" info.LastGenOutput = path.getname(testname) end end if fname:endswith(".xaml") then local testname = fname .. ".cs" if project.hasfile(fcfg.project, testname) then info.SubType = "Designer" info.Generator = "MSBuild:Compile" end end if info.DependentUpon then info.DependentUpon = path.getname(info.DependentUpon) end return info end function dotnet.gettoolname(cfg, tool) local compilers = { msnet = "csc", mono = "mcs", pnet = "cscc", } if tool == "csc" then local toolset = _OPTIONS.dotnet or iif(os.is(premake.WINDOWS), "msnet", "mono") return compilers[toolset] else return "resgen" end end dotnet.flags = { clr = { Unsafe = "/unsafe", }, flags = { FatalWarning = "/warnaserror", Symbols = "/debug", }, optimize = { On = "/optimize", Size = "/optimize", Speed = "/optimize", }, } function dotnet.getflags(cfg) local flags = config.mapFlags(cfg, dotnet.flags) table.insert(flags, '/noconfig') if cfg.project.icon then local fn = project.getrelative(cfg.project, cfg.project.icon) table.insert(flags, string.format('/win32icon:"%s"', fn)) end if #cfg.defines > 0 then table.insert(flags, table.implode(cfg.defines, "/d:", "", " ")) end return table.join(flags, cfg.buildoptions) end function dotnet.getkind(cfg) if (cfg.kind == "ConsoleApp") then return "Exe" elseif (cfg.kind == "WindowedApp") then return "WinExe" elseif (cfg.kind == "SharedLib") then return "Library" end end function dotnet.getmakesettings(cfg) return nil end local p = premake p.tools.gcc = {} local gcc = p.tools.gcc local project = p.project local config = p.config gcc.cppflags = { system = { haiku = "-MMD", wii = { "-MMD", "-MP", "-I$(LIBOGC_INC)", "$(MACHDEP)" }, _ = { "-MMD", "-MP" } } } function gcc.getcppflags(cfg) local flags = config.mapFlags(cfg, gcc.cppflags) return flags end gcc.cflags = { architecture = { x86 = "-m32", x86_64 = "-m64", }, flags = { FatalCompileWarnings = "-Werror", LinkTimeOptimization = "-flto", NoFramePointer = "-fomit-frame-pointer", ShadowedVariables = "-Wshadow", Symbols = "-g", UndefinedIdentifiers = "-Wundef", }, floatingpoint = { Fast = "-ffast-math", Strict = "-ffloat-store", }, strictaliasing = { Off = "-fno-strict-aliasing", Level1 = { "-fstrict-aliasing", "-Wstrict-aliasing=1" }, Level2 = { "-fstrict-aliasing", "-Wstrict-aliasing=2" }, Level3 = { "-fstrict-aliasing", "-Wstrict-aliasing=3" }, }, optimize = { Off = "-O0", On = "-O2", Debug = "-Og", Full = "-O3", Size = "-Os", Speed = "-O3", }, pic = { On = "-fPIC", }, vectorextensions = { AVX = "-mavx", AVX2 = "-mavx2", SSE = "-msse", SSE2 = "-msse2", SSE3 = "-msse3", SSSE3 = "-mssse3", ["SSE4.1"] = "-msse4.1", }, warnings = { Extra = "-Wall -Wextra", Off = "-w", } } function gcc.getcflags(cfg) local flags = config.mapFlags(cfg, gcc.cflags) flags = table.join(flags, gcc.getwarnings(cfg)) return flags end function gcc.getwarnings(cfg) local result = {} for _, enable in ipairs(cfg.enablewarnings) do table.insert(result, '-W' .. enable) end for _, disable in ipairs(cfg.disablewarnings) do table.insert(result, '-Wno-' .. disable) end for _, fatal in ipairs(cfg.fatalwarnings) do table.insert(result, '-Werror=' .. fatal) end return result end gcc.cxxflags = { exceptionhandling = { Off = "-fno-exceptions" }, flags = { NoBufferSecurityCheck = "-fno-stack-protector", ["C++11"] = "-std=c++11", ["C++14"] = "-std=c++14", }, rtti = { Off = "-fno-rtti" } } function gcc.getcxxflags(cfg) local flags = config.mapFlags(cfg, gcc.cxxflags) return flags end function gcc.getdefines(defines) local result = {} for _, define in ipairs(defines) do table.insert(result, '-D' .. define) end return result end function gcc.getundefines(undefines) local result = {} for _, undefine in ipairs(undefines) do table.insert(result, '-U' .. undefine) end return result end function gcc.getforceincludes(cfg) local result = {} table.foreachi(cfg.forceincludes, function(value) local fn = project.getrelative(cfg.project, value) table.insert(result, string.format('-include %s', premake.quoted(fn))) end) return result end function gcc.getincludedirs(cfg, dirs, sysdirs) local result = {} for _, dir in ipairs(dirs) do dir = project.getrelative(cfg.project, dir) table.insert(result, '-I' .. premake.quoted(dir)) end for _, dir in ipairs(sysdirs or {}) do dir = project.getrelative(cfg.project, dir) table.insert(result, '-isystem ' .. premake.quoted(dir)) end return result end gcc.ldflags = { architecture = { x86 = "-m32", x86_64 = "-m64", }, flags = { LinkTimeOptimization = "-flto", _Symbols = function(cfg) return iif(cfg.system == premake.MACOSX, "-Wl,-x", "-s") end, }, kind = { SharedLib = function(cfg) local r = { iif(cfg.system == premake.MACOSX, "-dynamiclib", "-shared") } if cfg.system == "windows" and not cfg.flags.NoImportLib then table.insert(r, '-Wl,--out-implib="' .. cfg.linktarget.relpath .. '"') end return r end, WindowedApp = function(cfg) if cfg.system == premake.WINDOWS then return "-mwindows" end end, }, system = { wii = "$(MACHDEP)", } } function gcc.getldflags(cfg) local flags = config.mapFlags(cfg, gcc.ldflags) return flags end gcc.libraryDirectories = { architecture = { x86 = "-L/usr/lib32", x86_64 = "-L/usr/lib64", }, system = { wii = "-L$(LIBOGC_LIB)", } } function gcc.getLibraryDirectories(cfg) local flags = config.mapFlags(cfg, gcc.libraryDirectories) for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do table.insert(flags, '-L' .. premake.quoted(dir)) end if cfg.flags.RelativeLinks then for _, dir in ipairs(config.getlinks(cfg, "siblings", "directory")) do local libFlag = "-L" .. premake.project.getrelative(cfg.project, dir) if not table.contains(flags, libFlag) then table.insert(flags, libFlag) end end end for _, dir in ipairs(cfg.syslibdirs) do table.insert(flags, '-L' .. premake.quoted(dir)) end return flags end function gcc.getlinks(cfg, systemonly) local result = {} if not systemonly then if cfg.flags.RelativeLinks then local libFiles = config.getlinks(cfg, "siblings", "basename") for _, link in ipairs(libFiles) do if string.find(link, "lib") == 1 then link = link:sub(4) end table.insert(result, "-l" .. link) end else result = config.getlinks(cfg, "siblings", "fullpath") end end local links = config.getlinks(cfg, "system", "fullpath") for _, link in ipairs(links) do if path.isframework(link) then table.insert(result, "-framework " .. path.getbasename(link)) elseif path.isobjectfile(link) then table.insert(result, link) else table.insert(result, "-l" .. path.getname(link)) end end return result end gcc.makesettings = { system = { wii = [[ ifeq ($(strip $(DEVKITPPC)),) $(error "DEVKITPPC environment variable is not set")' endif include $(DEVKITPPC)/wii_rules']] } } function gcc.getmakesettings(cfg) local settings = config.mapFlags(cfg, gcc.makesettings) return table.concat(settings) end gcc.tools = { cc = "gcc", cxx = "g++", ar = "ar", rc = "windres" } function gcc.gettoolname(cfg, tool) if (cfg.gccprefix and gcc.tools[tool]) or tool == "rc" then return (cfg.gccprefix or "") .. gcc.tools[tool] end return nil end local p = premake p.tools.msc = {} local msc = p.tools.msc local project = p.project local config = p.config function msc.getcppflags(cfg) return {} end msc.cflags = { clr = { On = "/clr", Unsafe = "/clr", Pure = "/clr:pure", Safe = "/clr:safe", }, flags = { FatalCompileWarnings = "/WX", MultiProcessorCompile = "/MP", NoFramePointer = "/Oy", NoMinimalRebuild = "/Gm-", Symbols = "/Z7", OmitDefaultLibrary = "/Zl", }, floatingpoint = { Fast = "/fp:fast", Strict = "/fp:strict", }, callingconvention = { Cdecl = "/Gd", FastCall = "/Gr", StdCall = "/Gz", VectorCall = "/Gv", }, optimize = { Off = "/Od", On = "/Ot", Debug = "/Od", Full = "/Ox", Size = "/O1", Speed = "/O2", }, vectorextensions = { AVX = "/arch:AVX", AVX2 = "/arch:AVX2", SSE = "/arch:SSE", SSE2 = "/arch:SSE2", SSE3 = "/arch:SSE2", SSSE3 = "/arch:SSE2", ["SSE4.1"] = "/arch:SSE2", }, warnings = { Extra = "/W4", Off = "/W0", } } function msc.getcflags(cfg) local flags = config.mapFlags(cfg, msc.cflags) flags = table.join(flags, msc.getwarnings(cfg)) local runtime = iif(cfg.flags.StaticRuntime, "/MT", "/MD") if config.isDebugBuild(cfg) then runtime = runtime .. "d" end table.insert(flags, runtime) return flags end function msc.getwarnings(cfg) local result = {} for _, disable in ipairs(cfg.disablewarnings) do table.insert(result, '/wd"' .. disable .. '"') end for _, fatal in ipairs(cfg.fatalwarnings) do table.insert(result, '/we"' .. fatal .. '"') end return result end msc.cxxflags = { exceptionhandling = { Default = "/EHsc", On = "/EHsc", SEH = "/EHa", }, rtti = { Off = "/GR-" } } function msc.getcxxflags(cfg) local flags = config.mapFlags(cfg, msc.cxxflags) return flags end msc.defines = { characterset = { Default = { '/D"_UNICODE"', '/D"UNICODE"' }, MBCS = '/D"_MBCS"', Unicode = { '/D"_UNICODE"', '/D"UNICODE"' }, } } function msc.getdefines(defines, cfg) local result if cfg and defines then result = config.mapFlags(cfg, msc.defines) else result = {} end for _, define in ipairs(defines) do table.insert(result, '/D"' .. define .. '"') end return result end function msc.getundefines(undefines) local result = {} for _, undefine in ipairs(undefines) do table.insert(result, '/U"' .. undefine .. '"') end return result end function msc.getforceincludes(cfg) local result = {} table.foreachi(cfg.forceincludes, function(value) local fn = project.getrelative(cfg.project, value) table.insert(result, "/FI" .. premake.quoted(fn)) end) return result end function msc.getincludedirs(cfg, dirs, sysdirs) local result = {} dirs = table.join(dirs, sysdirs) for _, dir in ipairs(dirs) do dir = project.getrelative(cfg.project, dir) table.insert(result, '-I' .. premake.quoted(dir)) end return result end msc.linkerFlags = { flags = { FatalLinkWarnings = "/WX", LinkTimeOptimization = "/GL", NoIncrementalLink = "/INCREMENTAL:NO", NoManifest = "/MANIFEST:NO", OmitDefaultLibrary = "/NODEFAULTLIB", Symbols = "/DEBUG", }, kind = { SharedLib = "/DLL", } } msc.librarianFlags = { flags = { FatalLinkWarnings = "/WX", } } function msc.getldflags(cfg) local map = iif(cfg.kind ~= premake.STATICLIB, msc.linkerFlags, msc.librarianFlags) local flags = config.mapFlags(cfg, map) table.insert(flags, 1, "/NOLOGO") for i, ignore in ipairs(cfg.ignoredefaultlibraries) do if not msc.getLibraryExtensions()[ignore:match("[^.]+$")] then ignore = path.appendextension(ignore, ".lib") end table.insert(flags, '/NODEFAULTLIB:' .. ignore) end return flags end function msc.getLibraryDirectories(cfg) local flags = {} local dirs = table.join(cfg.libdirs, cfg.syslibdirs) for i, dir in ipairs(dirs) do dir = project.getrelative(cfg.project, dir) table.insert(flags, '/LIBPATH:"' .. dir .. '"') end return flags end function msc.getLibraryExtensions() return { ["lib"] = true, ["obj"] = true, } end function msc.getlinks(cfg) local links = config.getlinks(cfg, "system", "fullpath") for i = 1, #links do if not msc.getLibraryExtensions()[links[i]:match("[^.]+$")] then links[i] = path.appendextension(links[i], ".lib") end end return links end function msc.getmakesettings(cfg) return nil end function msc.gettoolname(cfg, tool) return nil end premake.tools.snc = {} local snc = premake.tools.snc local gcc = premake.tools.gcc local config = premake.config snc.cflags = { flags = { FatalCompileWarnings = "-Xquit=2", }, optimize = { Off = "-O0", On = "-O1", Debug = "-Od", Full = "-O3", Size = "-Os", Speed = "-O2", }, warnings = { Extra = "-Xdiag=2", } } function snc.getcflags(cfg) local flags = config.mapFlags(cfg, snc.cflags) return flags end function snc.getcxxflags(cfg) local flags = {} if cfg.exceptionhandling == p.ON then table.insert(flags, "-Xc+=exceptions") elseif cfg.exceptionhandling == p.OFF then table.insert(flags, "-Xc-=exceptions") end if cfg.rtti == p.ON then table.insert(flags, "-Xc+=rtti") elseif cfg.rtti == p.OFF then table.insert(flags, "-Xc-=rtti") end return flags end function snc.getforceincludes(cfg) local flags = gcc.getforceincludes(cfg) return flags end function snc.getldflags(cfg) local flags = { } if not cfg.flags.Symbols then table.insert(flags, "-s") end return flags end snc.getcppflags = gcc.getcppflags snc.getdefines = gcc.getdefines snc.getincludedirs = gcc.getincludedirs snc.getLibraryDirectories = gcc.getLibraryDirectories snc.getlinks = gcc.getlinks function snc.getmakesettings(cfg) return nil end snc.tools = { } function snc.gettoolname(cfg, tool) local names = snc.tools[cfg.architecture] or snc.tools[cfg.system] or {} return names[tool] end premake.tools.clang = {} local clang = premake.tools.clang local gcc = premake.tools.gcc local config = premake.config function clang.getcppflags(cfg) local flags = gcc.getcppflags(cfg) return flags end function clang.getcflags(cfg) local flags = gcc.getcflags(cfg) return flags end function clang.getcxxflags(cfg) local flags = gcc.getcxxflags(cfg) return flags end function clang.getdefines(defines) local flags = gcc.getdefines(defines) return flags end function clang.getundefines(undefines) local flags = gcc.getundefines(undefines) return flags end function clang.getforceincludes(cfg) local flags = gcc.getforceincludes(cfg) return flags end function clang.getincludedirs(cfg, dirs, sysdirs) local flags = gcc.getincludedirs(cfg, dirs, sysdirs) return flags end clang.ldflags = { architecture = { x86 = "-m32", x86_64 = "-m64", }, flags = { LinkTimeOptimization = "-flto", }, kind = { SharedLib = function(cfg) local r = { iif(cfg.system == premake.MACOSX, "-dynamiclib", "-shared") } if cfg.system == "windows" and not cfg.flags.NoImportLib then table.insert(r, '-Wl,--out-implib="' .. cfg.linktarget.relpath .. '"') end return r end, WindowedApp = function(cfg) if cfg.system == premake.WINDOWS then return "-mwindows" end end, }, system = { wii = "$(MACHDEP)", } } function clang.getldflags(cfg) local flags = config.mapFlags(cfg, clang.ldflags) return flags end function clang.getLibraryDirectories(cfg) local flags = gcc.getLibraryDirectories(cfg) return flags end function clang.getlinks(cfg, systemOnly) local flags = gcc.getlinks(cfg, systemOnly) return flags end function clang.getmakesettings(cfg) local flags = gcc.getmakesettings(cfg) return flags end clang.tools = { cc = "clang", cxx = "clang++", ar = "ar" } function clang.gettoolname(cfg, tool) return clang.tools[tool] end premake.make = {} local p = premake local make = p.make local project = p.project newaction { trigger = "gmake", shortname = "GNU Make", description = "Generate GNU makefiles for POSIX, MinGW, and Cygwin", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Utility", "Makefile" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "clang", "gcc" }, dotnet = { "mono", "msnet", "pnet" } }, onWorkspace = function(wks) premake.escaper(make.esc) premake.generate(wks, make.getmakefilename(wks, false), make.generate_workspace) end, onProject = function(prj) premake.escaper(make.esc) local makefile = make.getmakefilename(prj, true) if prj.kind == premake.UTILITY then premake.generate(prj, makefile, make.utility.generate) elseif prj.kind == premake.MAKEFILE then premake.generate(prj, makefile, make.makefile.generate) else if project.isdotnet(prj) then premake.generate(prj, makefile, make.cs.generate) elseif project.iscpp(prj) then premake.generate(prj, makefile, make.cpp.generate) end end end, onCleanWorkspace = function(wks) premake.clean.file(wks, make.getmakefilename(wks, false)) end, onCleanProject = function(prj) premake.clean.file(prj, make.getmakefilename(prj, true)) end } function make.defaultconfig(target) local eachconfig = iif(target.project, project.eachconfig, p.workspace.eachconfig) local iter = eachconfig(target) local cfg = iter() if cfg then _p('ifndef config') _x(' config=%s', cfg.shortname) _p('endif') _p('') end end function make.esc(value) result = value:gsub("\\", "\\\\") result = result:gsub(" ", "\\ ") result = result:gsub("%(", "\\(") result = result:gsub("%)", "\\)") result = result:gsub("$\\%((.-)\\%)", "$(%1)") return result end function make.getmakefilename(this, searchprjs) local count = 0 for wks in p.global.eachWorkspace() do if wks.location == this.location then count = count + 1 end if searchprjs then for _, prj in ipairs(wks.projects) do if prj.location == this.location then count = count + 1 end end end end if count == 1 then return "Makefile" else return ".make" end end function make.header(target) local kind = iif(target.project, "project", "workspace") _p('# %s %s makefile autogenerated by Premake', premake.action.current().shortname, kind) _p('') if kind == "workspace" then _p('.NOTPARALLEL:') _p('') end make.defaultconfig(target) _p('ifndef verbose') _p(' SILENT = @') _p('endif') _p('') end function make.mkdirRules(dirname) _p('%s:', dirname) _p('\t@echo Creating %s', dirname) _p('ifeq (posix,$(SHELLTYPE))') _p('\t$(SILENT) mkdir -p %s', dirname) _p('else') _p('\t$(SILENT) mkdir $(subst /,\\\\,%s)', dirname) _p('endif') _p('') end function make.list(value) if #value > 0 then return " " .. table.concat(value, " ") else return "" end end function make.tovar(value) value = value:gsub("[ -]", "_") value = value:gsub("[()]", "") return value end function make.objdir(cfg) _x(' OBJDIR = %s', project.getrelative(cfg.project, cfg.objdir)) end function make.objDirRules(prj) make.mkdirRules("$(OBJDIR)") end function make.phonyRules(prj) _p('.PHONY: clean prebuild prelink') _p('') end function make.buildCmds(cfg, event) _p(' define %sCMDS', event:upper()) local steps = cfg[event .. "commands"] local msg = cfg[event .. "message"] if #steps > 0 then steps = os.translateCommands(steps) msg = msg or string.format("Running %s commands", event) _p('\t@echo %s', msg) _p('\t%s', table.implode(steps, "", "", "\n\t")) end _p(' endef') end function make.preBuildCmds(cfg, toolset) make.buildCmds(cfg, "prebuild") end function make.preBuildRules(prj) _p('prebuild:') _p('\t$(PREBUILDCMDS)') _p('') end function make.preLinkCmds(cfg, toolset) make.buildCmds(cfg, "prelink") end function make.preLinkRules(prj) _p('prelink:') _p('\t$(PRELINKCMDS)') _p('') end function make.postBuildCmds(cfg, toolset) make.buildCmds(cfg, "postbuild") end function make.settings(cfg, toolset) if #cfg.makesettings > 0 then for _, value in ipairs(cfg.makesettings) do _p(value) end end local value = toolset.getmakesettings(cfg) if value then _p(value) end end function make.shellType() _p('SHELLTYPE := msdos') _p('ifeq (,$(ComSpec)$(COMSPEC))') _p(' SHELLTYPE := posix') _p('endif') _p('ifeq (/bin,$(findstring /bin,$(SHELL)))') _p(' SHELLTYPE := posix') _p('endif') _p('') end function make.target(cfg) _x(' TARGETDIR = %s', project.getrelative(cfg.project, cfg.buildtarget.directory)) _x(' TARGET = $(TARGETDIR)/%s', cfg.buildtarget.name) end function make.targetDirRules(prj) make.mkdirRules("$(TARGETDIR)") end local p = premake local make = p.make local tree = p.tree local project = p.project function make.generate_workspace(wks) p.eol("\n") make.header(wks) make.configmap(wks) make.projects(wks) make.workspacePhonyRule(wks) make.groupRules(wks) make.projectrules(wks) make.cleanrules(wks) make.helprule(wks) end function make.configmap(wks) for cfg in p.workspace.eachconfig(wks) do _p('ifeq ($(config),%s)', cfg.shortname) for prj in p.workspace.eachproject(wks) do local prjcfg = project.getconfig(prj, cfg.buildcfg, cfg.platform) if prjcfg then _p(' %s_config = %s', make.tovar(prj.name), prjcfg.shortname) end end _p('endif') end _p('') end function make.cleanrules(wks) _p('clean:') for prj in p.workspace.eachproject(wks) do local prjpath = premake.filename(prj, make.getmakefilename(prj, true)) local prjdir = path.getdirectory(path.getrelative(wks.location, prjpath)) local prjname = path.getname(prjpath) _x(1,'@${MAKE} --no-print-directory -C %s -f %s clean', prjdir, prjname) end _p('') end function make.helprule(wks) _p('help:') _p(1,'@echo "Usage: make [config=name] [target]"') _p(1,'@echo ""') _p(1,'@echo "CONFIGURATIONS:"') for cfg in p.workspace.eachconfig(wks) do _x(1, '@echo " %s"', cfg.shortname) end _p(1,'@echo ""') _p(1,'@echo "TARGETS:"') _p(1,'@echo " all (default)"') _p(1,'@echo " clean"') for prj in p.workspace.eachproject(wks) do _p(1,'@echo " %s"', prj.name) end _p(1,'@echo ""') _p(1,'@echo "For more information, see http://industriousone.com/premake/quick-start"') end function make.projects(wks) _p('PROJECTS := %s', table.concat(premake.esc(table.extract(wks.projects, "name")), " ")) _p('') end function make.workspacePhonyRule(wks) local groups = {} local tr = p.workspace.grouptree(wks) tree.traverse(tr, { onbranch = function(n) table.insert(groups, n.path) end }) _p('.PHONY: all clean help $(PROJECTS) ' .. table.implode(groups, '', '', ' ')) _p('') _p('all: $(PROJECTS)') _p('') end function make.groupRules(wks) local tr = p.workspace.grouptree(wks) tree.traverse(tr, { onbranch = function(n) local rule = n.path .. ":" local projectTargets = {} local groupTargets = {} for i, c in pairs(n.children) do if type(i) == "string" then if c.project then table.insert(projectTargets, c.name) else table.insert(groupTargets, c.path) end end end if #groupTargets > 0 then rule = rule .. " " .. table.concat(groupTargets, " ") end if #projectTargets > 0 then rule = rule .. " " .. table.concat(projectTargets, " ") end _p(rule) _p('') end }) end function make.projectrules(wks) for prj in p.workspace.eachproject(wks) do local deps = project.getdependencies(prj) deps = table.extract(deps, "name") _p('%s:%s', premake.esc(prj.name), make.list(deps)) local cfgvar = make.tovar(prj.name) _p('ifneq (,$(%s_config))', cfgvar) _p(1,'@echo "==== Building %s ($(%s_config)) ===="', prj.name, cfgvar) local prjpath = premake.filename(prj, make.getmakefilename(prj, true)) local prjdir = path.getdirectory(path.getrelative(wks.location, prjpath)) local prjname = path.getname(prjpath) _x(1,'@${MAKE} --no-print-directory -C %s -f %s config=$(%s_config)', prjdir, prjname, cfgvar) _p('endif') _p('') end end local p = premake p.make.cpp = {} local make = p.make local cpp = p.make.cpp local project = p.project local config = p.config local fileconfig = p.fileconfig cpp.elements = {} cpp.elements.makefile = function(prj) return { make.header, make.phonyRules, make.cppConfigs, make.cppObjects, make.shellType, make.cppTargetRules, make.targetDirRules, make.objDirRules, make.cppCleanRules, make.preBuildRules, make.preLinkRules, make.pchRules, make.cppFileRules, make.cppDependencies, } end function make.cpp.generate(prj) premake.eol("\n") premake.callArray(cpp.elements.makefile, prj) end cpp.elements.configuration = function(cfg) return { make.cppTools, make.target, make.objdir, make.pch, make.defines, make.includes, make.forceInclude, make.cppFlags, make.cFlags, make.cxxFlags, make.resFlags, make.libs, make.ldDeps, make.ldFlags, make.linkCmd, make.exePaths, make.preBuildCmds, make.preLinkCmds, make.postBuildCmds, make.cppAllRules, make.settings, } end function make.cppConfigs(prj) for cfg in project.eachconfig(prj) do local toolset = premake.tools[_OPTIONS.cc or cfg.toolset or "gcc"] if not toolset then error("Invalid toolset '" .. cfg.toolset .. "'") end _x('ifeq ($(config),%s)', cfg.shortname) premake.callArray(cpp.elements.configuration, cfg, toolset) _p('endif') _p('') end end function make.exePaths(cfg) local dirs = project.getrelative(cfg.project, cfg.bindirs) if #dirs > 0 then _p(' EXECUTABLE_PATHS = "%s"', table.concat(dirs, ":")) _p(' EXE_PATHS = export PATH=$(EXECUTABLE_PATHS):$$PATH;') end end function cpp.buildcommand(prj, objext, node) local iscfile = node and path.iscfile(node.abspath) or false local flags = iif(prj.language == "C" or iscfile, '$(CC) $(ALL_CFLAGS)', '$(CXX) $(ALL_CXXFLAGS)') _p('\t$(SILENT) %s $(FORCE_INCLUDE) -o "$@" -MF "$(@:%%.%s=%%.d)" -c "$<"', flags, objext) end function make.cppFileRules(prj) local tr = project.getsourcetree(prj) premake.tree.traverse(tr, { onleaf = function(node, depth) local rules for cfg in project.eachconfig(prj) do local filecfg = fileconfig.getconfig(node, cfg) if fileconfig.hasCustomBuildRule(filecfg) then rules = true break end end if rules then cpp.customFileRules(prj, node) else cpp.standardFileRules(prj, node) end end }) _p('') end function cpp.standardFileRules(prj, node) if path.iscppfile(node.abspath) then _x('$(OBJDIR)/%s.o: %s', node.objname, node.relpath) _p('\t@echo $(notdir $<)') cpp.buildcommand(prj, "o", node) elseif path.isresourcefile(node.abspath) then _x('$(OBJDIR)/%s.res: %s', node.objname, node.relpath) _p('\t@echo $(notdir $<)') _p('\t$(SILENT) $(RESCOMP) $< -O coff -o "$@" $(ALL_RESFLAGS)') end end function cpp.customFileRules(prj, node) for cfg in project.eachconfig(prj) do local filecfg = fileconfig.getconfig(node, cfg) if filecfg then _x('ifeq ($(config),%s)', cfg.shortname) local output = project.getrelative(prj, filecfg.buildoutputs[1]) local dependencies = filecfg.relpath if filecfg.buildinputs and #filecfg.buildinputs > 0 then local inputs = project.getrelative(prj, filecfg.buildinputs) dependencies = dependencies .. " " .. table.concat(p.esc(inputs), " ") end _p('%s: %s', output, dependencies) _p('\t@echo "%s"', filecfg.buildmessage or ("Building " .. filecfg.relpath)) local cmds = os.translateCommands(filecfg.buildcommands) for _, cmd in ipairs(cmds) do if cfg.bindirs and #cfg.bindirs > 0 then _p('\t$(SILENT) $(EXE_PATHS) %s', cmd) else _p('\t$(SILENT) %s', cmd) end end _p('endif') end end end function make.cppObjects(prj) local root = { objects={}, resources={}, customfiles={} } local configs = {} for cfg in project.eachconfig(prj) do configs[cfg] = { objects={}, resources={}, customfiles={} } end local tr = project.getsourcetree(prj) premake.tree.traverse(tr, { onleaf = function(node, depth) local incfg = {} local inall = true local custom = false for cfg in project.eachconfig(prj) do local filecfg = fileconfig.getconfig(node, cfg) if filecfg and not filecfg.flags.ExcludeFromBuild then incfg[cfg] = filecfg custom = fileconfig.hasCustomBuildRule(filecfg) else inall = false end end if not custom then local kind if path.iscppfile(node.abspath) then kind = "objects" elseif path.isresourcefile(node.abspath) then kind = "resources" end if not custom and not kind then return end objectname = "$(OBJDIR)/" .. node.objname .. iif(kind == "objects", ".o", ".res") if inall then table.insert(root[kind], objectname) else for cfg in project.eachconfig(prj) do if incfg[cfg] then table.insert(configs[cfg][kind], objectname) end end end else for cfg in project.eachconfig(prj) do local filecfg = incfg[cfg] if filecfg then local output = project.getrelative(prj, filecfg.buildoutputs[1]) if path.isobjectfile(output) then table.insert(configs[cfg].objects, output) else table.insert(configs[cfg].customfiles, output) end end end end end }) function listobjects(var, list) _p('%s \\', var) for _, objectname in ipairs(list) do _x('\t%s \\', objectname) end _p('') end listobjects('OBJECTS :=', root.objects, 'o') listobjects('RESOURCES :=', root.resources, 'res') listobjects('CUSTOMFILES :=', root.customfiles) for cfg in project.eachconfig(prj) do local files = configs[cfg] if #files.objects > 0 or #files.resources > 0 or #files.customfiles > 0 then _x('ifeq ($(config),%s)', cfg.shortname) if #files.objects > 0 then listobjects(' OBJECTS +=', files.objects) end if #files.resources > 0 then listobjects(' RESOURCES +=', files.resources) end if #files.customfiles > 0 then listobjects(' CUSTOMFILES +=', files.customfiles) end _p('endif') _p('') end end end function make.cFlags(cfg, toolset) _p(' ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS)%s', make.list(table.join(toolset.getcflags(cfg), cfg.buildoptions))) end function make.cppAllRules(cfg, toolset) if cfg.system == premake.MACOSX and cfg.kind == premake.WINDOWEDAPP then _p('all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET) $(dir $(TARGETDIR))PkgInfo $(dir $(TARGETDIR))Info.plist') _p('\t@:') _p('') _p('$(dir $(TARGETDIR))PkgInfo:') _p('$(dir $(TARGETDIR))Info.plist:') else _p('all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)') _p('\t@:') end end function make.cppFlags(cfg, toolset) _p(' ALL_CPPFLAGS += $(CPPFLAGS)%s $(DEFINES) $(INCLUDES)', make.list(toolset.getcppflags(cfg))) end function make.cxxFlags(cfg, toolset) _p(' ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS)%s', make.list(toolset.getcxxflags(cfg))) end function make.cppCleanRules(prj) _p('clean:') _p('\t@echo Cleaning %s', prj.name) _p('ifeq (posix,$(SHELLTYPE))') _p('\t$(SILENT) rm -f $(TARGET)') _p('\t$(SILENT) rm -rf $(OBJDIR)') _p('else') _p('\t$(SILENT) if exist $(subst /,\\\\,$(TARGET)) del $(subst /,\\\\,$(TARGET))') _p('\t$(SILENT) if exist $(subst /,\\\\,$(OBJDIR)) rmdir /s /q $(subst /,\\\\,$(OBJDIR))') _p('endif') _p('') end function make.cppDependencies(prj) _p('-include $(OBJECTS:%%.o=%%.d)') _p('ifneq (,$(PCH))') _p(' -include $(OBJDIR)/$(notdir $(PCH)).d') _p('endif') end function make.cppTargetRules(prj) _p('$(TARGET): $(GCH) ${CUSTOMFILES} $(OBJECTS) $(LDDEPS) $(RESOURCES)') _p('\t@echo Linking %s', prj.name) _p('\t$(SILENT) $(LINKCMD)') _p('\t$(POSTBUILDCMDS)') _p('') end function make.cppTools(cfg, toolset) local tool = toolset.gettoolname(cfg, "cc") if tool then _p(' ifeq ($(origin CC), default)') _p(' CC = %s', tool) _p(' endif' ) end tool = toolset.gettoolname(cfg, "cxx") if tool then _p(' ifeq ($(origin CXX), default)') _p(' CXX = %s', tool) _p(' endif' ) end tool = toolset.gettoolname(cfg, "ar") if tool then _p(' ifeq ($(origin AR), default)') _p(' AR = %s', tool) _p(' endif' ) end tool = toolset.gettoolname(cfg, "rc") if tool then _p(' RESCOMP = %s', tool) end end function make.defines(cfg, toolset) _p(' DEFINES +=%s', make.list(table.join(toolset.getdefines(cfg.defines, cfg), toolset.getundefines(cfg.undefines)))) end function make.forceInclude(cfg, toolset) local includes = toolset.getforceincludes(cfg) if not cfg.flags.NoPCH and cfg.pchheader then table.insert(includes, "-include $(OBJDIR)/$(notdir $(PCH))") end _x(' FORCE_INCLUDE +=%s', make.list(includes)) end function make.includes(cfg, toolset) local includes = toolset.getincludedirs(cfg, cfg.includedirs, cfg.sysincludedirs) _p(' INCLUDES +=%s', make.list(includes)) end function make.ldDeps(cfg, toolset) local deps = config.getlinks(cfg, "siblings", "fullpath") _p(' LDDEPS +=%s', make.list(premake.esc(deps))) end function make.ldFlags(cfg, toolset) local flags = table.join(toolset.getLibraryDirectories(cfg), toolset.getldflags(cfg), cfg.linkoptions) _p(' ALL_LDFLAGS += $(LDFLAGS)%s', make.list(flags)) end function make.libs(cfg, toolset) local flags = toolset.getlinks(cfg) _p(' LIBS +=%s', make.list(flags)) end function make.linkCmd(cfg, toolset) if cfg.kind == premake.STATICLIB then if cfg.architecture == premake.UNIVERSAL then _p(' LINKCMD = libtool -o "$@" $(OBJECTS)') else _p(' LINKCMD = $(AR) -rcs "$@" $(OBJECTS)') end elseif cfg.kind == premake.UTILITY then _p(' LINKCMD =') else local cc = iif(cfg.language == "C", "CC", "CXX") _p(' LINKCMD = $(%s) -o "$@" $(OBJECTS) $(RESOURCES) $(ALL_LDFLAGS) $(LIBS)', cc) end end function make.pch(cfg, toolset) if not cfg.pchheader or cfg.flags.NoPCH then return end local pch = cfg.pchheader local found = false for _, incdir in ipairs(cfg.includedirs) do local testname = path.join(incdir, pch) if os.isfile(testname) then pch = project.getrelative(cfg.project, testname) found = true break end end if not found then pch = project.getrelative(cfg.project, path.getabsolute(pch)) end _x(' PCH = %s', pch) _p(' GCH = $(OBJDIR)/$(notdir $(PCH)).gch') end function make.pchRules(prj) _p('ifneq (,$(PCH))') _p('$(OBJECTS): $(GCH) $(PCH)') _p('$(GCH): $(PCH)') _p('\t@echo $(notdir $<)') local cmd = iif(prj.language == "C", "$(CC) -x c-header $(ALL_CFLAGS)", "$(CXX) -x c++-header $(ALL_CXXFLAGS)") _p('\t$(SILENT) %s -o "$@" -MF "$(@:%%.gch=%%.d)" -c "$<"', cmd) _p('endif') _p('') end function make.resFlags(cfg, toolset) local resflags = table.join(toolset.getdefines(cfg.resdefines), toolset.getincludedirs(cfg, cfg.resincludedirs), cfg.resoptions) _p(' ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)%s', make.list(resflags)) end premake.make.cs = {} local make = premake.make local cs = premake.make.cs local project = premake.project local config = premake.config local fileconfig = premake.fileconfig cs.elements = {} cs.elements.makefile = function(prj) return { make.header, make.phonyRules, make.csConfigs, make.csProjectConfig, make.csSources, make.csEmbedFiles, make.csCopyFiles, make.csResponseFile, make.shellType, make.csAllRules, make.csTargetRules, make.targetDirRules, make.csResponseRules, make.objDirRules, make.csCleanRules, make.preBuildRules, make.preLinkRules, make.csFileRules, } end function make.cs.generate(prj) premake.eol("\n") local toolset = premake.tools.dotnet premake.callArray(cs.elements.makefile, prj, toolset) end cs.elements.configuration = function(cfg) return { make.csTools, make.target, make.objdir, make.csFlags, make.csLinkCmd, make.preBuildCmds, make.preLinkCmds, make.postBuildCmds, make.settings, } end function make.csConfigs(prj, toolset) for cfg in project.eachconfig(prj) do _x('ifeq ($(config),%s)', cfg.shortname) premake.callArray(cs.elements.configuration, cfg, toolset) _p('endif') _p('') end end function cs.getresourcefilename(cfg, fname) if path.getextension(fname) == ".resx" then local name = cfg.buildtarget.basename .. "." local dir = path.getdirectory(fname) if dir ~= "." then name = name .. path.translate(dir, ".") .. "." end return "$(OBJDIR)/" .. premake.esc(name .. path.getbasename(fname)) .. ".resources" else return fname end end function cs.listsources(prj, selector) local tr = project.getsourcetree(prj) premake.tree.traverse(tr, { onleaf = function(node, depth) local value = selector(node) if value then _x('\t%s \\', value) end end }) end function make.csAllRules(prj, toolset) _p('all: $(TARGETDIR) $(OBJDIR) prebuild $(EMBEDFILES) $(COPYFILES) prelink $(TARGET)') _p('') end function make.csCleanRules(prj, toolset) end function make.csCopyFiles(prj, toolset) end function make.cs.getresponsefilename(prj) return '$(OBJDIR)/' .. prj.filename .. '.rsp' end function make.csResponseFile(prj, toolset) _x('RESPONSE += ' .. make.cs.getresponsefilename(prj)) end function make.csResponseRules(prj) local toolset = premake.tools.dotnet local ext = make.getmakefilename(prj, true) local makefile = path.getname(premake.filename(prj, ext)) local response = make.cs.getresponsefilename(prj) _p('$(RESPONSE): %s', makefile) _p('\t@echo Generating response file', prj.name) _p('ifeq (posix,$(SHELLTYPE))') _x('\t$(SILENT) rm -f $(RESPONSE)') _p('else') _x('\t$(SILENT) if exist $(RESPONSE) del %s', path.translate(response, '\\')) _p('endif') local sep = os.is("windows") and "\\" or "/" local tr = project.getsourcetree(prj) premake.tree.traverse(tr, { onleaf = function(node, depth) if toolset.fileinfo(node).action == "Compile" then _x('\t@echo %s >> $(RESPONSE)', path.translate(node.relpath, sep)) end end }) _p('') end function make.csEmbedFiles(prj, toolset) local cfg = project.getfirstconfig(prj) _p('EMBEDFILES += \\') cs.listsources(prj, function(node) local fcfg = fileconfig.getconfig(node, cfg) local info = toolset.fileinfo(fcfg) if info.action == "EmbeddedResource" then return cs.getresourcefilename(cfg, node.relpath) end end) _p('') end function make.csFileRules(prj, toolset) end function make.csFlags(cfg, toolset) _p(' FLAGS =%s', make.list(toolset.getflags(cfg))) end function make.csLinkCmd(cfg, toolset) local deps = premake.esc(config.getlinks(cfg, "dependencies", "fullpath")) _p(' DEPENDS =%s', make.list(deps)) _p(' REFERENCES = %s', table.implode(deps, "/r:", "", " ")) end function make.csProjectConfig(prj, toolset) local cfg = project.getfirstconfig(prj) local kindflag = "/t:" .. toolset.getkind(cfg):lower() local libdirs = table.implode(premake.esc(cfg.libdirs), "/lib:", "", " ") _p('FLAGS += %s', table.concat(table.join(kindflag, libdirs), " ")) local refs = premake.esc(config.getlinks(cfg, "system", "fullpath")) _p('REFERENCES += %s', table.implode(refs, "/r:", "", " ")) _p('') end function make.csSources(prj, toolset) local cfg = project.getfirstconfig(prj) _p('SOURCES += \\') cs.listsources(prj, function(node) local fcfg = fileconfig.getconfig(node, cfg) local info = toolset.fileinfo(fcfg) if info.action == "Compile" then return node.relpath end end) _p('') end function make.csTargetRules(prj, toolset) _p('$(TARGET): $(SOURCES) $(EMBEDFILES) $(DEPENDS) $(RESPONSE)') _p('\t$(SILENT) $(CSC) /nologo /out:$@ $(FLAGS) $(REFERENCES) @$(RESPONSE) $(patsubst %%,/resource:%%,$(EMBEDFILES))') _p('\t$(POSTBUILDCMDS)') _p('') end function make.csTools(cfg, toolset) _p(' CSC = %s', toolset.gettoolname(cfg, "csc")) _p(' RESGEN = %s', toolset.gettoolname(cfg, "resgen")) end local p = premake p.make.utility = {} local make = p.make local utility = p.make.utility local project = p.project local config = p.config local fileconfig = p.fileconfig utility.elements = {} utility.elements.makefile = { "header", "phonyRules", "utilityConfigs", "utilityTargetRules" } function make.utility.generate(prj) premake.eol("\n") premake.callarray(make, utility.elements.makefile, prj) end utility.elements.configuration = { "target", "preBuildCmds", "postBuildCmds", } function make.utilityConfigs(prj) for cfg in project.eachconfig(prj) do local toolset = premake.tools[cfg.toolset or "gcc"] if not toolset then error("Invalid toolset '" .. cfg.toolset .. "'") end _x('ifeq ($(config),%s)', cfg.shortname) premake.callarray(make, utility.elements.configuration, cfg, toolset) _p('endif') _p('') end end function make.utilityTargetRules(prj) _p('$(TARGET):') _p('\t$(PREBUILDCMDS)') _p('\t$(POSTBUILDCMDS)') _p('') end local p = premake p.make.makefile = {} local make = p.make local makefile = p.make.makefile local project = p.project local config = p.config local fileconfig = p.fileconfig makefile.elements = {} makefile.elements.makefile = { "header", "phonyRules", "makefileConfigs", "makefileTargetRules" } function make.makefile.generate(prj) premake.eol("\n") premake.callarray(make, makefile.elements.makefile, prj) end makefile.elements.configuration = { "target", "buildCommands", "cleanCommands", } function make.makefileConfigs(prj) for cfg in project.eachconfig(prj) do local toolset = premake.tools[cfg.toolset or "gcc"] if not toolset then error("Invalid toolset '" .. cfg.toolset .. "'") end _x('ifeq ($(config),%s)', cfg.shortname) premake.callarray(make, makefile.elements.configuration, cfg, toolset) _p('endif') _p('') end end function make.makefileTargetRules(prj) _p('$(TARGET):') _p('\t$(BUILDCMDS)') _p('') _p('clean:') _p('\t$(CLEANCMDS)') _p('') end function make.buildCommands(cfg) _p(' define BUILDCMDS') local steps = cfg.buildcommands if #steps > 0 then steps = os.translateCommands(steps) _p('\t@echo Running build commands') _p('\t%s', table.implode(steps, "", "", "\n\t")) end _p(' endef') end function make.cleanCommands(cfg) _p(' define CLEANCMDS') local steps = cfg.cleancommands if #steps > 0 then steps = os.translateCommands(steps) _p('\t@echo Running clean commands') _p('\t%s', table.implode(steps, "", "", "\n\t")) end _p(' endef') end premake.vstudio = {} local vstudio = premake.vstudio local p = premake local project = p.project local config = p.config vstudio.vs200x_architectures = { win32 = "x86", x86 = "x86", x86_64 = "x64", xbox360 = "Xbox 360", } vstudio.vs2010_architectures = { win32 = "x86", } local function architecture(system, arch) local result if _ACTION >= "vs2010" then result = vstudio.vs2010_architectures[arch] or vstudio.vs2010_architectures[system] end return result or vstudio.vs200x_architectures[arch] or vstudio.vs200x_architectures[system] end vstudio._cultures = { ["af"] = 0x0036, ["af-ZA"] = 0x0436, ["sq"] = 0x001C, ["sq-AL"] = 0x041C, ["ar"] = 0x0001, ["ar-DZ"] = 0x1401, ["ar-BH"] = 0x3C01, ["ar-EG"] = 0x0C01, ["ar-IQ"] = 0x0801, ["ar-JO"] = 0x2C01, ["ar-KW"] = 0x3401, ["ar-LB"] = 0x3001, ["ar-LY"] = 0x1001, ["ar-MA"] = 0x1801, ["ar-OM"] = 0x2001, ["ar-QA"] = 0x4001, ["ar-SA"] = 0x0401, ["ar-SY"] = 0x2801, ["ar-TN"] = 0x1C01, ["ar-AE"] = 0x3801, ["ar-YE"] = 0x2401, ["hy"] = 0x002B, ["hy-AM"] = 0x042B, ["az"] = 0x002C, ["az-Cyrl-AZ"] = 0x082C, ["az-Latn-AZ"] = 0x042C, ["eu"] = 0x002D, ["eu-ES"] = 0x042D, ["be"] = 0x0023, ["be-BY"] = 0x0423, ["bg"] = 0x0002, ["bg-BG"] = 0x0402, ["ca"] = 0x0003, ["ca-ES"] = 0x0403, ["zh-HK"] = 0x0C04, ["zh-MO"] = 0x1404, ["zh-CN"] = 0x0804, ["zh-Hans"] = 0x0004, ["zh-SG"] = 0x1004, ["zh-TW"] = 0x0404, ["zh-Hant"] = 0x7C04, ["hr"] = 0x001A, ["hr-HR"] = 0x041A, ["cs"] = 0x0005, ["cs-CZ"] = 0x0405, ["da"] = 0x0006, ["da-DK"] = 0x0406, ["dv"] = 0x0065, ["dv-MV"] = 0x0465, ["nl"] = 0x0013, ["nl-BE"] = 0x0813, ["nl-NL"] = 0x0413, ["en"] = 0x0009, ["en-AU"] = 0x0C09, ["en-BZ"] = 0x2809, ["en-CA"] = 0x1009, ["en-029"] = 0x2409, ["en-IE"] = 0x1809, ["en-JM"] = 0x2009, ["en-NZ"] = 0x1409, ["en-PH"] = 0x3409, ["en-ZA"] = 0x1C09, ["en-TT"] = 0x2C09, ["en-GB"] = 0x0809, ["en-US"] = 0x0409, ["en-ZW"] = 0x3009, ["et"] = 0x0025, ["et-EE"] = 0x0425, ["fo"] = 0x0038, ["fo-FO"] = 0x0438, ["fa"] = 0x0029, ["fa-IR"] = 0x0429, ["fi"] = 0x000B, ["fi-FI"] = 0x040B, ["fr"] = 0x000C, ["fr-BE"] = 0x080C, ["fr-CA"] = 0x0C0C, ["fr-FR"] = 0x040C, ["fr-LU"] = 0x140C, ["fr-MC"] = 0x180C, ["fr-CH"] = 0x100C, ["gl"] = 0x0056, ["gl-ES"] = 0x0456, ["ka"] = 0x0037, ["ka-GE"] = 0x0437, ["de"] = 0x0007, ["de-AT"] = 0x0C07, ["de-DE"] = 0x0407, ["de-LI"] = 0x1407, ["de-LU"] = 0x1007, ["de-CH"] = 0x0807, ["el"] = 0x0008, ["el-GR"] = 0x0408, ["gu"] = 0x0047, ["gu-IN"] = 0x0447, ["he"] = 0x000D, ["he-IL"] = 0x040D, ["hi"] = 0x0039, ["hi-IN"] = 0x0439, ["hu"] = 0x000E, ["hu-HU"] = 0x040E, ["is"] = 0x000F, ["is-IS"] = 0x040F, ["id"] = 0x0021, ["id-ID"] = 0x0421, ["it"] = 0x0010, ["it-IT"] = 0x0410, ["it-CH"] = 0x0810, ["ja"] = 0x0011, ["ja-JP"] = 0x0411, ["kn"] = 0x004B, ["kn-IN"] = 0x044B, ["kk"] = 0x003F, ["kk-KZ"] = 0x043F, ["kok"] = 0x0057, ["kok-IN"] = 0x0457, ["ko"] = 0x0012, ["ko-KR"] = 0x0412, ["ky"] = 0x0040, ["ky-KG"] = 0x0440, ["lv"] = 0x0026, ["lv-LV"] = 0x0426, ["lt"] = 0x0027, ["lt-LT"] = 0x0427, ["mk"] = 0x002F, ["mk-MK"] = 0x042F, ["ms"] = 0x003E, ["ms-BN"] = 0x083E, ["ms-MY"] = 0x043E, ["mr"] = 0x004E, ["mr-IN"] = 0x044E, ["mn"] = 0x0050, ["mn-MN"] = 0x0450, ["no"] = 0x0014, ["nb-NO"] = 0x0414, ["nn-NO"] = 0x0814, ["pl"] = 0x0015, ["pl-PL"] = 0x0415, ["pt"] = 0x0016, ["pt-BR"] = 0x0416, ["pt-PT"] = 0x0816, ["pa"] = 0x0046, ["pa-IN"] = 0x0446, ["ro"] = 0x0018, ["ro-RO"] = 0x0418, ["ru"] = 0x0019, ["ru-RU"] = 0x0419, ["sa"] = 0x004F, ["sa-IN"] = 0x044F, ["sr-Cyrl-CS"] = 0x0C1A, ["sr-Latn-CS"] = 0x081A, ["sk"] = 0x001B, ["sk-SK"] = 0x041B, ["sl"] = 0x0024, ["sl-SI"] = 0x0424, ["es"] = 0x000A, ["es-AR"] = 0x2C0A, ["es-BO"] = 0x400A, ["es-CL"] = 0x340A, ["es-CO"] = 0x240A, ["es-CR"] = 0x140A, ["es-DO"] = 0x1C0A, ["es-EC"] = 0x300A, ["es-SV"] = 0x440A, ["es-GT"] = 0x100A, ["es-HN"] = 0x480A, ["es-MX"] = 0x080A, ["es-NI"] = 0x4C0A, ["es-PA"] = 0x180A, ["es-PY"] = 0x3C0A, ["es-PE"] = 0x280A, ["es-PR"] = 0x500A, ["es-ES"] = 0x0C0A, ["es-ES_tradnl"]= 0x040A, ["es-UY"] = 0x380A, ["es-VE"] = 0x200A, ["sw"] = 0x0041, ["sw-KE"] = 0x0441, ["sv"] = 0x001D, ["sv-FI"] = 0x081D, ["sv-SE"] = 0x041D, ["syr"] = 0x005A, ["syr-SY"] = 0x045A, ["ta"] = 0x0049, ["ta-IN"] = 0x0449, ["tt"] = 0x0044, ["tt-RU"] = 0x0444, ["te"] = 0x004A, ["te-IN"] = 0x044A, ["th"] = 0x001E, ["th-TH"] = 0x041E, ["tr"] = 0x001F, ["tr-TR"] = 0x041F, ["uk"] = 0x0022, ["uk-UA"] = 0x0422, ["ur"] = 0x0020, ["ur-PK"] = 0x0420, ["uz"] = 0x0043, ["uz-Cyrl-UZ"] = 0x0843, ["uz-Latn-UZ"] = 0x0443, ["vi"] = 0x002A, ["vi-VN"] = 0x042A, } function vstudio.archFromConfig(cfg, win32) local isnative = project.isnative(cfg.project) local arch = architecture(cfg.system, cfg.architecture) if not arch then arch = iif(isnative, "x86", "Any CPU") end if win32 and isnative and arch == "x86" then arch = "Win32" end return arch end function vstudio.archFromPlatform(platform) local system = premake.api.checkValue(premake.fields.system, platform) local arch = premake.api.checkValue(premake.fields.architecture, platform) return architecture(system, arch or platform:lower()) end function vstudio.cultureForLocale(locale) if locale then local culture = vstudio._cultures[locale] if not culture then premake.warnOnce("Locale" .. locale, 'Unsupported locale "%s"', locale) end return culture end end function vstudio.getLinks(cfg, explicit) local links = {} if explicit then links = config.getlinks(cfg, "siblings", "fullpath") end local system = config.getlinks(cfg, "system", "fullpath") for i = 1, #system do local link = system[i] if not p.tools.msc.getLibraryExtensions()[link:match("[^.]+$")] then link = path.appendextension(link, ".lib") end table.insert(links, link) end return links end function vstudio.isMakefile(cfg) return (cfg.kind == premake.MAKEFILE or cfg.kind == premake.NONE) end function vstudio.needsExplicitLink(cfg) if not cfg._needsExplicitLink then local ex = cfg.flags.NoImplicitLink if not ex then local prjdeps = project.getdependencies(cfg.project, "linkOnly") local cfgdeps = config.getlinks(cfg, "dependencies", "object") ex = #prjdeps ~= #cfgdeps end cfg._needsExplicitLink = ex end return cfg._needsExplicitLink end function vstudio.path(cfg, value) cfg = cfg.project or cfg local dirs = path.translate(project.getrelative(cfg, value)) if type(dirs) == 'table' then dirs = table.filterempty(dirs) end return dirs end function vstudio.projectConfig(cfg, arch) local platform = vstudio.projectPlatform(cfg) local architecture = arch or vstudio.archFromConfig(cfg, true) return platform .. "|" .. architecture end function vstudio.projectElement() p.push('') end function vstudio.projectfile(prj) local extension if project.isdotnet(prj) then extension = ".csproj" elseif project.iscpp(prj) then extension = iif(_ACTION > "vs2008", ".vcxproj", ".vcproj") end return premake.filename(prj, extension) end function vstudio.projectPlatform(cfg) local platform = cfg.platform if platform then local pltarch = vstudio.archFromPlatform(cfg.platform) or platform local cfgarch = vstudio.archFromConfig(cfg) if pltarch == cfgarch then platform = nil end end if platform then return cfg.buildcfg .. " " .. platform else return cfg.buildcfg end end function vstudio.solutionPlatform(cfg) local platform = cfg.platform local platarch if platform then platform = vstudio.archFromPlatform(platform) or platform if platform ~= "x86" then return platform end end local hasnative = false local hasnet = false local slnarch for prj in p.workspace.eachproject(cfg.workspace) do if project.isnative(prj) then hasnative = true elseif project.isdotnet(prj) then hasnet = true end local prjcfg = project.getconfig(prj, cfg.buildcfg, cfg.platform) if prjcfg then local prjarch = vstudio.archFromConfig(prjcfg) if not slnarch then slnarch = prjarch elseif slnarch ~= prjarch then slnarch = "Mixed Platforms" end end end if platform then return iif(hasnet, "x86", "Win32") elseif slnarch then return iif(slnarch == "x86" and not hasnet, "Win32", slnarch) elseif hasnet and hasnative then return "Mixed Platforms" elseif hasnet then return "Any CPU" else return "Win32" end end function vstudio.solutionarch(cfg) local hasnative = false local hasdotnet = false local arch = cfg.platform for prj in p.workspace.eachproject(cfg.workspace) do if project.isnative(prj) then hasnative = true elseif project.isdotnet(prj) then hasdotnet = true end if hasnative and hasdotnet then return "Mixed Platforms" end if not arch then local prjcfg = project.getconfig(prj, cfg.buildcfg, cfg.platform) if prjcfg then if prjcfg.architecture then arch = vstudio.archFromConfig(prjcfg) end end end end arch = arch or iif(hasnative, "Win32", "Any CPU") return arch end function vstudio.solutionconfig(cfg) local platform = cfg.platform if not platform then platform = vstudio.solutionarch(cfg) end return string.format("%s|%s", cfg.buildcfg, platform) end function vstudio.tool(prj) if project.isdotnet(prj) then return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC" elseif project.iscpp(prj) then return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942" end end premake.vstudio.vs2005 = {} local p = premake local vs2005 = p.vstudio.vs2005 local vstudio = p.vstudio function vs2005.generateSolution(wks) p.indent("\t") p.eol("\r\n") p.escaper(vs2005.esc) premake.generate(wks, ".sln", vstudio.sln2005.generate) end function vs2005.generateProject(prj) p.indent(" ") p.eol("\r\n") p.escaper(vs2005.esc) if premake.project.isdotnet(prj) then premake.generate(prj, ".csproj", vstudio.cs2005.generate) local user = p.capture(function() vstudio.cs2005.generateUser(prj) end) if #user > 0 then p.generate(prj, ".csproj.user", function() p.outln(user) end) end elseif premake.project.iscpp(prj) then premake.generate(prj, ".vcproj", vstudio.vc200x.generate) local user = p.capture(function() vstudio.vc200x.generateUser(prj) end) if #user > 0 then p.generate(prj, ".vcproj.user", function() p.outln(user) end) end end end function vs2005.esc(value) value = string.gsub(value, '&', "&") value = value:gsub('"', """) value = value:gsub("'", "'") value = value:gsub('<', "<") value = value:gsub('>', ">") value = value:gsub('\r', " ") value = value:gsub('\n', " ") return value end newaction { trigger = "vs2005", shortname = "Visual Studio 2005", description = "Generate Visual Studio 2005 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Makefile", "None" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onWorkspace = vstudio.vs2005.generateSolution, onProject = vstudio.vs2005.generateProject, onCleanWorkspace = vstudio.cleanSolution, onCleanProject = vstudio.cleanProject, onCleanTarget = vstudio.cleanTarget, vstudio = { csprojSchemaVersion = "2.0", productVersion = "8.0.50727", solutionVersion = "9", versionName = "2005", } } premake.vstudio.vs2008 = {} local vs2008 = premake.vstudio.vs2008 local vstudio = premake.vstudio newaction { trigger = "vs2008", shortname = "Visual Studio 2008", description = "Generate Visual Studio 2008 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Makefile", "None" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onWorkspace = vstudio.vs2005.generateSolution, onProject = vstudio.vs2005.generateProject, onCleanWorkspace = vstudio.cleanSolution, onCleanProject = vstudio.cleanProject, onCleanTarget = vstudio.cleanTarget, vstudio = { csprojSchemaVersion = "2.0", productVersion = "9.0.30729", solutionVersion = "10", versionName = "2008", toolsVersion = "3.5", } } premake.vstudio.vc200x = {} local m = premake.vstudio.vc200x local p = premake local vstudio = p.vstudio local context = p.context local project = p.project local config = p.config local fileconfig = p.fileconfig m.elements = {} m.elements.project = function(prj) return { m.xmlElement, m.visualStudioProject, m.platforms, m.toolFiles, m.configurations, m.references, m.files, m.globals } end function m.generate(prj) p.indent("\t") p.callArray(m.elements.project, prj) p.pop('') p.w() end m.elements.visualStudioProject = function(prj) return { m.projectType, m.version, m.projectName, m.projectGUID, m.rootNamespace, m.keyword, m.targetFrameworkVersion } end function m.visualStudioProject(prj) p.push('') end function m.configurations(prj) p.push('') local mapping = {} for cfg in project.eachconfig(prj) do local name = vstudio.projectConfig(cfg) mapping[cfg] = name mapping[name] = cfg end for cfg in project.eachconfig(prj) do for i, arch in ipairs(architectures) do local target local testName = vstudio.projectConfig(cfg, arch) if testName == mapping[cfg] then target = cfg elseif not mapping[testName] then target = { fake = true } end if target then m.configuration(target, testName) m.tools(target) p.pop('') end end end p.pop('') end m.elements.configuration = function(cfg) if cfg.fake then return { m.intermediateDirectory, m.configurationType } else return { m.outputDirectory, m.intermediateDirectory, m.configurationType, m.useOfMFC, m.characterSet, m.managedExtensions, } end end function m.configuration(cfg, name) p.push('') end m.elements.tools = function(cfg) if vstudio.isMakefile(cfg) and not cfg.fake then return { m.VCNMakeTool } end if cfg.system == p.XBOX360 then return { m.VCPreBuildEventTool, m.VCCustomBuildTool, m.VCXMLDataGeneratorTool, m.VCWebServiceProxyGeneratorTool, m.VCMIDLTool, m.VCCLCompilerTool, m.VCManagedResourceCompilerTool, m.VCResourceCompilerTool, m.VCPreLinkEventTool, m.VCLinkerTool, m.VCALinkTool, m.VCX360ImageTool, m.VCBscMakeTool, m.VCX360DeploymentTool, m.VCPostBuildEventTool, m.DebuggerTool, } else return { m.VCPreBuildEventTool, m.VCCustomBuildTool, m.VCXMLDataGeneratorTool, m.VCWebServiceProxyGeneratorTool, m.VCMIDLTool, m.VCCLCompilerTool, m.VCManagedResourceCompilerTool, m.VCResourceCompilerTool, m.VCPreLinkEventTool, m.VCLinkerTool, m.VCALinkTool, m.VCManifestTool, m.VCXDCMakeTool, m.VCBscMakeTool, m.VCFxCopTool, m.VCAppVerifierTool, m.VCPostBuildEventTool, } end end function m.tools(cfg) premake.callArray(m.elements.tools, cfg, config.toolset(cfg)) end m.elements.references = function(prj) return { m.assemblyReferences, m.projectReferences, } end function m.references(prj) p.push('') p.callArray(m.elements.references, prj) p.pop('') end function m.files(prj) local tr = m.filesSorted(prj) p.push('') p.tree.traverse(tr, { onbranchenter = m.filesFilterStart, onbranchexit = m.filesFilterEnd, onleaf = m.filesFile, }, false) p.pop('') end function m.filesSorted(prj) return project.getsourcetree(prj, function(a,b) local istop = (a.parent.parent == nil) local aSortName = a.name local bSortName = b.name if a.relpath then if not b.relpath then return not istop end aSortName = a.relpath:gsub("%.%.%/", "") end if b.relpath then if not a.relpath then return istop end bSortName = b.relpath:gsub("%.%.%/", "") end return aSortName < bSortName end) end function m.filesFilterStart(node) p.push('') end function m.filesFilterEnd(node) p.pop('') end function m.filesFile(node) p.push('') local prj = node.project for cfg in project.eachconfig(prj) do m.fileConfiguration(cfg, node) end p.pop('') end m.elements.fileConfigurationAttributes = function(filecfg) return { m.excludedFromBuild, } end function m.fileConfiguration(cfg, node) local filecfg = fileconfig.getconfig(node, cfg) local configAttribs = p.capture(function () p.push() p.callArray(m.elements.fileConfigurationAttributes, filecfg) p.pop() end) local compilerAttribs = p.capture(function () p.push() m.VCCLCompilerTool(filecfg) p.pop() end) if #configAttribs > 0 or compilerAttribs:lines() > 3 then p.push(' 0 then p.outln(configAttribs) end p.w('>') p.outln(compilerAttribs) p.pop('') end end m.elements.globals = function(prj) return {} end function m.globals(prj) p.push('') p.callArray(m.elements.globals, prj) p.pop('') end function m.VCTool(name, cfg, ...) p.push('') end m.elements.DebuggerTool = function(cfg) return {} end function m.DebuggerTool(cfg) p.push('') end m.elements.VCALinkTool = function(cfg) return {} end function m.VCALinkTool(cfg) m.VCTool("VCALinkTool", cfg) end m.elements.VCAppVerifierTool = function(cfg) return {} end function m.VCAppVerifierTool(cfg) if cfg.kind ~= p.STATICLIB then m.VCTool("VCAppVerifierTool", cfg) end end m.elements.VCBscMakeTool = function(cfg) return {} end function m.VCBscMakeTool(cfg) m.VCTool("VCBscMakeTool", cfg) end m.elements.VCCLCompilerTool = function(cfg, toolset) if not toolset then return { m.customBuildTool, m.objectFile, m.additionalCompilerOptions, m.optimization, m.additionalIncludeDirectories, m.wholeProgramOptimization, m.preprocessorDefinitions, m.undefinePreprocessorDefinitions, m.minimalRebuild, m.basicRuntimeChecks, m.bufferSecurityCheck, m.stringPooling, m.exceptionHandling, m.runtimeLibrary, m.enableFunctionLevelLinking, m.enableEnhancedInstructionSet, m.floatingPointModel, m.runtimeTypeInfo, m.treatWChar_tAsBuiltInType, m.usePrecompiledHeader, m.programDataBaseFileName, m.warningLevel, m.warnAsError, m.detect64BitPortabilityProblems, m.debugInformationFormat, m.compileAs, m.disableSpecificWarnings, m.forcedIncludeFiles, m.omitDefaultLib, } else return { m.additionalExternalCompilerOptions, m.additionalIncludeDirectories, m.preprocessorDefinitions, m.undefinePreprocessorDefinitions, m.usePrecompiledHeader, m.programDataBaseFileName, m.debugInformationFormat, m.compileAs, m.forcedIncludeFiles, } end end function m.VCCLCompilerToolName(cfg) local prjcfg, filecfg = config.normalize(cfg) if filecfg and fileconfig.hasCustomBuildRule(filecfg) then return "VCCustomBuildTool" elseif prjcfg and prjcfg.system == p.XBOX360 then return "VCCLX360CompilerTool" else return "VCCLCompilerTool" end end function m.VCCLCompilerTool(cfg, toolset) m.VCTool("VCCLCompilerTool", cfg, toolset) end m.elements.VCCustomBuildTool = function(cfg) return {} end function m.VCCustomBuildTool(cfg) m.VCTool("VCCustomBuildTool", cfg) end m.elements.VCFxCopTool = function(cfg) return {} end function m.VCFxCopTool(cfg) m.VCTool("VCFxCopTool", cfg) end m.elements.VCLinkerTool = function(cfg, toolset) if cfg.kind ~= p.STATICLIB then return { m.linkLibraryDependencies, m.ignoreImportLibrary, m.additionalLinkerOptions, m.additionalDependencies, m.outputFile, m.linkIncremental, m.additionalLibraryDirectories, m.moduleDefinitionFile, m.generateManifest, m.generateDebugInformation, m.programDatabaseFile, m.subSystem, m.largeAddressAware, m.optimizeReferences, m.enableCOMDATFolding, m.entryPointSymbol, m.importLibrary, m.targetMachine, } else return { m.additionalLinkerOptions, m.additionalDependencies, m.outputFile, m.additionalLibraryDirectories, } end end function m.VCLinkerToolName(cfg) if cfg.kind == p.STATICLIB then return "VCLibrarianTool" elseif cfg.system == p.XBOX360 then return "VCX360LinkerTool" else return "VCLinkerTool" end end function m.VCLinkerTool(cfg, toolset) m.VCTool("VCLinkerTool", cfg, toolset) end m.elements.VCManagedResourceCompilerTool = function(cfg) return {} end function m.VCManagedResourceCompilerTool(cfg) m.VCTool("VCManagedResourceCompilerTool", cfg) end m.elements.VCManifestTool = function(cfg) return { m.additionalManifestFiles, } end function m.VCManifestTool(cfg) if cfg.kind ~= p.STATICLIB then m.VCTool("VCManifestTool", cfg) end end m.elements.VCMIDLTool = function(cfg) return { m.targetEnvironment } end function m.VCMIDLTool(cfg) m.VCTool("VCMIDLTool", cfg) end m.elements.VCNMakeTool = function(cfg) return { m.buildCommandLine, m.reBuildCommandLine, m.cleanCommandLine, m.output, m.preprocessorDefinitions, m.undefinePreprocessorDefinitions, m.includeSearchPath, m.forcedIncludes, m.assemblySearchPath, m.forcedUsingAssemblies, m.compileAsManaged, } end function m.VCNMakeTool(cfg) m.VCTool("VCNMakeTool", cfg) end m.elements.VCBuildTool = function(cfg, stage) return { m.commandLine, } end function m.VCBuildToolName(cfg, stage) return "VC" .. stage .. "EventTool" end function m.VCPreBuildEventTool(cfg) m.VCTool("VCBuildTool", cfg, "PreBuild") end function m.VCPreLinkEventTool(cfg) m.VCTool("VCBuildTool", cfg, "PreLink") end function m.VCPostBuildEventTool(cfg) m.VCTool("VCBuildTool", cfg, "PostBuild") end m.elements.VCResourceCompilerTool = function(cfg) return { m.additionalResourceOptions, m.resourcePreprocessorDefinitions, m.additionalResourceIncludeDirectories, m.culture, } end function m.VCResourceCompilerTool(cfg) m.VCTool("VCResourceCompilerTool", cfg) end m.elements.VCWebServiceProxyGeneratorTool = function(cfg) return {} end function m.VCWebServiceProxyGeneratorTool(cfg) m.VCTool("VCWebServiceProxyGeneratorTool", cfg) end m.elements.VCX360DeploymentTool = function(cfg) return { m.deploymentType, m.additionalDeploymentOptions, } end function m.VCX360DeploymentTool(cfg) m.VCTool("VCX360DeploymentTool", cfg) end m.elements.VCX360ImageTool = function(cfg) return { m.additionalImageOptions, m.outputFileName, } end function m.VCX360ImageTool(cfg) m.VCTool("VCX360ImageTool", cfg) end m.elements.VCXDCMakeTool = function(cfg) return {} end function m.VCXDCMakeTool(cfg) m.VCTool("VCXDCMakeTool", cfg) end m.elements.VCXMLDataGeneratorTool = function(cfg) return {} end function m.VCXMLDataGeneratorTool(cfg) m.VCTool("VCXMLDataGeneratorTool", cfg) end function m.symbols(cfg) if not cfg.flags.Symbols then return 0 elseif cfg.debugformat == "c7" then return 1 else if cfg.editandcontinue == p.OFF or config.isOptimizedBuild(cfg) or cfg.clr ~= p.OFF or cfg.architecture == p.X86_64 then return 3 else return 4 end end end function m.additionalCompilerOptions(cfg) local opts = cfg.buildoptions if cfg.flags.MultiProcessorCompile then table.insert(opts, "/MP") end if #opts > 0 then p.x('AdditionalOptions="%s"', table.concat(opts, " ")) end end function m.additionalDependencies(cfg, toolset) if #cfg.links == 0 then return end local ex = vstudio.needsExplicitLink(cfg) local links if not toolset then links = vstudio.getLinks(cfg, ex) for i, link in ipairs(links) do if link:find(" ", 1, true) then link = '"' .. link .. '"' end links[i] = path.translate(link) end else links = toolset.getlinks(cfg, not ex) end if #links > 0 then p.x('AdditionalDependencies="%s"', table.concat(links, " ")) end end function m.additionalDeploymentOptions(cfg) if #cfg.deploymentoptions > 0 then p.x('AdditionalOptions="%s"', table.concat(cfg.deploymentoptions, " ")) end end function m.additionalExternalCompilerOptions(cfg, toolset) local buildoptions = table.join(toolset.getcflags(cfg), toolset.getcxxflags(cfg), cfg.buildoptions) if not cfg.flags.NoPCH and cfg.pchheader then table.insert(buildoptions, '--use_pch="$(IntDir)/$(TargetName).pch"') end if #buildoptions > 0 then p.x('AdditionalOptions="%s"', table.concat(buildoptions, " ")) end end function m.additionalImageOptions(cfg) if #cfg.imageoptions > 0 then p.x('AdditionalOptions="%s"', table.concat(cfg.imageoptions, " ")) end end function m.additionalIncludeDirectories(cfg) if #cfg.includedirs > 0 then local dirs = vstudio.path(cfg, cfg.includedirs) p.x('AdditionalIncludeDirectories="%s"', table.concat(dirs, ";")) end end function m.additionalLibraryDirectories(cfg) if #cfg.libdirs > 0 then local dirs = vstudio.path(cfg, cfg.libdirs) p.x('AdditionalLibraryDirectories="%s"', table.concat(dirs, ";")) end end function m.additionalLinkerOptions(cfg, toolset) local flags if toolset then flags = table.join(toolset.getldflags(cfg), cfg.linkoptions) else flags = cfg.linkoptions end if #flags > 0 then p.x('AdditionalOptions="%s"', table.concat(flags, " ")) end end function m.additionalManifestFiles(cfg) local manifests = {} for i, fname in ipairs(cfg.files) do if path.getextension(fname) == ".manifest" then table.insert(manifests, project.getrelative(cfg.project, fname)) end end if #manifests > 0 then p.x('AdditionalManifestFiles="%s"', table.concat(manifests, ";")) end end function m.additionalResourceIncludeDirectories(cfg) local dirs = table.join(cfg.includedirs, cfg.resincludedirs) if #dirs > 0 then dirs = vstudio.path(cfg, dirs) p.x('AdditionalIncludeDirectories="%s"', table.concat(dirs, ";")) end end function m.additionalResourceOptions(cfg) if #cfg.resoptions > 0 then p.x('AdditionalOptions="%s"', table.concat(cfg.resoptions, " ")) end end function m.assemblyReferences(prj) local cfg = project.getfirstconfig(prj) local refs = config.getlinks(cfg, "system", "fullpath", "managed") table.foreachi(refs, function(value) p.push('') end) end function m.assemblySearchPath(cfg) p.w('AssemblySearchPath=""') end function m.basicRuntimeChecks(cfg) local cfg, filecfg = config.normalize(cfg) if not filecfg and not config.isOptimizedBuild(cfg) and cfg.clr == p.OFF and not cfg.flags.NoRuntimeChecks then p.w('BasicRuntimeChecks="3"') end end function m.bufferSecurityCheck(cfg) if cfg.flags.NoBufferSecurityCheck then p.w('BufferSecurityCheck="false"') end end function m.buildCommandLine(cfg) local cmds = os.translateCommands(cfg.buildcommands, p.WINDOWS) p.x('BuildCommandLine="%s"', table.concat(cmds, "\r\n")) end function m.characterSet(cfg) if not vstudio.isMakefile(cfg) then p.w('CharacterSet="%s"', iif(cfg.characterset == p.MBCS, 2, 1)) end end function m.cleanCommandLine(cfg) local cmds = os.translateCommands(cfg.cleancommands, p.WINDOWS) cmds = table.concat(cmds, "\r\n") p.x('CleanCommandLine="%s"', cmds) end function m.commandLine(cfg, stage) local field = stage:lower() local steps = cfg[field .. "commands"] local msg = cfg[field .. "message"] if #steps > 0 then if msg then p.x('Description="%s"', msg) end steps = os.translateCommands(steps, p.WINDOWS) p.x('CommandLine="%s"', table.implode(steps, "", "", "\r\n")) end end function m.compileAs(cfg, toolset) local cfg, filecfg = config.normalize(cfg) local c = project.isc(cfg) if filecfg then if path.iscfile(filecfg.name) ~= c then if path.iscppfile(filecfg.name) then local value = iif(c, 2, 1) p.w('CompileAs="%s"', value) end end else local compileAs if toolset then compileAs = "0" elseif c then compileAs = "1" end if compileAs then p.w('CompileAs="%s"', compileAs) end end end function m.disableSpecificWarnings(cfg) if #cfg.disablewarnings > 0 then p.x('DisableSpecificWarnings="%s"', table.concat(cfg.disablewarnings, ";")) end end function m.compileAsManaged(cfg) p.w('CompileAsManaged=""') end function m.configurationType(cfg) local cfgtypes = { Makefile = 0, None = 0, SharedLib = 2, StaticLib = 4, } p.w('ConfigurationType="%s"', cfgtypes[cfg.kind] or 1) end function m.culture(cfg) local value = vstudio.cultureForLocale(cfg.locale) if value then p.w('Culture="%d"', value) end end function m.customBuildTool(cfg) local cfg, filecfg = config.normalize(cfg) if filecfg and fileconfig.hasCustomBuildRule(filecfg) then local cmds = os.translateCommands(filecfg.buildcommands, p.WINDOWS) p.x('CommandLine="%s"', table.concat(cmds,'\r\n')) local outputs = project.getrelative(filecfg.project, filecfg.buildoutputs) p.x('Outputs="%s"', table.concat(outputs, ';')) if filecfg.buildinputs and #filecfg.buildinputs > 0 then local inputs = project.getrelative(filecfg.project, filecfg.buildinputs) p.x('AdditionalDependencies="%s"', table.concat(inputs, ';')) end end end function m.debugInformationFormat(cfg, toolset) local prjcfg, filecfg = config.normalize(cfg) if not filecfg then local fmt = iif(toolset, "0", m.symbols(cfg)) p.w('DebugInformationFormat="%s"', fmt) end end function m.deploymentType(cfg) p.w('DeploymentType="0"') end function m.detect64BitPortabilityProblems(cfg) local prjcfg, filecfg = config.normalize(cfg) if _ACTION < "vs2008" and cfg.clr == p.OFF and cfg.warnings ~= p.OFF and not filecfg then p.w('Detect64BitPortabilityProblems="%s"', tostring(not cfg.flags.No64BitChecks)) end end function m.enableCOMDATFolding(cfg, toolset) if config.isOptimizedBuild(cfg) and not toolset then p.w('EnableCOMDATFolding="2"') end end function m.largeAddressAware(cfg) if (cfg.largeaddressaware == true) then p.w('LargeAddressAware="2"') end end function m.enableEnhancedInstructionSet(cfg) local map = { SSE = "1", SSE2 = "2" } local value = map[cfg.vectorextensions] if value and cfg.system ~= "Xbox360" and cfg.architecture ~= "x86_64" then p.w('EnableEnhancedInstructionSet="%d"', value) end end function m.enableFunctionLevelLinking(cfg) local cfg, filecfg = config.normalize(cfg) if not filecfg then p.w('EnableFunctionLevelLinking="true"') end end function m.entryPointSymbol(cfg, toolset) if (cfg.kind == "ConsoleApp" or cfg.kind == "WindowedApp") and not cfg.flags.WinMain and not toolset then p.w('EntryPointSymbol="mainCRTStartup"') end end function m.exceptionHandling(cfg) if cfg.exceptionhandling == p.OFF then p.w('ExceptionHandling="%s"', iif(_ACTION < "vs2005", "FALSE", 0)) elseif cfg.exceptionhandling == "SEH" and _ACTION > "vs2003" then p.w('ExceptionHandling="2"') end end function m.excludedFromBuild(filecfg) if not filecfg or filecfg.flags.ExcludeFromBuild then p.w('ExcludedFromBuild="true"') end end function m.floatingPointModel(cfg) local map = { Strict = "1", Fast = "2" } local value = map[cfg.floatingpoint] if value then p.w('FloatingPointModel="%d"', value) end end function m.forcedIncludeFiles(cfg) if #cfg.forceincludes > 0 then local includes = vstudio.path(cfg, cfg.forceincludes) p.w('ForcedIncludeFiles="%s"', table.concat(includes, ';')) end if #cfg.forceusings > 0 then local usings = vstudio.path(cfg, cfg.forceusings) p.w('ForcedUsingFiles="%s"', table.concat(usings, ';')) end end function m.forcedIncludes(cfg) p.w('ForcedIncludes=""') end function m.forcedUsingAssemblies(cfg) p.w('ForcedUsingAssemblies=""') end function m.keyword(prj) local windows, managed, makefile for cfg in project.eachconfig(prj) do if cfg.system == p.WINDOWS then windows = true end if cfg.clr ~= p.OFF then managed = true end if vstudio.isMakefile(cfg) then makefile = true end end if windows then local keyword = "Win32Proj" if managed then keyword = "ManagedCProj" end if makefile then keyword = "MakeFileProj" end p.w('Keyword="%s"', keyword) end end function m.generateDebugInformation(cfg, toolset) if not toolset then p.w('GenerateDebugInformation="%s"', tostring(m.symbols(cfg) ~= 0)) end end function m.generateManifest(cfg, toolset) if cfg.flags.NoManifest or toolset then p.w('GenerateManifest="false"') end end function m.ignoreImportLibrary(cfg, toolset) if cfg.flags.NoImportLib and not toolset then p.w('IgnoreImportLibrary="true"') end end function m.importLibrary(cfg, toolset) if cfg.kind == p.SHAREDLIB and not toolset then local implibdir = cfg.linktarget.abspath if cfg.flags.NoImportLib then implibdir = path.join(cfg.objdir, path.getname(implibdir)) end implibdir = vstudio.path(cfg, implibdir) p.x('ImportLibrary="%s"', implibdir) end end function m.includeSearchPath(cfg) p.w('IncludeSearchPath=""') end function m.intermediateDirectory(cfg) local objdir if not cfg.fake then objdir = vstudio.path(cfg, cfg.objdir) else objdir = "$(PlatformName)\\$(ConfigurationName)" end p.x('IntermediateDirectory="%s"', objdir) end function m.linkIncremental(cfg, toolset) local value if not toolset then value = iif(config.canLinkIncremental(cfg) , 2, 1) else value = 0 end p.w('LinkIncremental="%s"', value) end function m.linkLibraryDependencies(cfg, toolset) if vstudio.needsExplicitLink(cfg) and not toolset then p.w('LinkLibraryDependencies="false"') end end function m.managedExtensions(cfg) if cfg.clr ~= p.OFF then p.w('ManagedExtensions="1"') end end function m.minimalRebuild(cfg) if config.isDebugBuild(cfg) and cfg.debugformat ~= "c7" and not cfg.flags.NoMinimalRebuild and cfg.clr == p.OFF and not cfg.flags.MultiProcessorCompile then p.w('MinimalRebuild="true"') end end function m.moduleDefinitionFile(cfg, toolset) if not toolset then local deffile = config.findfile(cfg, ".def") if deffile then p.w('ModuleDefinitionFile="%s"', deffile) end end end function m.objectFile(cfg) local cfg, filecfg = config.normalize(cfg) if filecfg and path.iscppfile(filecfg.name) then if filecfg.objname ~= path.getbasename(filecfg.abspath) then p.x('ObjectFile="$(IntDir)\\%s.obj"', filecfg.objname) end end end function m.omitDefaultLib(cfg) if cfg.flags.OmitDefaultLibrary then p.w('OmitDefaultLibName="true"') end end function m.omitFramePointers(cfg) if cfg.flags.NoFramePointer then p.w('OmitFramePointers="true"') end end function m.optimization(cfg) local map = { Off=0, On=3, Debug=0, Full=3, Size=1, Speed=2 } local value = map[cfg.optimize] if value or not cfg.abspath then p.w('Optimization="%s"', value or 0) end end function m.optimizeReferences(cfg, toolset) if config.isOptimizedBuild(cfg) and not toolset then p.w('OptimizeReferences="2"') end end function m.output(cfg) p.w('Output="$(OutDir)%s"', cfg.buildtarget.name) end function m.outputDirectory(cfg) local outdir = project.getrelative(cfg.project, cfg.buildtarget.directory) p.x('OutputDirectory="%s"', path.translate(outdir)) end function m.outputFile(cfg) p.x('OutputFile="$(OutDir)\\%s"', cfg.buildtarget.name) end function m.outputFileName(cfg) if cfg.imagepath ~= nil then p.x('OutputFileName="%s"', path.translate(cfg.imagepath)) end end function m.platforms(prj) architectures = {} for cfg in project.eachconfig(prj) do local arch = vstudio.archFromConfig(cfg, true) if not table.contains(architectures, arch) then table.insert(architectures, arch) end end p.push('') table.foreachi(architectures, function(arch) p.push('') end) p.pop('') end function m.preprocessorDefinitions(cfg) if #cfg.defines > 0 or vstudio.isMakefile(cfg) then p.x('PreprocessorDefinitions="%s"', table.concat(cfg.defines, ";")) end end function m.undefinePreprocessorDefinitions(cfg) if #cfg.undefines > 0 then p.x('UndefinePreprocessorDefinitions="%s"', table.concat(cfg.undefines, ";")) end end function m.programDatabaseFile(cfg, toolset) if toolset then p.w('ProgramDatabaseFile=""') end end function m.programDataBaseFileName(cfg, toolset) if toolset then p.w('ProgramDataBaseFileName=""') end end function m.projectGUID(prj) p.w('ProjectGUID="{%s}"', prj.uuid) end function m.projectName(prj) p.x('Name="%s"', prj.name) end function m.projectReferences(prj) local deps = project.getdependencies(prj) if #deps > 0 then for i, dep in ipairs(deps) do local relpath = vstudio.path(prj.workspace, vstudio.projectfile(dep)) if not relpath:startswith(".") then relpath = ".\\" .. relpath end p.push('') end end end function m.projectType(prj) p.w('ProjectType="Visual C++"') end function m.reBuildCommandLine(cfg) commands = table.concat(cfg.rebuildcommands, "\r\n") p.x('ReBuildCommandLine="%s"', commands) end function m.resourcePreprocessorDefinitions(cfg) local defs = table.join(cfg.defines, cfg.resdefines) if #defs > 0 then p.x('PreprocessorDefinitions="%s"', table.concat(defs, ";")) end end function m.rootNamespace(prj) local hasWindows = project.hasConfig(prj, function(cfg) return cfg.system == p.WINDOWS end) if hasWindows and _ACTION > "vs2003" then p.x('RootNamespace="%s"', prj.name) end end function m.runtimeLibrary(cfg) local cfg, filecfg = config.normalize(cfg) if not filecfg then local runtimes = { StaticRelease = 0, StaticDebug = 1, SharedRelease = 2, SharedDebug = 3, } p.w('RuntimeLibrary="%s"', runtimes[config.getruntime(cfg)]) end end function m.runtimeTypeInfo(cfg) if cfg.rtti == p.OFF and cfg.clr == p.OFF then p.w('RuntimeTypeInfo="false"') elseif cfg.rtti == p.ON then p.w('RuntimeTypeInfo="true"') end end function m.stringPooling(cfg) if config.isOptimizedBuild(cfg) then p.w('StringPooling="true"') end end function m.subSystem(cfg, toolset) if not toolset then p.w('SubSystem="%s"', iif(cfg.kind == "ConsoleApp", 1, 2)) end end function m.targetEnvironment(cfg) if cfg.architecture == "x86_64" then p.w('TargetEnvironment="3"') end end function m.targetFrameworkVersion(prj) local windows, makefile for cfg in project.eachconfig(prj) do if cfg.system == p.WINDOWS then windows = true end if vstudio.isMakefile(cfg) then makefile = true end end local version = 0 if makefile or not windows then version = 196613 end p.w('TargetFrameworkVersion="%d"', version) end function m.targetMachine(cfg, toolset) if not toolset then p.w('TargetMachine="%d"', iif(cfg.architecture == "x86_64", 17, 1)) end end function m.toolFiles(prj) if _ACTION > "vs2003" then p.w('') p.w('') end end function m.treatWChar_tAsBuiltInType(cfg) local map = { On = "true", Off = "false" } local value = map[cfg.nativewchar] if value then p.w('TreatWChar_tAsBuiltInType="%s"', value) end end function m.useOfMFC(cfg) if (cfg.flags.MFC) then p.w('UseOfMFC="%d"', iif(cfg.flags.StaticRuntime, 1, 2)) end end function m.usePrecompiledHeader(cfg) local prj, file = config.normalize(cfg) if file then if prj.pchsource == file.abspath and not prj.flags.NoPCH and prj.system == p.WINDOWS then p.w('UsePrecompiledHeader="1"') end else if not prj.flags.NoPCH and prj.pchheader then p.w('UsePrecompiledHeader="%s"', iif(_ACTION < "vs2005", 3, 2)) p.x('PrecompiledHeaderThrough="%s"', prj.pchheader) else p.w('UsePrecompiledHeader="%s"', iif(_ACTION > "vs2003" or prj.flags.NoPCH, 0, 2)) end end end function m.version(prj) local map = { vs2002 = '7.0', vs2003 = '7.1', vs2005 = '8.0', vs2008 = '9.0' } p.w('Version="%s0"', map[_ACTION]) end function m.warnAsError(cfg) if cfg.flags.FatalCompileWarnings and cfg.warnings ~= p.OFF then p.w('WarnAsError="true"') end end function m.warningLevel(cfg) local prjcfg, filecfg = config.normalize(cfg) local level if cfg.warnings == p.OFF then level = "0" elseif cfg.warnings == "Extra" then level = "4" elseif not filecfg then level = "3" end if level then p.w('WarningLevel="%s"', level) end end function m.wholeProgramOptimization(cfg) if cfg.flags.LinkTimeOptimization then p.x('WholeProgramOptimization="true"') end end function m.xmlElement() p.w('') end local p = premake local m = p.vstudio.vc200x m.elements.user = function(cfg) return { m.debugSettings, } end function m.generateUser(prj) p.indent("\t") local contents = {} local size = 0 for cfg in p.project.eachconfig(prj) do contents[cfg] = p.capture(function() p.push(4) p.callArray(m.elements.user, cfg) p.pop(4) end) size = size + #contents[cfg] end if size > 0 then m.xmlElement() m.visualStudioUserFile() p.push('') for cfg in p.project.eachconfig(prj) do m.userConfiguration(cfg) p.push(' 0 then p.outln(contents[cfg]) end p.pop('/>') p.pop('') end p.pop('') p.pop('') end end function m.visualStudioUserFile() p.push('') end function m.userConfiguration(cfg) p.push('') end m.elements.debugSettings = function(cfg) return { m.debugCommand, m.debugDir, m.debugArgs, m.debugEnvironment, } end function m.debugSettings(cfg) p.callArray(m.elements.debugSettings, cfg) end function m.debugArgs(cfg) if #cfg.debugargs > 0 then p.x('CommandArguments="%s"', table.concat(cfg.debugargs, " ")) end end function m.debugCommand(cfg) if cfg.debugcommand then p.x('Command="%s"', p.vstudio.path(cfg, cfg.debugcommand)) end end function m.debugDir(cfg) if cfg.debugdir then p.x('WorkingDirectory="%s"', p.vstudio.path(cfg, cfg.debugdir)) end end function m.debugEnvironment(cfg) if #cfg.debugenvs > 0 then p.x('Environment="%s"', table.concat(cfg.debugenvs, "\n")) if cfg.flags.DebugEnvsDontMerge then p.x('EnvironmentMerge="false"') end end end premake.vstudio.sln2005 = {} local p = premake local vstudio = p.vstudio local sln2005 = p.vstudio.sln2005 local project = p.project local tree = p.tree sln2005.elements = {} function sln2005.solutionSections(wks) return { "ConfigurationPlatforms", "SolutionProperties", "NestedProjects", "ExtensibilityGlobals" } end function sln2005.generate(wks) premake.utf8() premake.outln('') sln2005.reorderProjects(wks) sln2005.header() sln2005.projects(wks) p.push('Global') sln2005.sections(wks) p.pop('EndGlobal') p.w() end function sln2005.header() local action = premake.action.current() p.w('Microsoft Visual Studio Solution File, Format Version %d.00', action.vstudio.solutionVersion) p.w('# Visual Studio %s', action.vstudio.versionName) end function sln2005.reorderProjects(wks) if wks.startproject then local np local tr = p.workspace.grouptree(wks) tree.traverse(tr, { onleaf = function(n) if n.project.name == wks.startproject then np = n end end }) while np and np.parent do local p = np.parent local i = table.indexof(p.children, np) table.remove(p.children, i) table.insert(p.children, 1, np) np = p end end end function sln2005.projects(wks) local tr = p.workspace.grouptree(wks) tree.traverse(tr, { onleaf = function(n) local prj = n.project local prjpath = vstudio.projectfile(prj) prjpath = vstudio.path(prj.workspace, prjpath) prjpath = prjpath:gsub("$%((.-)%)", "%%%1%%") p.x('Project("{%s}") = "%s", "%s", "{%s}"', vstudio.tool(prj), prj.name, prjpath, prj.uuid) p.push() sln2005.projectdependencies(prj) p.pop('EndProject') end, onbranch = function(n) p.push('Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "%s", "%s", "{%s}"', n.name, n.name, n.uuid) p.pop('EndProject') end, }) end function sln2005.projectdependencies(prj) local deps = project.getdependencies(prj, 'dependOnly') if #deps > 0 then p.push('ProjectSection(ProjectDependencies) = postProject') for _, dep in ipairs(deps) do p.w('{%s} = {%s}', dep.uuid, dep.uuid) end p.pop('EndProjectSection') end end sln2005.elements.projectConfigurationPlatforms = function(cfg, context) return { sln2005.activeCfg, sln2005.build0, } end function sln2005.projectConfigurationPlatforms(wks, sorted, descriptors) p.w("GlobalSection(ProjectConfigurationPlatforms) = postSolution") local tr = p.workspace.grouptree(wks) tree.traverse(tr, { onleaf = function(n) local prj = n.project table.foreachi(sorted, function(cfg) local context = {} context.prj = prj context.prjCfg = project.getconfig(prj, cfg.buildcfg, cfg.platform) context.excluded = (context.prjCfg == nil or context.prjCfg.flags.ExcludeFromBuild) if context.prjCfg == nil then context.prjCfg = project.findClosestMatch(prj, cfg.buildcfg, cfg.platform) end context.descriptor = descriptors[cfg] context.platform = vstudio.projectPlatform(context.prjCfg) context.architecture = vstudio.archFromConfig(context.prjCfg, true) p.push() p.callArray(sln2005.elements.projectConfigurationPlatforms, cfg, context) p.pop() end) end }) p.w("EndGlobalSection") end function sln2005.activeCfg(cfg, context) p.w('{%s}.%s.ActiveCfg = %s|%s', context.prj.uuid, context.descriptor, context.platform, context.architecture) end function sln2005.build0(cfg, context) if not context.excluded and context.prjCfg.kind ~= premake.NONE then p.w('{%s}.%s.Build.0 = %s|%s', context.prj.uuid, context.descriptor, context.platform, context.architecture) end end function sln2005.configurationPlatforms(wks) local descriptors = {} local sorted = {} for cfg in p.workspace.eachconfig(wks) do local platform = vstudio.solutionPlatform(cfg) descriptors[cfg] = string.format("%s|%s", cfg.buildcfg, platform) table.insert(sorted, cfg) end table.sort(sorted, function(cfg0, cfg1) return descriptors[cfg0]:lower() < descriptors[cfg1]:lower() end) if wks.defaultplatform then p.push('GlobalSection(SolutionConfigurationPlatforms) = preSolution') table.foreachi(sorted, function (cfg) if cfg.platform == wks.defaultplatform then p.w('%s = %s', descriptors[cfg], descriptors[cfg]) end end) p.pop("EndGlobalSection") end p.push('GlobalSection(SolutionConfigurationPlatforms) = preSolution') table.foreachi(sorted, function (cfg) if not wks.defaultplatform or cfg.platform ~= wks.defaultplatform then p.w('%s = %s', descriptors[cfg], descriptors[cfg]) end end) p.pop("EndGlobalSection") sln2005.projectConfigurationPlatforms(wks, sorted, descriptors) end function sln2005.properties(wks) p.push('GlobalSection(SolutionProperties) = preSolution') p.w('HideSolutionNode = FALSE') p.pop('EndGlobalSection') end function sln2005.nestedProjects(wks) local tr = p.workspace.grouptree(wks) if tree.hasbranches(tr) then p.push('GlobalSection(NestedProjects) = preSolution') tree.traverse(tr, { onnode = function(n) if n.parent.uuid then p.w('{%s} = {%s}', (n.project or n).uuid, n.parent.uuid) end end }) p.pop('EndGlobalSection') end end function sln2005.premakeExtensibilityGlobals(wks) if wks.editorintegration then local args = {} for _, arg in ipairs(_ARGV) do if not (arg:startswith("--file") or arg:startswith("/file")) then table.insert(args, arg); end end p.w('PremakeBinary = %s', _PREMAKE_COMMAND) p.w('PremakeScript = %s', p.workspace.getrelative(wks, _MAIN_SCRIPT)) p.w('PremakeArguments = %s', table.concat(args, ' ')) end end sln2005.elements.extensibilityGlobals = function(wks) return { sln2005.premakeExtensibilityGlobals, } end function sln2005.extensibilityGlobals(wks) local contents = p.capture(function () p.push() p.callArray(sln2005.elements.extensibilityGlobals, wks) p.pop() end) if #contents > 0 then p.push('GlobalSection(ExtensibilityGlobals) = postSolution') p.outln(contents) p.pop('EndGlobalSection') end end sln2005.elements.sections = function(wks) return { sln2005.configurationPlatforms, sln2005.properties, sln2005.nestedProjects, sln2005.extensibilityGlobals, } end function sln2005.sections(wks) p.callArray(sln2005.elements.sections, wks) end premake.vstudio.cs2005 = {} local p = premake local vstudio = p.vstudio local cs2005 = p.vstudio.cs2005 local project = p.project local config = p.config local fileconfig = p.fileconfig local dotnet = p.tools.dotnet cs2005.elements = {} cs2005.elements.project = { "xmlDeclaration", "projectElement", "commonProperties", "projectProperties", "configurations", "applicationIcon", "assemblyReferences", } function cs2005.generate(prj) p.utf8() premake.callarray(cs2005, cs2005.elements.project, prj) _p(1,'') cs2005.files(prj) _p(1,'') cs2005.projectReferences(prj) cs2005.targets(prj) cs2005.buildEvents(prj) p.out('') end function cs2005.projectElement(prj) local ver = '' local action = premake.action.current() if action.vstudio.toolsVersion then ver = string.format(' ToolsVersion="%s"', action.vstudio.toolsVersion) end _p('', ver) end cs2005.elements.projectProperties = { "configurationCondition", "platformCondition", "productVersion", "schemaVersion", "projectGuid", "outputType", "appDesignerFolder", "rootNamespace", "assemblyName", "targetFrameworkVersion", "targetFrameworkProfile", "fileAlignment", "projectTypeGuids", } function cs2005.projectProperties(prj) _p(1,'') local cfg = project.getfirstconfig(prj) premake.callarray(cs2005, cs2005.elements.projectProperties, cfg) _p(1,'') end cs2005.elements.configuration = { "propertyGroup", "debugProps", "outputProps", "compilerProps", } function cs2005.configurations(prj) for cfg in project.eachconfig(prj) do cs2005.configuration(cfg) end end function cs2005.configuration(cfg) premake.callarray(cs2005, cs2005.elements.configuration, cfg) _p(1,'') end function cs2005.files(prj) local cfg = project.getfirstconfig(prj) local elements = { "AutoGen", "CopyToOutputDirectory", "DesignTime", "DependentUpon", "DesignTimeSharedInput", "Generator", "LastGenOutput", "SubType", } local tr = project.getsourcetree(prj) premake.tree.traverse(tr, { onleaf = function(node, depth) local filecfg = fileconfig.getconfig(node, cfg) local fname = path.translate(node.relpath) local link, count = node.relpath:gsub("%.%.%/", "") local external = (count > 0) if external and node.vpath ~= node.relpath then link = node.vpath end local info = dotnet.fileinfo(filecfg) local contents = premake.capture(function () for _, el in ipairs(elements) do local value = info[el] if value then _p(3,"<%s>%s", el, value, el) end end end) if #contents > 0 or external then _p(2,'<%s Include="%s">', info.action, fname) if external then _p(3,'%s', path.translate(link)) end if #contents > 0 then _p("%s", contents) end if info.action == "EmbeddedResource" and cfg.customtoolnamespace then _p(3,"%s", cfg.customtoolnamespace) end _p(2,'', info.action) else _p(2,'<%s Include="%s" />', info.action, fname) end end }, false) end function cs2005.buildEvents(prj) local function output(name, steps) if #steps > 0 then steps = os.translateCommands(steps, p.WINDOWS) steps = table.implode(steps, "", "", "\r\n") _x(2,'<%sBuildEvent>%s', name, steps, name) end end local cfg = project.getfirstconfig(prj) if #cfg.prebuildcommands > 0 or #cfg.postbuildcommands > 0 then _p(1,'') output("Pre", cfg.prebuildcommands) output("Post", cfg.postbuildcommands) _p(1,'') end end function cs2005.compilerProps(cfg) _x(2,'%s', table.concat(cfg.defines, ";")) _p(2,'prompt') _p(2,'4') if cfg.clr == "Unsafe" then _p(2,'true') end if cfg.flags.FatalCompileWarnings then _p(2,'true') end cs2005.debugCommandParameters(cfg) end function cs2005.debugCommandParameters(cfg) if #cfg.debugargs > 0 then _x(2,'%s', table.concat(cfg.debugargs, " ")) end end function cs2005.debugProps(cfg) if cfg.flags.Symbols then _p(2,'true') _p(2,'full') else _p(2,'pdbonly') end _p(2,'%s', iif(config.isOptimizedBuild(cfg), "true", "false")) end function cs2005.outputProps(cfg) local outdir = vstudio.path(cfg, cfg.buildtarget.directory) _x(2,'%s\\', outdir) local objdir = vstudio.path(cfg, cfg.objdir) if _ACTION > "vs2008" then _x(2,'%s\\', objdir) _p(2,'$(BaseIntermediateOutputPath)') else _x(2,'%s\\', objdir) end end function cs2005.assemblyReferences(prj) _p(1,'') local cfg = project.getfirstconfig(prj) config.getlinks(cfg, "system", function(original, decorated) local name = path.getname(decorated) if path.getextension(name) == ".dll" then name = name.sub(name, 1, -5) end if decorated:find("/", nil, true) then _x(2,'', name) _x(3,'%s', path.appendextension(path.translate(decorated), ".dll")) if not config.isCopyLocal(prj, original, true) then _p(3,"False") end _p(2,'') else _x(2,'', name) end end) _p(1,'') end function cs2005.projectReferences(prj) _p(1,'') local deps = project.getdependencies(prj, 'linkOnly') if #deps > 0 then for _, dep in ipairs(deps) do local relpath = vstudio.path(prj, vstudio.projectfile(dep)) _x(2,'', relpath) _p(3,'{%s}', dep.uuid) _x(3,'%s', dep.name) if not config.isCopyLocal(prj, dep.name, true) then _p(3,"False") end _p(2,'') end end _p(1,'') end function cs2005.arch(cfg) local arch = vstudio.archFromConfig(cfg) if arch == "Any CPU" then arch = "AnyCPU" end return arch end function cs2005.propertyGroup(cfg) local platform = vstudio.projectPlatform(cfg) local arch = cs2005.arch(cfg) p.push('', platform, arch) if arch ~= "AnyCPU" or _ACTION > "vs2008" then p.x('%s', arch) end end function cs2005.applicationIcon(prj) if prj.icon then local icon = vstudio.path(prj, prj.icon) _p(1,'') _x(2,'%s', icon) _p(1,'') end end function cs2005.condition(cfg) return string.format('Condition="\'$(Configuration)|$(Platform)\'==\'%s\'"', premake.esc(vstudio.projectConfig(cfg))) end function cs2005.appDesignerFolder(cfg) _p(2,'Properties') end function cs2005.assemblyName(cfg) _p(2,'%s', cfg.buildtarget.basename) end function cs2005.commonProperties(prj) if _ACTION > "vs2010" then _p(1,'') end end function cs2005.configurationCondition(cfg) _x(2,'%s', cfg.buildcfg) end function cs2005.fileAlignment(cfg) if _ACTION >= "vs2010" then _p(2,'512') end end function cs2005.outputType(cfg) _p(2,'%s', dotnet.getkind(cfg)) end function cs2005.platformCondition(cfg) _p(2,'%s', cs2005.arch(cfg.project)) end function cs2005.productVersion(cfg) local action = premake.action.current() if action.vstudio.productVersion then _p(2,'%s', action.vstudio.productVersion) end end function cs2005.projectGuid(cfg) _p(2,'{%s}', cfg.uuid) end function cs2005.projectTypeGuids(cfg) if cfg.flags.WPF then _p(2,'{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') end end function cs2005.rootNamespace(cfg) _p(2,'%s', cfg.namespace or cfg.buildtarget.basename) end function cs2005.schemaVersion(cfg) local action = premake.action.current() if action.vstudio.csprojSchemaVersion then _p(2,'%s', action.vstudio.csprojSchemaVersion) end end function cs2005.targetFrameworkVersion(cfg) local action = premake.action.current() local framework = cfg.dotnetframework or action.vstudio.targetFramework if framework then _p(2,'v%s', framework) end end function cs2005.targetFrameworkProfile(cfg) if _ACTION == "vs2010" then _p(2,'') _p(2,'') end end function cs2005.targets(prj) local bin = iif(_ACTION <= "vs2010", "MSBuildBinPath", "MSBuildToolsPath") _p(1,'', bin) _p(1,'') end function cs2005.xmlDeclaration() if _ACTION > "vs2008" then p.xmlUtf8() end end local p = premake local m = p.vstudio.cs2005 m.elements.userProjectPropertyGroup = function() return { m.referencePath, } end m.elements.userConfigPropertyGroup = function() return { m.localDebuggerCommandArguments, } end function m.generateUser(prj) local prjGroup = p.capture(function() p.push(2) p.callArray(m.elements.userProjectPropertyGroup, prj) p.pop(2) end) local contents = {} local size = 0 for cfg in p.project.eachconfig(prj) do contents[cfg] = p.capture(function() p.push(2) p.callArray(m.elements.userConfigPropertyGroup, cfg) p.pop(2) end) size = size + #contents[cfg] end if #prjGroup > 0 or size > 0 then p.vstudio.projectElement() if #prjGroup > 0 then p.push('') p.outln(prjGroup) p.pop('') end for cfg in p.project.eachconfig(prj) do if #contents[cfg] > 0 then p.push('', m.condition(cfg)) p.outln(contents[cfg]) p.pop('') end end p.pop('') end end function m.referencePath(prj) local cfg = p.project.getfirstconfig(prj) local paths = p.vstudio.path(prj, cfg.libdirs) if #paths > 0 then p.w('%s', table.concat(paths, ";")) end end function m.localDebuggerCommandArguments(cfg) if #cfg.debugargs > 0 then p.x('%s', table.concat(cfg.debugargs, " ")) end endpremake.vstudio.vs2010 = {} local p = premake local vs2010 = p.vstudio.vs2010 local vstudio = p.vstudio local project = p.project local tree = p.tree vstudio.pathVars = { ["cfg.objdir"] = { absolute = true, token = "$(IntDir)" }, ["prj.location"] = { absolute = true, token = "$(ProjectDir)" }, ["prj.name"] = { absolute = false, token = "$(ProjectName)" }, ["sln.location"] = { absolute = true, token = "$(SolutionDir)" }, ["sln.name"] = { absolute = false, token = "$(SolutionName)" }, ["wks.location"] = { absolute = true, token = "$(SolutionDir)" }, ["wks.name"] = { absolute = false, token = "$(SolutionName)" }, ["cfg.buildtarget.directory"] = { absolute = false, token = "$(TargetDir)" }, ["cfg.buildtarget.name"] = { absolute = false, token = "$(TargetFileName)" }, ["cfg.buildtarget.basename"] = { absolute = false, token = "$(TargetName)" }, ["file.basename"] = { absolute = false, token = "%(Filename)" }, ["file.abspath"] = { absolute = true, token = "%(FullPath)" }, ["file.relpath"] = { absolute = false, token = "%(Identity)" }, } function vs2010.generateProject(prj) p.eol("\r\n") p.indent(" ") p.escaper(vs2010.esc) if premake.project.isdotnet(prj) then premake.generate(prj, ".csproj", vstudio.cs2005.generate) local user = p.capture(function() vstudio.cs2005.generateUser(prj) end) if #user > 0 then p.generate(prj, ".csproj.user", function() p.outln(user) end) end elseif premake.project.iscpp(prj) then premake.generate(prj, ".vcxproj", vstudio.vc2010.generate) local user = p.capture(function() vstudio.vc2010.generateUser(prj) end) if #user > 0 then p.generate(prj, ".vcxproj.user", function() p.outln(user) end) end if tree.hasbranches(project.getsourcetree(prj)) then premake.generate(prj, ".vcxproj.filters", vstudio.vc2010.generateFilters) end end end function vs2010.generateRule(rule) p.eol("\r\n") p.indent(" ") p.escaper(vs2010.esc) p.generate(rule, ".props", vs2010.rules.props.generate) p.generate(rule, ".targets", vs2010.rules.targets.generate) p.generate(rule, ".xml", vs2010.rules.xml.generate) end function vs2010.esc(value) value = value:gsub('&', "&") value = value:gsub('<', "<") value = value:gsub('>', ">") return value end newaction { trigger = "vs2010", shortname = "Visual Studio 2010", description = "Generate Visual Studio 2010 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Makefile", "None", "Utility" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onWorkspace = function(wks) vstudio.vs2005.generateSolution(wks) end, onProject = function(prj) vstudio.vs2010.generateProject(prj) end, onRule = function(rule) vstudio.vs2010.generateRule(rule) end, onCleanWorkspace = function(wks) vstudio.cleanSolution(wks) end, onCleanProject = function(prj) vstudio.cleanProject(prj) end, onCleanTarget = function(prj) vstudio.cleanTarget(prj) end, pathVars = vstudio.pathVars, vstudio = { csprojSchemaVersion = "2.0", productVersion = "8.0.30703", solutionVersion = "11", versionName = "2010", targetFramework = "4.0", toolsVersion = "4.0", } } premake.vstudio.vc2010 = {} local p = premake local vstudio = p.vstudio local project = p.project local config = p.config local fileconfig = p.fileconfig local tree = p.tree local m = p.vstudio.vc2010 m.elements = {} m.elements.project = function(prj) return { m.xmlDeclaration, m.project, m.projectConfigurations, m.globals, m.importDefaultProps, m.configurationPropertiesGroup, m.importLanguageSettings, m.importExtensionSettings, m.propertySheetGroup, m.userMacros, m.outputPropertiesGroup, m.itemDefinitionGroups, m.assemblyReferences, m.files, m.projectReferences, m.importLanguageTargets, m.importExtensionTargets, } end function m.generate(prj) p.utf8() p.callArray(m.elements.project, prj) p.out('') end function m.project(prj) local action = p.action.current() p.push('', action.vstudio.toolsVersion) end function m.projectConfigurations(prj) local platforms = {} for cfg in project.eachconfig(prj) do local arch = vstudio.archFromConfig(cfg, true) if not table.contains(platforms, arch) then table.insert(platforms, arch) end end local configs = {} p.push('') for cfg in project.eachconfig(prj) do for _, arch in ipairs(platforms) do local prjcfg = vstudio.projectConfig(cfg, arch) if not configs[prjcfg] then configs[prjcfg] = prjcfg p.push('', vstudio.projectConfig(cfg, arch)) p.x('%s', vstudio.projectPlatform(cfg)) p.w('%s', arch) p.pop('') end end end p.pop('') end function m.targetFramework(prj) local action = p.action.current() local tools = string.format(' ToolsVersion="%s"', action.vstudio.toolsVersion) local framework = prj.dotnetframework or action.vstudio.targetFramework or "4.0" p.w('v%s', framework) end m.elements.globals = function(prj) return { m.projectGuid, m.ignoreWarnDuplicateFilename, m.keyword, m.projectName, } end function m.globals(prj) m.propertyGroup(nil, "Globals") p.callArray(m.elements.globals, prj) p.pop('') end m.elements.configurationProperties = function(cfg) if cfg.kind == p.UTILITY then return { m.configurationType, m.platformToolset, } else return { m.configurationType, m.useDebugLibraries, m.useOfMfc, m.useOfAtl, m.clrSupport, m.characterSet, m.platformToolset, m.wholeProgramOptimization, m.nmakeOutDirs, } end end function m.configurationProperties(cfg) m.propertyGroup(cfg, "Configuration") p.callArray(m.elements.configurationProperties, cfg) p.pop('') end function m.configurationPropertiesGroup(prj) for cfg in project.eachconfig(prj) do m.configurationProperties(cfg) end end m.elements.outputProperties = function(cfg) if cfg.kind == p.UTILITY then return { m.outDir, m.intDir, m.extensionsToDeleteOnClean, } else return { m.linkIncremental, m.ignoreImportLibrary, m.outDir, m.outputFile, m.intDir, m.targetName, m.targetExt, m.includePath, m.libraryPath, m.imageXexOutput, m.generateManifest, m.extensionsToDeleteOnClean, m.executablePath, } end end function m.outputProperties(cfg) if not vstudio.isMakefile(cfg) then m.propertyGroup(cfg) p.callArray(m.elements.outputProperties, cfg) p.pop('') end end function m.outputPropertiesGroup(prj) for cfg in project.eachconfig(prj) do m.outputProperties(cfg) m.nmakeProperties(cfg) end end function m.nmakeProperties(cfg) if vstudio.isMakefile(cfg) then m.propertyGroup(cfg) m.nmakeOutput(cfg) m.nmakeCommandLine(cfg, cfg.buildcommands, "Build") m.nmakeCommandLine(cfg, cfg.rebuildcommands, "ReBuild") m.nmakeCommandLine(cfg, cfg.cleancommands, "Clean") p.pop('') end end m.elements.itemDefinitionGroup = function(cfg) if cfg.kind == p.UTILITY then return { m.ruleVars, m.buildEvents, } else return { m.clCompile, m.resourceCompile, m.linker, m.manifest, m.buildEvents, m.imageXex, m.deploy, m.ruleVars, m.buildLog, } end end function m.itemDefinitionGroup(cfg) if not vstudio.isMakefile(cfg) then p.push('', m.condition(cfg)) p.callArray(m.elements.itemDefinitionGroup, cfg) p.pop('') else if cfg == project.getfirstconfig(cfg.project) then p.w('') p.w('') end end end function m.itemDefinitionGroups(prj) for cfg in project.eachconfig(prj) do m.itemDefinitionGroup(cfg) end end m.elements.clCompile = function(cfg) return { m.precompiledHeader, m.warningLevel, m.treatWarningAsError, m.disableSpecificWarnings, m.treatSpecificWarningsAsErrors, m.basicRuntimeChecks, m.clCompilePreprocessorDefinitions, m.clCompileUndefinePreprocessorDefinitions, m.clCompileAdditionalIncludeDirectories, m.clCompileAdditionalUsingDirectories, m.forceIncludes, m.debugInformationFormat, m.programDataBaseFileName, m.optimization, m.functionLevelLinking, m.intrinsicFunctions, m.minimalRebuild, m.omitFramePointers, m.stringPooling, m.runtimeLibrary, m.omitDefaultLib, m.exceptionHandling, m.runtimeTypeInfo, m.bufferSecurityCheck, m.treatWChar_tAsBuiltInType, m.floatingPointModel, m.inlineFunctionExpansion, m.enableEnhancedInstructionSet, m.multiProcessorCompilation, m.additionalCompileOptions, m.compileAs, m.callingConvention, } end function m.clCompile(cfg) p.push('') p.callArray(m.elements.clCompile, cfg) p.pop('') end m.elements.resourceCompile = function(cfg) return { m.resourcePreprocessorDefinitions, m.resourceAdditionalIncludeDirectories, m.culture, } end function m.resourceCompile(cfg) if cfg.system ~= p.XBOX360 and p.config.hasFile(cfg, path.isresourcefile) then local contents = p.capture(function () p.push() p.callArray(m.elements.resourceCompile, cfg) p.pop() end) if #contents > 0 then p.push('') p.outln(contents) p.pop('') end end end m.elements.linker = function(cfg, explicit) return { m.link, m.lib, m.linkLibraryDependencies, } end function m.linker(cfg) local explicit = vstudio.needsExplicitLink(cfg) p.callArray(m.elements.linker, cfg, explicit) end m.elements.link = function(cfg, explicit) if cfg.kind == p.STATICLIB then return { m.subSystem, m.generateDebugInformation, m.optimizeReferences, } else return { m.subSystem, m.generateDebugInformation, m.optimizeReferences, m.additionalDependencies, m.additionalLibraryDirectories, m.importLibrary, m.entryPointSymbol, m.generateMapFile, m.moduleDefinitionFile, m.treatLinkerWarningAsErrors, m.ignoreDefaultLibraries, m.largeAddressAware, m.targetMachine, m.additionalLinkOptions, } end end function m.link(cfg, explicit) local contents = p.capture(function () p.push() p.callArray(m.elements.link, cfg, explicit) p.pop() end) if #contents > 0 then p.push('') p.outln(contents) p.pop('') end end m.elements.lib = function(cfg, explicit) if cfg.kind == p.STATICLIB then return { m.treatLinkerWarningAsErrors, m.targetMachine, m.additionalLinkOptions, } else return {} end end function m.lib(cfg, explicit) local contents = p.capture(function () p.push() p.callArray(m.elements.lib, cfg, explicit) p.pop() end) if #contents > 0 then p.push('') p.outln(contents) p.pop('') end end function m.manifest(cfg) if cfg.kind ~= p.STATICLIB then local manifests = {} for _, fname in ipairs(cfg.files) do if path.getextension(fname) == ".manifest" then table.insert(manifests, project.getrelative(cfg.project, fname)) end end if #manifests > 0 then p.push('') m.element("AdditionalManifestFiles", nil, "%s %%(AdditionalManifestFiles)", table.concat(manifests, " ")) p.pop('') end end end function m.buildEvents(cfg) local write = function (event) local name = event .. "Event" local field = event:lower() local steps = cfg[field .. "commands"] local msg = cfg[field .. "message"] if #steps > 0 then steps = os.translateCommands(steps, p.WINDOWS) p.push('<%s>', name) p.x('%s', table.implode(steps, "", "", "\r\n")) if msg then p.x('%s', msg) end p.pop('', name) end end write("PreBuild") write("PreLink") write("PostBuild") end function m.ruleVars(cfg) for i = 1, #cfg.rules do local rule = p.global.getRule(cfg.rules[i]) local contents = p.capture(function () p.push() for prop in p.rule.eachProperty(rule) do local fld = p.rule.getPropertyField(rule, prop) local value = cfg[fld.name] if value ~= nil then if fld.kind == "path" then value = vstudio.path(cfg, value) else value = p.rule.getPropertyString(rule, prop, value) end if value ~= nil and #value > 0 then m.element(prop.name, nil, '%s', value) end end end p.pop() end) if #contents > 0 then p.push('<%s>', rule.name) p.outln(contents) p.pop('', rule.name) end end end function m.assemblyReferences(prj) local cfg = project.getfirstconfig(prj) local refs = config.getlinks(cfg, "system", "fullpath", "managed") if #refs > 0 then p.push('') for i = 1, #refs do local value = refs[i] if value:find('/', 1, true) then p.push('', path.getbasename(value)) p.x('%s', path.translate(value)) p.pop('') else p.x('', path.getbasename(value)) end end p.pop('') end end m.elements.files = function(prj, groups) return { m.clIncludeFiles, m.clCompileFiles, m.noneFiles, m.resourceCompileFiles, m.customBuildFiles, m.customRuleFiles, m.midlFiles } end function m.files(prj) local groups = m.categorizeSources(prj) p.callArray(m.elements.files, prj, groups) end m.elements.ClCompileFile = function(cfg, file) return {} end m.elements.ClCompileFileCfg = function(fcfg, condition) if fcfg then return { m.excludedFromBuild, m.objectFileName, m.clCompilePreprocessorDefinitions, m.clCompileUndefinePreprocessorDefinitions, m.optimization, m.forceIncludes, m.precompiledHeader, m.enableEnhancedInstructionSet, m.additionalCompileOptions, m.disableSpecificWarnings, m.treatSpecificWarningsAsErrors } else return { m.excludedFromBuild } end end function m.clCompileFiles(prj, groups) m.emitFiles(prj, groups, "ClCompile") end m.elements.ClIncludeFile = function(cfg, file) return {} end m.elements.ClIncludeFileCfg = function(fcfg, condition) return {} end function m.clIncludeFiles(prj, groups) m.emitFiles(prj, groups, "ClInclude") end m.elements.CustomBuildFile = function(cfg, file) return { m.fileType } end m.elements.CustomBuildFileCfg = function(fcfg, condition) return { m.excludedFromBuild, m.buildCommands, m.buildOutputs, m.buildMessage, m.buildAdditionalInputs } end function m.customBuildFiles(prj, groups) m.emitFiles(prj, groups, "CustomBuild", function (cfg, fcfg) return fileconfig.hasCustomBuildRule(fcfg) end) end function m.customRuleFiles(prj, groups) for i = 1, #prj.rules do local rule = p.global.getRule(prj.rules[i]) local files = groups[rule.name] if files and #files > 0 then p.push('') for _, file in ipairs(files) do local contents = p.capture(function() p.push() for prop in p.rule.eachProperty(rule) do local fld = p.rule.getPropertyField(rule, prop) for cfg in project.eachconfig(prj) do local fcfg = fileconfig.getconfig(file, cfg) if fcfg and fcfg[fld.name] then local value = p.rule.getPropertyString(rule, prop, fcfg[fld.name]) if value and #value > 0 then m.element(prop.name, m.condition(cfg), '%s', value) end end end end p.pop() end) if #contents > 0 then p.push('<%s Include=\"%s\">', rule.name, path.translate(file.relpath)) p.outln(contents) p.pop('', rule.name) else p.x('<%s Include=\"%s\" />', rule.name, path.translate(file.relpath)) end end p.pop('') end end end m.elements.NoneFile = function(cfg, file) return {} end m.elements.NoneFileCfg = function(fcfg, condition) return {} end function m.noneFiles(prj, groups) m.emitFiles(prj, groups, "None") end m.elements.ResourceCompileFile = function(cfg, file) return {} end m.elements.ResourceCompileFileCfg = function(fcfg, condition) return { m.excludedFromBuild } end function m.resourceCompileFiles(prj, groups) m.emitFiles(prj, groups, "ResourceCompile", function(cfg) return cfg.system == p.WINDOWS end) end m.elements.MidlFile = function(cfg, file) return {} end m.elements.MidlFileCfg = function(fcfg, condition) return { m.excludedFromBuild } end function m.midlFiles(prj, groups) m.emitFiles(prj, groups, "Midl", function(cfg) return cfg.system == p.WINDOWS end) end function m.categorizeSources(prj) local groups = prj._vc2010_sources if groups then return groups end groups = {} prj._vc2010_sources = groups local tr = project.getsourcetree(prj) tree.traverse(tr, { onleaf = function(node) local cat = m.categorizeFile(prj, node) groups[cat] = groups[cat] or {} table.insert(groups[cat], node) end }) for group, files in pairs(groups) do table.sort(files, function (a, b) return a.relpath < b.relpath end) end return groups end function m.categorizeFile(prj, file) for cfg in project.eachconfig(prj) do local fcfg = fileconfig.getconfig(file, cfg) if fileconfig.hasCustomBuildRule(fcfg) then return "CustomBuild" end end local rule = p.global.getRuleForFile(file.name, prj.rules) if rule then return rule.name end if path.iscppfile(file.name) then return "ClCompile" elseif path.iscppheader(file.name) then return "ClInclude" elseif path.isresourcefile(file.name) then return "ResourceCompile" elseif path.isidlfile(file.name) then return "Midl" else return "None" end end function m.emitFiles(prj, groups, group, check) local files = groups[group] if files and #files > 0 then p.push('') for _, file in ipairs(files) do local contents = p.capture(function () p.push() p.callArray(m.elements[group .. "File"], cfg, file) for cfg in project.eachconfig(prj) do local fcfg = fileconfig.getconfig(file, cfg) if not check or check(cfg, fcfg) then p.callArray(m.elements[group .. "FileCfg"], fcfg, m.condition(cfg)) end end p.pop() end) local rel = path.translate(file.relpath) if #contents > 0 then p.push('<%s Include="%s">', group, rel) p.outln(contents) p.pop('', group) else p.x('<%s Include="%s" />', group, rel) end end p.pop('') end end m.elements.projectReferences = function(prj, ref) if prj.clr ~= p.OFF then return { m.referenceProject, m.referencePrivate, m.referenceOutputAssembly, m.referenceCopyLocalSatelliteAssemblies, m.referenceLinkLibraryDependencies, m.referenceUseLibraryDependences, } else return { m.referenceProject, } end end function m.projectReferences(prj) local refs = project.getdependencies(prj, 'linkOnly') if #refs > 0 then p.push('') for _, ref in ipairs(refs) do local relpath = vstudio.path(prj, vstudio.projectfile(ref)) p.push('', relpath) p.callArray(m.elements.projectReferences, prj, ref) p.pop('') end p.pop('') end end function m.additionalDependencies(cfg, explicit) local links local toolset = config.toolset(cfg) if toolset then links = toolset.getlinks(cfg, not explicit) else links = vstudio.getLinks(cfg, explicit) end if #links > 0 then links = path.translate(table.concat(links, ";")) m.element("AdditionalDependencies", nil, "%s;%%(AdditionalDependencies)", links) end end function m.additionalIncludeDirectories(cfg, includedirs) if #includedirs > 0 then local dirs = vstudio.path(cfg, includedirs) if #dirs > 0 then m.element("AdditionalIncludeDirectories", nil, "%s;%%(AdditionalIncludeDirectories)", table.concat(dirs, ";")) end end end function m.additionalLibraryDirectories(cfg) if #cfg.libdirs > 0 then local dirs = table.concat(vstudio.path(cfg, cfg.libdirs), ";") m.element("AdditionalLibraryDirectories", nil, "%s;%%(AdditionalLibraryDirectories)", dirs) end end function m.additionalUsingDirectories(cfg) if #cfg.usingdirs > 0 then local dirs = vstudio.path(cfg, cfg.usingdirs) if #dirs > 0 then m.element("AdditionalUsingDirectories", nil, "%s;%%(AdditionalUsingDirectories)", table.concat(dirs, ";")) end end end function m.largeAddressAware(cfg) if (cfg.largeaddressaware == true) then m.element("LargeAddressAware", nil, 'true') end end function m.additionalCompileOptions(cfg, condition) if #cfg.buildoptions > 0 then local opts = table.concat(cfg.buildoptions, " ") m.element("AdditionalOptions", condition, '%s %%(AdditionalOptions)', opts) end end function m.additionalLinkOptions(cfg) if #cfg.linkoptions > 0 then local opts = table.concat(cfg.linkoptions, " ") m.element("AdditionalOptions", nil, "%s %%(AdditionalOptions)", opts) end end function m.basicRuntimeChecks(cfg) local runtime = config.getruntime(cfg) if cfg.flags.NoRuntimeChecks or (config.isOptimizedBuild(cfg) and runtime:endswith("Debug")) then m.element("BasicRuntimeChecks", nil, "Default") end end function m.buildAdditionalInputs(fcfg, condition) if fcfg.buildinputs and #fcfg.buildinputs > 0 then local inputs = project.getrelative(fcfg.project, fcfg.buildinputs) m.element("AdditionalInputs", condition, '%s', table.concat(inputs, ";")) end end function m.buildCommands(fcfg, condition) local commands = os.translateCommands(fcfg.buildcommands, p.WINDOWS) commands = table.concat(commands,'\r\n') m.element("Command", condition, '%s', commands) end function m.buildLog(cfg) if cfg.buildlog and #cfg.buildlog > 0 then p.push('') m.element("Path", nil, "%s", vstudio.path(cfg, cfg.buildlog)) p.pop('') end end function m.buildMessage(fcfg, condition) if fcfg.buildmessage then m.element("Message", condition, '%s', fcfg.buildmessage) end end function m.buildOutputs(fcfg, condition) local outputs = project.getrelative(fcfg.project, fcfg.buildoutputs) m.element("Outputs", condition, '%s', table.concat(outputs, ";")) end function m.characterSet(cfg) if not vstudio.isMakefile(cfg) then m.element("CharacterSet", nil, iif(cfg.characterset == p.MBCS, "MultiByte", "Unicode")) end end function m.wholeProgramOptimization(cfg) if cfg.flags.LinkTimeOptimization then m.element("WholeProgramOptimization", nil, "true") end end function m.clCompileAdditionalIncludeDirectories(cfg) m.additionalIncludeDirectories(cfg, cfg.includedirs) end function m.clCompileAdditionalUsingDirectories(cfg) m.additionalUsingDirectories(cfg, cfg.usingdirs) end function m.clCompilePreprocessorDefinitions(cfg, condition) m.preprocessorDefinitions(cfg, cfg.defines, false, condition) end function m.clCompileUndefinePreprocessorDefinitions(cfg, condition) m.undefinePreprocessorDefinitions(cfg, cfg.undefines, false, condition) end function m.clrSupport(cfg) local value if cfg.clr == "On" or cfg.clr == "Unsafe" then value = "true" elseif cfg.clr ~= p.OFF then value = cfg.clr end if value then m.element("CLRSupport", nil, value) end end function m.compileAs(cfg) if cfg.project.language == "C" then m.element("CompileAs", nil, "CompileAsC") end end function m.configurationType(cfg) local types = { SharedLib = "DynamicLibrary", StaticLib = "StaticLibrary", ConsoleApp = "Application", WindowedApp = "Application", Makefile = "Makefile", None = "Makefile", Utility = "Utility", } m.element("ConfigurationType", nil, types[cfg.kind]) end function m.culture(cfg) local value = vstudio.cultureForLocale(cfg.locale) if value then m.element("Culture", nil, "0x%04x", tostring(value)) end end function m.debugInformationFormat(cfg) local value local tool, toolVersion = p.config.toolset(cfg) if cfg.flags.Symbols then if cfg.debugformat == "c7" then value = "OldStyle" elseif cfg.architecture == "x86_64" or cfg.clr ~= p.OFF or config.isOptimizedBuild(cfg) or cfg.editandcontinue == p.OFF or (toolVersion and toolVersion:startswith("LLVM-vs")) then value = "ProgramDatabase" else value = "EditAndContinue" end end if value then m.element("DebugInformationFormat", nil, value) end end function m.deploy(cfg) if cfg.system == p.XBOX360 then p.push('') m.element("DeploymentType", nil, "CopyToHardDrive") m.element("DvdEmulationType", nil, "ZeroSeekTimes") m.element("DeploymentFiles", nil, "$(RemoteRoot)=$(ImagePath);") p.pop('') end end function m.enableEnhancedInstructionSet(cfg, condition) local v local x = cfg.vectorextensions if x == "AVX" and _ACTION > "vs2010" then v = "AdvancedVectorExtensions" elseif x == "AVX2" and _ACTION > "vs2012" then v = "AdvancedVectorExtensions2" elseif cfg.architecture ~= "x86_64" then if x == "SSE2" or x == "SSE3" or x == "SSSE3" or x == "SSE4.1" then v = "StreamingSIMDExtensions2" elseif x == "SSE" then v = "StreamingSIMDExtensions" end end if v then m.element('EnableEnhancedInstructionSet', condition, v) end end function m.entryPointSymbol(cfg) if cfg.entrypoint then m.element("EntryPointSymbol", nil, cfg.entrypoint) else if (cfg.kind == premake.CONSOLEAPP or cfg.kind == premake.WINDOWEDAPP) and not cfg.flags.WinMain and cfg.clr == p.OFF and cfg.system ~= p.XBOX360 then m.element("EntryPointSymbol", nil, "mainCRTStartup") end end end function m.exceptionHandling(cfg) local value if cfg.exceptionhandling == p.OFF then m.element("ExceptionHandling", nil, "false") elseif cfg.exceptionhandling == "SEH" then m.element("ExceptionHandling", nil, "Async") end end function m.excludedFromBuild(filecfg, condition) if not filecfg or filecfg.flags.ExcludeFromBuild then m.element("ExcludedFromBuild", condition, "true") end end function m.extensionsToDeleteOnClean(cfg) if #cfg.cleanextensions > 0 then local value = table.implode(cfg.cleanextensions, "*", ";", "") m.element("ExtensionsToDeleteOnClean", nil, value .. "$(ExtensionsToDeleteOnClean)") end end function m.fileType(cfg, file) m.element("FileType", nil, "Document") end function m.floatingPointModel(cfg) if cfg.floatingpoint then m.element("FloatingPointModel", nil, cfg.floatingpoint) end end function m.inlineFunctionExpansion(cfg) if cfg.inlining then local types = { Default = "Default", Disabled = "Disabled", Explicit = "OnlyExplicitInline", Auto = "AnySuitable", } m.element("InlineFunctionExpansion", nil, types[cfg.inlining]) end end function m.forceIncludes(cfg, condition) if #cfg.forceincludes > 0 then local includes = vstudio.path(cfg, cfg.forceincludes) if #includes > 0 then m.element("ForcedIncludeFiles", condition, table.concat(includes, ';')) end end if #cfg.forceusings > 0 then local usings = vstudio.path(cfg, cfg.forceusings) if #usings > 0 then m.element("ForcedUsingFiles", condition, table.concat(usings, ';')) end end end function m.functionLevelLinking(cfg) if config.isOptimizedBuild(cfg) then m.element("FunctionLevelLinking", nil, "true") end end function m.generateDebugInformation(cfg) m.element("GenerateDebugInformation", nil, tostring(cfg.flags.Symbols ~= nil)) end function m.generateManifest(cfg) if cfg.flags.NoManifest then m.element("GenerateManifest", nil, "false") end end function m.generateMapFile(cfg) if cfg.flags.Maps then m.element("GenerateMapFile", nil, "true") end end function m.ignoreDefaultLibraries(cfg) if #cfg.ignoredefaultlibraries > 0 then local ignored = cfg.ignoredefaultlibraries for i = 1, #ignored do if not p.tools.msc.getLibraryExtensions()[ignored[i]:match("[^.]+$")] then ignored[i] = path.appendextension(ignored[i], ".lib") end end m.element("IgnoreSpecificDefaultLibraries", condition, table.concat(ignored, ';')) end end function m.ignoreWarnDuplicateFilename(prj) if _ACTION > "vs2012" then m.element("IgnoreWarnCompileDuplicatedFilename", nil, "true") end end function m.ignoreImportLibrary(cfg) if cfg.kind == p.SHAREDLIB and cfg.flags.NoImportLib then m.element("IgnoreImportLibrary", nil, "true") end end function m.imageXex(cfg) if cfg.system == p.XBOX360 then p.push('') if cfg.configfile then m.element("ConfigurationFile", nil, "%s", cfg.configfile) else p.w('') p.w('') end p.w('') p.w('') p.pop('') end end function m.imageXexOutput(cfg) if cfg.system == p.XBOX360 then m.element("ImageXexOutput", nil, "%s", "$(OutDir)$(TargetName).xex") end end function m.importLanguageTargets(prj) p.w('') end m.elements.importExtensionTargets = function(prj) return { m.importRuleTargets, } end function m.importExtensionTargets(prj) p.push('') p.callArray(m.elements.importExtensionTargets, prj) p.pop('') end function m.importRuleTargets(prj) for i = 1, #prj.rules do local rule = p.global.getRule(prj.rules[i]) local loc = vstudio.path(prj, p.filename(rule, ".targets")) p.x('', loc) end end function m.importDefaultProps(prj) p.w('') end function m.importLanguageSettings(prj) p.w('') end m.elements.importExtensionSettings = function(prj) return { m.importRuleSettings, } end function m.importExtensionSettings(prj) p.push('') p.callArray(m.elements.importExtensionSettings, prj) p.pop('') end function m.importRuleSettings(prj) for i = 1, #prj.rules do local rule = p.global.getRule(prj.rules[i]) local loc = vstudio.path(prj, p.filename(rule, ".props")) p.x('', loc) end end function m.importLibrary(cfg) if cfg.kind == p.SHAREDLIB then m.element("ImportLibrary", nil, "%s", path.translate(cfg.linktarget.relpath)) end end function m.includePath(cfg) local dirs = vstudio.path(cfg, cfg.sysincludedirs) if #dirs > 0 then m.element("IncludePath", nil, "%s;$(IncludePath)", table.concat(dirs, ";")) end end function m.intDir(cfg) local objdir = vstudio.path(cfg, cfg.objdir) m.element("IntDir", nil, "%s\\", objdir) end function m.intrinsicFunctions(cfg) if config.isOptimizedBuild(cfg) then m.element("IntrinsicFunctions", nil, "true") end end function m.keyword(prj) local isWin, isManaged, isMakefile for cfg in project.eachconfig(prj) do if cfg.system == p.WINDOWS then isWin = true end if cfg.clr ~= p.OFF then isManaged = true end if vstudio.isMakefile(cfg) then isMakefile = true end end if isWin then if isMakefile then m.element("Keyword", nil, "MakeFileProj") else if isManaged then m.targetFramework(prj) m.element("Keyword", nil, "ManagedCProj") else m.element("Keyword", nil, "Win32Proj") end m.element("RootNamespace", nil, "%s", prj.name) end end end function m.libraryPath(cfg) local dirs = vstudio.path(cfg, cfg.syslibdirs) if #dirs > 0 then m.element("LibraryPath", nil, "%s;$(LibraryPath)", table.concat(dirs, ";")) end end function m.linkIncremental(cfg) if cfg.kind ~= p.STATICLIB then m.element("LinkIncremental", nil, "%s", tostring(config.canLinkIncremental(cfg))) end end function m.linkLibraryDependencies(cfg, explicit) if explicit then p.push('') m.element("LinkLibraryDependencies", nil, "false") p.pop('') end end function m.minimalRebuild(cfg) if config.isOptimizedBuild(cfg) or cfg.flags.NoMinimalRebuild or cfg.flags.MultiProcessorCompile or cfg.debugformat == p.C7 then m.element("MinimalRebuild", nil, "false") end end function m.moduleDefinitionFile(cfg) local df = config.findfile(cfg, ".def") if df then m.element("ModuleDefinitionFile", nil, "%s", df) end end function m.multiProcessorCompilation(cfg) if cfg.flags.MultiProcessorCompile then m.element("MultiProcessorCompilation", nil, "true") end end function m.nmakeCommandLine(cfg, commands, phase) if #commands > 0 then commands = os.translateCommands(commands, p.WINDOWS) commands = table.concat(p.esc(commands), p.eol()) p.w('%s', phase, commands, phase) end end function m.nmakeOutDirs(cfg) if vstudio.isMakefile(cfg) then m.outDir(cfg) m.intDir(cfg) end end function m.nmakeOutput(cfg) m.element("NMakeOutput", nil, "$(OutDir)%s", cfg.buildtarget.name) end function m.objectFileName(fcfg) if fcfg.objname ~= fcfg.basename then m.element("ObjectFileName", m.condition(fcfg.config), "$(IntDir)\\%s.obj", fcfg.objname) end end function m.omitDefaultLib(cfg) if cfg.flags.OmitDefaultLibrary then m.element("OmitDefaultLibName", nil, "true") end end function m.omitFramePointers(cfg) if cfg.flags.NoFramePointer then m.element("OmitFramePointers", nil, "true") end end function m.optimizeReferences(cfg) if config.isOptimizedBuild(cfg) then m.element("EnableCOMDATFolding", nil, "true") m.element("OptimizeReferences", nil, "true") end end function m.optimization(cfg, condition) local map = { Off="Disabled", On="Full", Debug="Disabled", Full="Full", Size="MinSpace", Speed="MaxSpeed" } local value = map[cfg.optimize] if value or not condition then m.element('Optimization', condition, value or "Disabled") end end function m.outDir(cfg) local outdir = vstudio.path(cfg, cfg.buildtarget.directory) m.element("OutDir", nil, "%s\\", outdir) end function m.outputFile(cfg) if cfg.system == p.XBOX360 then m.element("OutputFile", nil, "$(OutDir)%s", cfg.buildtarget.name) end end function m.executablePath(cfg) local dirs = vstudio.path(cfg, cfg.bindirs) if #dirs > 0 then m.element("ExecutablePath", nil, "%s;$(ExecutablePath)", table.concat(dirs, ";")) end end function m.platformToolset(cfg) local tool, version = p.config.toolset(cfg) if not version then local action = p.action.current() version = action.vstudio.platformToolset end if version then if cfg.kind == p.NONE or cfg.kind == p.MAKEFILE then if p.config.hasFile(cfg, path.iscppfile) then m.element("PlatformToolset", nil, version) end else m.element("PlatformToolset", nil, version) end end end function m.precompiledHeader(cfg, condition) prjcfg, filecfg = p.config.normalize(cfg) if filecfg then if prjcfg.pchsource == filecfg.abspath and not prjcfg.flags.NoPCH then m.element('PrecompiledHeader', condition, 'Create') elseif filecfg.flags.NoPCH then m.element('PrecompiledHeader', condition, 'NotUsing') end else if not prjcfg.flags.NoPCH and prjcfg.pchheader then m.element("PrecompiledHeader", nil, "Use") m.element("PrecompiledHeaderFile", nil, "%s", prjcfg.pchheader) else m.element("PrecompiledHeader", nil, "NotUsing") end end end function m.preprocessorDefinitions(cfg, defines, escapeQuotes, condition) if #defines > 0 then defines = table.concat(defines, ";") if escapeQuotes then defines = defines:gsub('"', '\\"') end defines = p.esc(defines) .. ";%%(PreprocessorDefinitions)" m.element('PreprocessorDefinitions', condition, defines) end end function m.undefinePreprocessorDefinitions(cfg, undefines, escapeQuotes, condition) if #undefines > 0 then undefines = table.concat(undefines, ";") if escapeQuotes then undefines = undefines:gsub('"', '\\"') end undefines = p.esc(undefines) .. ";%%(UndefinePreprocessorDefinitions)" m.element('UndefinePreprocessorDefinitions', condition, undefines) end end function m.programDataBaseFileName(cfg) end function m.projectGuid(prj) m.element("ProjectGuid", nil, "{%s}", prj.uuid) end function m.projectName(prj) if prj.name ~= prj.filename then m.element("ProjectName", nil, "%s", prj.name) end end function m.propertyGroup(cfg, label) local cond if cfg then cond = string.format(' %s', m.condition(cfg)) end if label then label = string.format(' Label="%s"', label) end p.push('', cond or "", label or "") end function m.propertySheets(cfg) p.push('', m.condition(cfg)) p.w('') p.pop('') end function m.propertySheetGroup(prj) for cfg in project.eachconfig(prj) do m.propertySheets(cfg) end end function m.referenceCopyLocalSatelliteAssemblies(prj, ref) m.element("CopyLocalSatelliteAssemblies", nil, "false") end function m.referenceLinkLibraryDependencies(prj, ref) m.element("LinkLibraryDependencies", nil, "true") end function m.referenceOutputAssembly(prj, ref) m.element("ReferenceOutputAssembly", nil, "true") end function m.referencePrivate(prj, ref) m.element("Private", nil, "true") end function m.referenceProject(prj, ref) m.element("Project", nil, "{%s}", ref.uuid) end function m.referenceUseLibraryDependences(prj, ref) m.element("UseLibraryDependencyInputs", nil, "false") end function m.resourceAdditionalIncludeDirectories(cfg) m.additionalIncludeDirectories(cfg, table.join(cfg.includedirs, cfg.resincludedirs)) end function m.resourcePreprocessorDefinitions(cfg) m.preprocessorDefinitions(cfg, table.join(cfg.defines, cfg.resdefines), true) end function m.runtimeLibrary(cfg) local runtimes = { StaticDebug = "MultiThreadedDebug", StaticRelease = "MultiThreaded", } local runtime = runtimes[config.getruntime(cfg)] if runtime then m.element("RuntimeLibrary", nil, runtime) end end function m.callingConvention(cfg) if cfg.callingconvention then m.element("CallingConvention", nil, cfg.callingconvention) end end function m.runtimeTypeInfo(cfg) if cfg.rtti == p.OFF and cfg.clr == p.OFF then m.element("RuntimeTypeInfo", nil, "false") elseif cfg.rtti == p.ON then m.element("RuntimeTypeInfo", nil, "true") end end function m.bufferSecurityCheck(cfg) local tool, toolVersion = p.config.toolset(cfg) if cfg.flags.NoBufferSecurityCheck or (toolVersion and toolVersion:startswith("LLVM-vs")) then m.element("BufferSecurityCheck", nil, "false") end end function m.stringPooling(cfg) if config.isOptimizedBuild(cfg) then m.element("StringPooling", nil, "true") end end function m.subSystem(cfg) if cfg.system ~= p.XBOX360 then local subsystem = iif(cfg.kind == p.CONSOLEAPP, "Console", "Windows") m.element("SubSystem", nil, subsystem) end end function m.targetExt(cfg) local ext = cfg.buildtarget.extension if ext ~= "" then m.element("TargetExt", nil, "%s", ext) else p.w('') p.w('') end end function m.targetMachine(cfg) local targetmachine = { x86 = "MachineX86", x86_64 = "MachineX64", } if cfg.kind == p.STATICLIB and config.hasFile(cfg, path.isresourcefile) then local value = targetmachine[cfg.architecture] if value ~= nil then m.element("TargetMachine", nil, '%s', value) end end end function m.targetName(cfg) m.element("TargetName", nil, "%s%s", cfg.buildtarget.prefix, cfg.buildtarget.basename) end function m.treatLinkerWarningAsErrors(cfg) if cfg.flags.FatalLinkWarnings then local el = iif(cfg.kind == p.STATICLIB, "Lib", "Linker") m.element("Treat" .. el .. "WarningAsErrors", nil, "true") end end function m.treatWChar_tAsBuiltInType(cfg) local map = { On = "true", Off = "false" } local value = map[cfg.nativewchar] if value then m.element("TreatWChar_tAsBuiltInType", nil, value) end end function m.treatWarningAsError(cfg) if cfg.flags.FatalCompileWarnings and cfg.warnings ~= p.OFF then m.element("TreatWarningAsError", nil, "true") end end function m.disableSpecificWarnings(cfg, condition) if #cfg.disablewarnings > 0 then local warnings = table.concat(cfg.disablewarnings, ";") warnings = p.esc(warnings) .. ";%%(DisableSpecificWarnings)" m.element('DisableSpecificWarnings', condition, warnings) end end function m.treatSpecificWarningsAsErrors(cfg, condition) if #cfg.fatalwarnings > 0 then local fatal = table.concat(cfg.fatalwarnings, ";") fatal = p.esc(fatal) .. ";%%(TreatSpecificWarningsAsErrors)" m.element('TreatSpecificWarningsAsErrors', condition, fatal) end end function m.useDebugLibraries(cfg) local runtime = config.getruntime(cfg) m.element("UseDebugLibraries", nil, tostring(runtime:endswith("Debug"))) end function m.useOfMfc(cfg) if cfg.flags.MFC then m.element("UseOfMfc", nil, iif(cfg.flags.StaticRuntime, "Static", "Dynamic")) end end function m.useOfAtl(cfg) if cfg.atl then m.element("UseOfATL", nil, cfg.atl) end end function m.userMacros(cfg) p.w('') end function m.warningLevel(cfg) local map = { Off = "TurnOffAllWarnings", Extra = "Level4" } m.element("WarningLevel", nil, "%s", map[cfg.warnings] or "Level3") end function m.xmlDeclaration() p.xmlUtf8() end function m.condition(cfg) return string.format('Condition="\'$(Configuration)|$(Platform)\'==\'%s\'"', p.esc(vstudio.projectConfig(cfg))) end function m.element(name, condition, value, ...) if select('#',...) == 0 then value = p.esc(value) end local format if condition then format = string.format('<%s %s>%s', name, condition, value, name) else format = string.format('<%s>%s', name, value, name) end p.x(format, ...) end local p = premake local m = p.vstudio.vc2010 m.elements.user = function(cfg) return { m.debugSettings, } end function m.generateUser(prj) local contents = {} local size = 0 for cfg in p.project.eachconfig(prj) do contents[cfg] = p.capture(function() p.push(2) p.callArray(m.elements.user, cfg) p.pop(2) end) size = size + #contents[cfg] end if size > 0 then m.xmlDeclaration() m.userProject() for cfg in p.project.eachconfig(prj) do p.push('', m.condition(cfg)) if #contents[cfg] > 0 then p.outln(contents[cfg]) end p.pop('') end p.pop('') end end function m.userProject() local action = premake.action.current() p.push('', action.vstudio.toolsVersion) end m.elements.debugSettings = function(cfg) return { m.localDebuggerCommand, m.localDebuggerWorkingDirectory, m.debuggerFlavor, m.localDebuggerCommandArguments, m.localDebuggerDebuggerType, m.localDebuggerEnvironment, m.localDebuggerMergeEnvironment, } end function m.debugSettings(cfg) p.callArray(m.elements.debugSettings, cfg) end function m.debuggerFlavor(cfg) if cfg.debugdir or cfg.debugcommand then p.w('WindowsLocalDebugger') end end function m.localDebuggerCommand(cfg) if cfg.debugcommand then local dir = path.translate(cfg.debugcommand) p.w('%s', dir) end end function m.localDebuggerDebuggerType(cfg) if cfg.debuggertype then p.w('%s', cfg.debuggertype) end end function m.localDebuggerCommandArguments(cfg) if #cfg.debugargs > 0 then p.x('%s', table.concat(cfg.debugargs, " ")) end end function m.localDebuggerWorkingDirectory(cfg) if cfg.debugdir then local dir = p.vstudio.path(cfg, cfg.debugdir) p.x('%s', dir) end end function m.localDebuggerEnvironment(cfg) if #cfg.debugenvs > 0 then local envs = table.concat(cfg.debugenvs, "\n") if cfg.flags.DebugEnvsInherit then envs = envs .. "\n$(LocalDebuggerEnvironment)" end p.w('%s', envs) if cfg.flags.DebugEnvsDontMerge then p.w(2,'false') end end end function m.localDebuggerMergeEnvironment(cfg) if #cfg.debugenvs > 0 and cfg.flags.DebugEnvsDontMerge then p.w(2,'false') end end local p = premake local project = p.project local tree = p.tree local m = p.vstudio.vc2010 function m.generateFilters(prj) m.xmlDeclaration() m.filtersProject() m.uniqueIdentifiers(prj) m.filterGroups(prj) p.out('') end function m.filtersProject() local action = premake.action.current() p.push('', action.vstudio.filterToolsVersion or action.vstudio.toolsVersion) end m.elements.filterGroups = { "None", "ClInclude", "ClCompile", "ResourceCompile", "CustomBuild", "CustomRule" } m.elements.filters = function(prj, groups) local calls = {} for i, group in ipairs(m.elements.filterGroups) do calls[i] = m[group .. "Filters"] end return calls end function m.filterGroups(prj) local groups = m.categorizeSources(prj) p.callArray(m.elements.filters, prj, groups) end function m.uniqueIdentifiers(prj) local tr = project.getsourcetree(prj) local contents = p.capture(function() p.push() tree.traverse(tr, { onbranch = function(node, depth) p.push('', path.translate(node.path)) p.w('{%s}', os.uuid(node.path)) p.pop('') end }, false) p.pop() end) if #contents > 0 then p.push('') p.outln(contents) p.pop('') end end function m.ClCompileFilters(prj, groups) m.filterGroup(prj, groups, "ClCompile") end function m.ClIncludeFilters(prj, groups) m.filterGroup(prj, groups, "ClInclude") end function m.CustomBuildFilters(prj, groups) m.filterGroup(prj, groups, "CustomBuild") end function m.CustomRuleFilters(prj, groups) for group, files in pairs(groups) do if not table.contains(m.elements.filterGroups, group) then m.filterGroup(prj, groups, group) end end end function m.NoneFilters(prj, groups) m.filterGroup(prj, groups, "None") end function m.ResourceCompileFilters(prj, groups) m.filterGroup(prj, groups, "ResourceCompile") end function m.filterGroup(prj, groups, group) local files = groups[group] or {} if #files > 0 then p.push('') for _, file in ipairs(files) do if file.parent.path then p.push('<%s Include=\"%s\">', group, path.translate(file.relpath)) p.w('%s', path.translate(file.parent.path)) p.pop('', group) else p.w('<%s Include=\"%s\" />', group, path.translate(file.relpath)) end end p.pop('') end end premake.vstudio.vs2010.rules = {} premake.vstudio.vs2010.rules.props = {} local m = premake.vstudio.vs2010.rules.props m.elements = {} local p = premake m.elements.project = function(r) return { p.vstudio.projectElement, m.targetsGroup, m.dependsOnGroup, m.ruleGroup, } end function m.generate(r) p.xmlUtf8() p.callArray(m.elements.project, r) p.pop() p.out('') end m.elements.targetsGroup = function(r) return { m.beforeTargets, m.afterTargets, } end function m.targetsGroup(r) p.w('', r.name, r.name) p.callArray(m.elements.targetsGroup, r) p.pop('') end m.elements.dependsOnGroup = function(r) return { m.dependsOn, } end function m.dependsOnGroup(r) p.push('') p.callArray(m.elements.dependsOnGroup, r) p.pop('') end m.elements.ruleGroup = function(r) return { m.propertyDefaults, m.commandLineTemplates, m.outputs, m.executionDescription, m.additionalDependencies, } end function m.ruleGroup(r) p.push('') p.push('<%s>', r.name) p.callArray(m.elements.ruleGroup, r) p.pop('', r.name) p.pop('') end function m.propertyDefaults(r) local defs = r.propertydefinition for i = 1, #defs do local def = defs[i] local value = def.value if value then if def.kind == "path" then value = path.translate(value) end p.w('<%s>%s', def.name, value, def.name) end end end function m.additionalDependencies(r) local deps = table.concat(r.builddependencies, ";") p.x('%s', deps) end function m.afterTargets(r) p.w('<%sAfterTargets>CustomBuild', r.name, r.name) end function m.beforeTargets(r) p.w('<%sBeforeTargets>Midl', r.name, r.name) end function m.commandLineTemplates(r) if #r.buildcommands then local cmds = os.translateCommands(r.buildcommands, p.WINDOWS) cmds = table.concat(cmds, p.eol()) p.x('%s', cmds) end end function m.dependsOn(r) p.w('<%sDependsOn', r.name) p.w(' Condition="\'$(ConfigurationType)\' != \'Makefile\'">_SelectedFiles;$(%sDependsOn)', r.name, r.name, r.name) end function m.executionDescription(r) if r.buildmessage then p.x('%s', r.buildmessage) end end function m.outputs(r) if #r.buildoutputs then local outputs = table.concat(r.buildoutputs, ";") p.x('%s', path.translate(outputs)) end end premake.vstudio.vs2010.rules.targets = {} local m = premake.vstudio.vs2010.rules.targets m.elements = {} local p = premake m.elements.project = function(r) return { p.vstudio.projectElement, m.availableItemGroup, m.computeInputsGroup, m.usingTask, m.ruleTarget, m.computeOutputTarget, } end function m.generate(r) p.xmlUtf8() p.callArray(m.elements.project, r) p.pop() p.out('') end m.elements.availableItemGroup = function(r) return { m.propertyPageSchema, m.availableItemName, } end function m.availableItemGroup(r) p.push('') p.callArray(m.elements.availableItemGroup, r) p.pop('') end m.elements.computeInputsGroup = function(r) return { m.computeLinkInputsTargets, m.computeLibInputsTargets, } end function m.computeInputsGroup(r) p.push('') p.callArray(m.elements.computeInputsGroup, r) p.pop('') end m.elements.ruleTargetAttributes = function(r) return { m.targetName, m.beforeTargets, m.afterTargets, m.targetCondition, m.targetOutputs, m.targetInputs, m.dependsOnTargets, } end m.elements.ruleTarget = function(r) return { m.selectedFiles, m.tlog, m.message, m.tlogWrite, m.tlogRead, m.rule, } end function m.ruleTarget(r) local attribs = p.capture(function() p.push() p.callArray(m.elements.ruleTargetAttributes, r) p.pop() end) p.push('') p.callArray(m.elements.ruleTarget, r) p.pop('') end m.elements.tlog = function(r) return { m.tlogSource, m.tlogInputs, m.tlogProperties, } end function m.tlog(r) p.push('') p.push('<%s_tlog', r.name) p.w('Include="%%(%s.Outputs)"', r.name) p.w('Condition="\'%%(%s.Outputs)\' != \'\' and \'%%(%s.ExcludedFromBuild)\' != \'true\'">', r.name, r.name) p.callArray(m.elements.tlog, r) p.pop('', r.name) p.pop('') end m.elements.ruleAttributes = function(r) return { m.ruleCondition, m.commandLineTemplate, m.properties, m.additionalOptions, m.inputs, m.standardOutputImportance, } end function m.rule(r) local attribs = p.capture(function() p.push() p.callArray(m.elements.ruleAttributes, r) p.pop() end) p.w('<%s', r.name) p.outln(attribs .. ' />') end m.elements.computeOutputItems = function(r) return { m.outputs, m.linkLib, } end m.elements.computeOutputTarget = function(r) return { m.makeDir, } end function m.computeOutputTarget(r) p.push('', r.name) p.push('') p.callArray(m.elements.computeOutputItems, r) p.pop('') p.callArray(m.elements.computeOutputTarget, r) p.pop('') end function m.additionalOptions(r) p.w('AdditionalOptions="%%(%s.AdditionalOptions)"', r.name) end function m.commandLineTemplate(r) p.w('CommandLineTemplate="%%(%s.CommandLineTemplate)"', r.name) end function m.afterTargets(r) p.w('AfterTargets="$(%sAfterTargets)"', r.name) end function m.availableItemName(r) p.push('', r.name) p.w('_%s', r.name) p.pop('') end function m.beforeTargets(r) p.w('BeforeTargets="$(%sBeforeTargets)"', r.name) end function m.computeLibInputsTargets(r) p.push('') p.w('$(ComputeLibInputsTargets);') p.w('Compute%sOutput;', r.name) p.pop('') end function m.computeLinkInputsTargets(r) p.push('') p.w('$(ComputeLinkInputsTargets);') p.w('Compute%sOutput;', r.name) p.pop('') end function m.dependsOnTargets(r) p.w('DependsOnTargets="$(%sDependsOn);Compute%sOutput"', r.name, r.name) end function m.inputs(r) p.w('Inputs="%%(%s.Identity)"', r.name) end function m.linkLib(r) local linkable for i = 1, #r.buildoutputs do if (path.islinkable(r.buildoutputs[i])) then linkable = true end end if linkable then for i, el in pairs { 'Link', 'Lib', 'ImpLib' } do p.push('<%s', el) p.w('Include="%%(%sOutputs.Identity)"', r.name) p.w('Condition="\'%%(Extension)\'==\'.obj\' or \'%%(Extension)\'==\'.res\' or \'%%(Extension)\'==\'.rsc\' or \'%%(Extension)\'==\'.lib\'" />') p.pop() end end end function m.makeDir(r) p.w('', r.name) end function m.message(r) p.w('', r.name) end function m.outputs(r) p.w('<%sOutputs', r.name) p.w(' Condition="\'@(%s)\' != \'\' and \'%%(%s.ExcludedFromBuild)\' != \'true\'"', r.name, r.name) p.w(' Include="%%(%s.Outputs)" />', r.name) end function m.properties(r) local defs = r.propertydefinition for i = 1, #defs do local name = defs[i].name p.w('%s="%%(%s.%s)"', name, r.name, name) end end function m.propertyPageSchema(r) p.w('') end function m.ruleCondition(r) p.w('Condition="\'@(%s)\' != \'\' and \'%%(%s.ExcludedFromBuild)\' != \'true\'"', r.name, r.name) end function m.selectedFiles(r) p.push('') p.w('<%s Remove="@(%s)" Condition="\'%%(Identity)\' != \'@(SelectedFiles)\'" />', r.name, r.name) p.pop('') end function m.standardOutputImportance(r) p.w('StandardOutputImportance="High"') p.w('StandardErrorImportance="High"') end function m.targetCondition(r) p.w('Condition="\'@(%s)\' != \'\'"', r.name) end function m.targetInputs(r) local extra = {} local defs = r.propertydefinition for i = 1, #defs do local def = defs[i] if def.dependency then table.insert(extra, string.format("%%(%s.%s);", r.name, def.name)) end end extra = table.concat(extra) p.w('Inputs="%%(%s.Identity);%%(%s.AdditionalDependencies);%s$(MSBuildProjectFile)"', r.name, r.name, extra) end function m.targetName(r) p.w('Name="_%s"', r.name) end function m.targetOutputs(r) p.w('Outputs="%%(%s.Outputs)"', r.name) end function m.tlogInputs(r) p.w("@(%s, ';')", r.name) end function m.tlogProperties(r) local defs = r.propertydefinition for i = 1, #defs do local def = defs[i] if def.dependency then p.w('<%s>%%(%s.%s)', def.name, r.name, def.name, def.name) end end end function m.tlogRead(r) local extra = {} local defs = r.propertydefinition for i = 1, #defs do local def = defs[i] if def.dependency then table.insert(extra, string.format("%%(%s_tlog.%s);", r.name, def.name)) end end extra = table.concat(extra) p.w('', r.name, extra, r.name) end function m.tlogWrite(r) p.w('', r.name, r.name) end function m.tlogSource(r) p.w("@(%s, '|')", r.name) end function m.usingTask(r) p.push('') p.w('$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml') p.pop('') end premake.vstudio.vs2010.rules.xml = {} local m = premake.vstudio.vs2010.rules.xml m.elements = {} local p = premake m.elements.project = function(r) return { p.xmlUtf8, m.projectSchemaDefinitions, m.rule, m.ruleItem, m.fileExtension, m.contentType, } end function m.generate(r) p.callArray(m.elements.project, r) p.out('') end m.elements.rule = function(r) return { m.dataSource, m.categories, m.inputs, m.properties, m.commandLineTemplate, m.beforeTargets, m.afterTargets, m.outputs, m.executionDescription, m.additionalDependencies, m.additionalOptions, } end function m.rule(r) p.push('') p.callArray(m.elements.rule, r) p.pop('') end function m.categories(r) local categories = { [1] = { name="General" }, [2] = { name="Command Line", subtype="CommandLine" }, } p.push('') for i = 1, #categories do m.category(categories[i]) end p.pop('') end function m.category(cat) local attribs = p.capture(function() p.push() p.w('Name="%s"', cat.name) if cat.subtype then p.w('Subtype="%s"', cat.subtype) end p.pop() end) p.push('') p.push('') p.w('%s', cat.name) p.pop('') p.pop('') end function m.properties(r) local defs = r.propertydefinition for i = 1, #defs do local def = defs[i] if def.kind == "boolean" then m.boolProperty(def) elseif def.kind == "list" then m.stringListProperty(def) elseif type(def.values) == "table" then m.enumProperty(def) else m.stringProperty(def) end end end function m.baseProperty(def, suffix) local c = p.capture(function () p.w('Name="%s"', def.name) p.w('HelpContext="0"') p.w('DisplayName="%s"', def.display or def.name) if def.description then p.w('Description="%s"', def.description) end end) if suffix then c = c .. suffix end p.outln(c) end function m.boolProperty(def) p.push('', def.switch or "[value]") p.pop() end function m.enumProperty(def) p.push('') local values = def.values local switches = def.switch or {} local keys = table.keys(def.values) table.sort(keys) for _, key in pairs(keys) do p.push('', switches[key]) else p.w('DisplayName="%s" />', values[key]) end p.pop() end p.pop('') end function m.stringProperty(def) p.push('', def.switch or "[value]") p.pop() end function m.stringListProperty(def) p.push('', def.switch or "[value]") p.pop() end function m.additionalDependencies(r) p.push('') p.pop() end function m.additionalOptions(r) p.push('') p.push('') p.w('Additional Options') p.pop('') p.push('') p.w('Additional Options') p.pop('') p.pop('') end function m.afterTargets(r) p.push('') p.push('') p.w('Execute After') p.pop('') p.push('') p.w('Specifies the targets for the build customization to run after.') p.pop('') p.push('') p.push('', r.name) p.pop() p.pop('') p.push('') p.push('') p.pop() p.pop('') p.pop('') end function m.beforeTargets(r) p.push('') p.push('') p.w('Execute Before') p.pop('') p.push('') p.w('Specifies the targets for the build customization to run before.') p.pop('') p.push('') p.push('', r.name) p.pop() p.pop('') p.push('') p.push('') p.pop() p.pop('') p.pop('') end function m.commandLineTemplate(r) p.push('') p.pop() end function m.contentType(r) p.push('', r.name) p.pop() end function m.dataSource(r) p.push('') p.push('', r.name) p.pop() p.pop('') end function m.executionDescription(r) p.push('') p.pop() end function m.fileExtension(r) p.push('', r.name) p.pop() end function m.inputs(r) p.push('') p.push('') p.push('') p.pop() p.pop('') p.pop('') end function m.outputs(r) p.push('') p.pop() end function m.ruleItem(r) p.push('', r.display or r.name) p.pop() end function m.projectSchemaDefinitions(r) p.push('') end local vstudio = premake.vstudio local cs2005 = vstudio.cs2005 local vc2010 = vstudio.vc2010 local p = premake newaction { trigger = "vs2012", shortname = "Visual Studio 2012", description = "Generate Visual Studio 2012 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Makefile", "None", "Utility" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onWorkspace = function(wks) vstudio.vs2005.generateSolution(wks) end, onProject = function(prj) vstudio.vs2010.generateProject(prj) end, onRule = function(rule) vstudio.vs2010.generateRule(rule) end, onCleanWorkspace = function(wks) vstudio.cleanSolution(wks) end, onCleanProject = function(prj) vstudio.cleanProject(prj) end, onCleanTarget = function(prj) vstudio.cleanTarget(prj) end, pathVars = vstudio.pathVars, vstudio = { solutionVersion = "12", versionName = "2012", targetFramework = "4.5", toolsVersion = "4.0", platformToolset = "v110" } } premake.vstudio.vc2013 = {} local p = premake local vstudio = p.vstudio local vc2010 = vstudio.vc2010 local m = vstudio.vc2013 newaction { trigger = "vs2013", shortname = "Visual Studio 2013", description = "Generate Visual Studio 2013 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Makefile", "None", "Utility" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onWorkspace = function(wks) vstudio.vs2005.generateSolution(wks) end, onProject = function(prj) vstudio.vs2010.generateProject(prj) end, onRule = function(rule) vstudio.vs2010.generateRule(rule) end, onCleanWorkspace = function(wks) vstudio.cleanSolution(wks) end, onCleanProject = function(prj) vstudio.cleanProject(prj) end, onCleanTarget = function(prj) vstudio.cleanTarget(prj) end, pathVars = vstudio.pathVars, vstudio = { solutionVersion = "12", versionName = "2013", targetFramework = "4.5", toolsVersion = "12.0", filterToolsVersion = "4.0", platformToolset = "v120" } } premake.vstudio.vc2015 = {} local p = premake local vstudio = p.vstudio local vc2010 = vstudio.vc2010 local m = vstudio.vc2015 newaction { trigger = "vs2015", shortname = "Visual Studio 2015", description = "Generate Visual Studio 2015 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Makefile", "None", "Utility" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onWorkspace = function(wks) vstudio.vs2005.generateSolution(wks) end, onProject = function(prj) vstudio.vs2010.generateProject(prj) end, onRule = function(rule) vstudio.vs2010.generateRule(rule) end, onCleanWorkspace = function(wks) vstudio.cleanSolution(wks) end, onCleanProject = function(prj) vstudio.cleanProject(prj) end, onCleanTarget = function(prj) vstudio.cleanTarget(prj) end, pathVars = vstudio.pathVars, vstudio = { solutionVersion = "12", versionName = "2015", targetFramework = "4.5", toolsVersion = "14.0", filterToolsVersion = "4.0", platformToolset = "v140" } } premake.clean = {} newaction { trigger = "clean", description = "Remove all binaries and generated files", execute = function() print("** The clean action has not yet been ported") end } local p = premake local api = p.api local DOC_URL = "See https://github.com/premake/premake-core/wiki/" api.register { name = "architecture", scope = "config", kind = "string", allowed = { "universal", p.X86, p.X86_64, }, aliases = { i386 = p.X86, amd64 = p.X86_64, x32 = p.X86,-- these should be DEPRECATED x64 = p.X86_64, }, } api.register { name = "atl", scope = "config", kind = "string", allowed = { "Off", "Dynamic", "Static", }, } api.register { name = "basedir", scope = "project", kind = "path" } api.register { name = "buildaction", scope = "config", kind = "string", allowed = { "Application", "Compile", "Component", "Copy", "Embed", "Form", "None", "Resource", "UserControl", }, } api.register { name = "buildcommands", scope = { "config", "rule" }, kind = "list:string", tokens = true, pathVars = true, } api.register { name = "builddependencies", scope = { "rule" }, kind = "list:string", tokens = true, pathVars = true, } api.register { name = "buildlog", scope = { "config" }, kind = "path", tokens = true, pathVars = true, } api.register { name = "buildmessage", scope = { "config", "rule" }, kind = "string", tokens = true, pathVars = true, } api.register { name = "buildoptions", scope = "config", kind = "list:string", tokens = true, pathVars = true, } api.register { name = "buildoutputs", scope = { "config", "rule" }, kind = "list:path", tokens = true, pathVars = true, } api.register { name = "buildinputs", scope = "config", kind = "list:path", tokens = true, pathVars = true, } api.register { name = "buildrule", -- DEPRECATED scope = "config", kind = "table", tokens = true, } api.register { name = "characterset", scope = "config", kind = "string", allowed = { "Default", "MBCS", "Unicode", } } api.register { name = "cleancommands", scope = "config", kind = "list:string", tokens = true, pathVars = true, } api.register { name = "cleanextensions", scope = "config", kind = "list:string", } api.register { name = "clr", scope = "config", kind = "string", allowed = { "Off", "On", "Pure", "Safe", "Unsafe", } } api.register { name = "configmap", scope = "project", kind = "list:keyed:array:string", } api.register { name = "configfile", scope = "config", kind = "string", tokens = true, } api.register { name = "configurations", scope = "project", kind = "list:string", } api.register { name = "copylocal", scope = "config", kind = "list:mixed", tokens = true, } api.register { name = "debugargs", scope = "config", kind = "list:string", tokens = true, pathVars = true, } api.register { name = "debugcommand", scope = "config", kind = "path", tokens = true, pathVars = true, } api.register { name = "debugconnectcommands", scope = "config", kind = "list:string", tokens = true, } api.register { name = "debugdir", scope = "config", kind = "path", tokens = true, pathVars = true, } api.register { name = "debugenvs", scope = "config", kind = "list:string", tokens = true, pathVars = true, } api.register { name = "debugextendedprotocol", scope = "config", kind = "boolean", } api.register { name = "debugformat", scope = "config", kind = "string", allowed = { "c7", }, } api.register { name = "debugger", scope = "config", kind = "string", allowed = { "Default", "GDB", "LLDB", } } api.register { name = "debuggertype", scope = "config", kind = "string", allowed = { "Mixed", "NativeOnly", "ManagedOnly", } } api.register { name = "debugpathmap", scope = "config", kind = "list:keyed:path", tokens = true, } api.register { name = "debugport", scope = "config", kind = "integer", } api.register { name = "debugremotehost", scope = "config", kind = "string", tokens = true, } api.register { name = "debugsearchpaths", scope = "config", kind = "list:path", tokens = true, } api.register { name = "debugstartupcommands", scope = "config", kind = "list:string", tokens = true, } api.register { name = "debugtoolargs", scope = "config", kind = "list:string", tokens = true, pathVars = true, } api.register { name = "debugtoolcommand", scope = "config", kind = "path", tokens = true, pathVars = true, } api.register { name = "defaultplatform", scope = "project", kind = "string", } api.register { name = "defines", scope = "config", kind = "list:string", tokens = true, } api.register { name = "dependson", scope = "config", kind = "list:string", tokens = true, } api.register { name = "deploymentoptions", scope = "config", kind = "list:string", tokens = true, } api.register { name = "disablewarnings", scope = "config", kind = "list:string", tokens = true, } api.register { name = "display", scope = "rule", kind = "string", } api.register { name = "editandcontinue", scope = "config", kind = "string", allowed = { "Default", "On", "Off", }, } api.register { name = "exceptionhandling", scope = "config", kind = "string", allowed = { "Default", "On", "Off", "SEH" }, } api.register { name = "enablewarnings", scope = "config", kind = "list:string", tokens = true, } api.register { name = "endian", scope = "config", kind = "string", allowed = { "Default", "Little", "Big", }, } api.register { name = "entrypoint", scope = "config", kind = "string", } api.register { name = "fatalwarnings", scope = "config", kind = "list:string", tokens = true, } api.register { name = "fileextension", scope = "rule", kind = "string", } api.register { name = "filename", scope = { "project", "rule" }, kind = "string", tokens = true, } api.register { name = "files", scope = "config", kind = "list:file", tokens = true, } api.register { name = "flags", scope = "config", kind = "list:string", allowed = { "Component", -- DEPRECATED "DebugEnvsDontMerge", "DebugEnvsInherit", "EnableSSE", -- DEPRECATED "EnableSSE2", -- DEPRECATED "ExcludeFromBuild", "ExtraWarnings", -- DEPRECATED "FatalCompileWarnings", "FatalLinkWarnings", "FloatFast", -- DEPRECATED "FloatStrict", -- DEPRECATED "LinkTimeOptimization", "Managed", -- DEPRECATED "Maps", "MFC", "MultiProcessorCompile", "NativeWChar", -- DEPRECATED "No64BitChecks", "NoCopyLocal", "NoEditAndContinue", -- DEPRECATED "NoExceptions", -- DEPRECATED "NoFramePointer", "NoImplicitLink", "NoImportLib", "NoIncrementalLink", "NoManifest", "NoMinimalRebuild", "NoNativeWChar", -- DEPRECATED "NoPCH", "NoRuntimeChecks", "NoRTTI", -- DEPRECATED "NoBufferSecurityCheck", "NoWarnings", -- DEPRECATED "OmitDefaultLibrary", "Optimize", -- DEPRECATED "OptimizeSize", -- DEPRECATED "OptimizeSpeed", -- DEPRECATED "RelativeLinks", "ReleaseRuntime", -- DEPRECATED "SEH", -- DEPRECATED "ShadowedVariables", "StaticRuntime", "Symbols", "UndefinedIdentifiers", "Unicode", -- DEPRECATED "Unsafe", -- DEPRECATED "WinMain", "WPF", "C++11", "C++14", }, aliases = { FatalWarnings = { "FatalWarnings", "FatalCompileWarnings", "FatalLinkWarnings" }, Optimise = 'Optimize', OptimiseSize = 'OptimizeSize', OptimiseSpeed = 'OptimizeSpeed', }, } api.register { name = "floatingpoint", scope = "config", kind = "string", allowed = { "Default", "Fast", "Strict", } } api.register { name = "inlining", scope = "config", kind = "string", allowed = { "Default", "Disabled", "Explicit", "Auto" } } api.register { name = "callingconvention", scope = "config", kind = "string", allowed = { "Cdecl", "FastCall", "StdCall", "VectorCall", } } api.register { name = "forceincludes", scope = "config", kind = "list:mixed", tokens = true, } api.register { name = "forceusings", scope = "config", kind = "list:file", tokens = true, } api.register { name = "fpu", scope = "config", kind = "string", allowed = { "Software", "Hardware", } } api.register { name = "dotnetframework", scope = "config", kind = "string", } api.register { name = "gccprefix", scope = "config", kind = "string", tokens = true, } api.register { name = "ignoredefaultlibraries", scope = "config", kind = "list:mixed", tokens = true, } api.register { name = "icon", scope = "project", kind = "file", tokens = true, } api.register { name = "imageoptions", scope = "config", kind = "list:string", tokens = true, } api.register { name = "imagepath", scope = "config", kind = "path", tokens = true, } api.register { name = "implibdir", scope = "config", kind = "path", tokens = true, } api.register { name = "implibextension", scope = "config", kind = "string", tokens = true, } api.register { name = "implibname", scope = "config", kind = "string", tokens = true, } api.register { name = "implibprefix", scope = "config", kind = "string", tokens = true, } api.register { name = "implibsuffix", scope = "config", kind = "string", tokens = true, } api.register { name = "includedirs", scope = "config", kind = "list:directory", tokens = true, } api.register { name = "bindirs", scope = "config", kind = "list:directory", tokens = true, } api.register { name = "kind", scope = "config", kind = "string", allowed = { "ConsoleApp", "Makefile", "None", "SharedLib", "StaticLib", "WindowedApp", "Utility", }, } api.register { name = "language", scope = "project", kind = "string", allowed = { "C", "C++", "C#", }, } api.register { name = "libdirs", scope = "config", kind = "list:directory", tokens = true, } api.register { name = "linkoptions", scope = "config", kind = "list:string", tokens = true, } api.register { name = "links", scope = "config", kind = "list:mixed", tokens = true, } api.register { name = "locale", scope = "config", kind = "string", tokens = false, } api.register { name = "location", scope = { "project", "rule" }, kind = "path", tokens = true, } api.register { name = "makesettings", scope = "config", kind = "list:string", tokens = true, } api.register { name = "namespace", scope = "project", kind = "string", tokens = true, } api.register { name = "nativewchar", scope = "config", kind = "string", allowed = { "Default", "On", "Off", } } api.register { name = "objdir", scope = "config", kind = "path", tokens = true, } api.register { name = "optimize", scope = "config", kind = "string", allowed = { "Off", "On", "Debug", "Size", "Speed", "Full", } } api.register { name = "runtime", scope = "config", kind = "string", allowed = { "Debug", "Release", } } api.register { name = "pchheader", scope = "config", kind = "string", tokens = true, } api.register { name = "pchsource", scope = "config", kind = "path", tokens = true, } api.register { name = "pic", scope = "config", kind = "string", allowed = { "Off", "On", } } api.register { name = "platforms", scope = "project", kind = "list:string", } api.register { name = "postbuildcommands", scope = "config", kind = "list:string", tokens = true, pathVars = true, } api.register { name = "postbuildmessage", scope = "config", kind = "string", tokens = true, pathVars = true, } api.register { name = "prebuildcommands", scope = "config", kind = "list:string", tokens = true, pathVars = true, } api.register { name = "prebuildmessage", scope = "config", kind = "string", tokens = true, pathVars = true, } api.register { name = "prelinkcommands", scope = "config", kind = "list:string", tokens = true, pathVars = true, } api.register { name = "prelinkmessage", scope = "config", kind = "string", tokens = true, pathVars = true, } api.register { name = "propertydefinition", scope = "rule", kind = "list:table", } api.register { name = "rebuildcommands", scope = "config", kind = "list:string", tokens = true, pathVars = true, } api.register { name = "resdefines", scope = "config", kind = "list:string", tokens = true, } api.register { name = "resincludedirs", scope = "config", kind = "list:directory", tokens = true, } api.register { name = "resoptions", scope = "config", kind = "list:string", tokens = true, } api.register { name = "rtti", scope = "config", kind = "string", allowed = { "Default", "On", "Off", }, } api.register { name = "rules", scope = "project", kind = "list:string", } api.register { name = "startproject", scope = "workspace", kind = "string", tokens = true, } api.register { name = "strictaliasing", scope = "config", kind = "string", allowed = { "Off", "Level1", "Level2", "Level3", } } api.register { name = "sysincludedirs", scope = "config", kind = "list:directory", tokens = true, } api.register { name = "syslibdirs", scope = "config", kind = "list:directory", tokens = true, } api.register { name = "system", scope = "config", kind = "string", allowed = { "aix", "bsd", "haiku", "linux", "macosx", "solaris", "wii", "windows", "xbox360", }, } api.register { name = "targetdir", scope = "config", kind = "path", tokens = true, } api.register { name = "targetextension", scope = "config", kind = "string", tokens = true, } api.register { name = "targetname", scope = "config", kind = "string", tokens = true, } api.register { name = "targetprefix", scope = "config", kind = "string", tokens = true, } api.register { name = "targetsuffix", scope = "config", kind = "string", tokens = true, } api.register { name = "toolset", scope = "config", kind = "string", allowed = function(value) value = value:lower() local tool, version = p.tools.canonical(value) if tool then return value end end, } api.register { name = "customtoolnamespace", scope = "config", kind = "string", } api.register { name = "undefines", scope = "config", kind = "list:string", tokens = true, } api.register { name = "usingdirs", scope = "config", kind = "list:directory", tokens = true, } api.register { name = "uuid", scope = "project", kind = "string", allowed = function(value) local ok = true if (#value ~= 36) then ok = false end for i=1,36 do local ch = value:sub(i,i) if (not ch:find("[ABCDEFabcdef0123456789-]")) then ok = false end end if (value:sub(9,9) ~= "-") then ok = false end if (value:sub(14,14) ~= "-") then ok = false end if (value:sub(19,19) ~= "-") then ok = false end if (value:sub(24,24) ~= "-") then ok = false end if (not ok) then return nil, "invalid UUID" end return value:upper() end } api.register { name = "vectorextensions", scope = "config", kind = "string", allowed = { "Default", "AVX", "AVX2", "SSE", "SSE2", "SSE3", "SSSE3", "SSE4.1", } } api.register { name = "vpaths", scope = "project", kind = "list:keyed:list:path", tokens = true, pathVars = true, } api.register { name = "warnings", scope = "config", kind = "string", allowed = { "Off", "Default", "Extra", } } api.register { name = "largeaddressaware", scope = "config", kind = "boolean", } api.register { name = "editorintegration", scope = "workspace", kind = "boolean", } api.alias("buildcommands", "buildCommands") api.alias("builddependencies", "buildDependencies") api.alias("buildmessage", "buildMessage") api.alias("buildoutputs", "buildOutputs") api.alias("cleanextensions", "cleanExtensions") api.alias("configfile", "configFile") api.alias("dotnetframework", "framework") api.alias("editandcontinue", "editAndContinue") api.alias("fileextension", "fileExtension") api.alias("propertydefinition", "propertyDefinition") api.alias("removefiles", "excludes") api.deprecateField("buildrule", nil, function(value) if value.description then buildmessage(value.description) end buildcommands(value.commands) buildoutputs(value.outputs) end) api.deprecateValue("flags", "Component", nil, function(value) buildaction "Component" end) api.deprecateValue("flags", { "EnableSSE", "EnableSSE2" }, nil, function(value) vectorextensions(value:sub(7)) end, function(value) vectorextension "Default" end) api.deprecateValue("flags", { "FloatFast", "FloatStrict" }, nil, function(value) floatingpoint(value:sub(6)) end, function(value) floatingpoint "Default" end) api.deprecateValue("flags", { "NativeWChar", "NoNativeWChar" }, nil, function(value) local map = { NativeWChar = "On", NoNativeWChar = "Off" } nativewchar(map[value] or "Default") end, function(value) nativewchar "Default" end) api.deprecateValue("flags", { "Optimize", "OptimizeSize", "OptimizeSpeed" }, nil, function(value) local map = { Optimize = "On", OptimizeSize = "Size", OptimizeSpeed = "Speed" } optimize (map[value] or "Off") end, function(value) optimize "Off" end) api.deprecateValue("flags", { "ReleaseRuntime" }, nil, function(value) runtime 'Release' end, function(value) end) api.deprecateValue("flags", { "Optimise", "OptimiseSize", "OptimiseSpeed" }, nil, function(value) local map = { Optimise = "On", OptimiseSize = "Size", OptimiseSpeed = "Speed" } optimize (map[value] or "Off") end, function(value) optimize "Off" end) api.deprecateValue("flags", { "ExtraWarnings", "NoWarnings" }, nil, function(value) local map = { ExtraWarnings = "Extra", NoWarnings = "Off" } warnings (map[value] or "Default") end, function(value) warnings "Default" end) api.deprecateValue("flags", "Managed", nil, function(value) clr "On" end, function(value) clr "Off" end) api.deprecateValue("flags", "NoEditAndContinue", nil, function(value) editandcontinue "Off" end, function(value) editandcontinue "On" end) api.deprecateValue("flags", "NoExceptions", 'Use `exceptionhandling "Off"` instead', function(value) exceptionhandling "Off" end, function(value) exceptionhandling "On" end) api.deprecateValue("flags", "NoRTTI", 'Use `rtti "Off"` instead', function(value) rtti "Off" end, function(value) rtti "On" end) api.deprecateValue("flags", "SEH", 'Use `exceptionhandling "SEH"` instead', function(value) exceptionhandling "SEH" end, function(value) exceptionhandling "Default" end) api.deprecateValue("flags", "Unsafe", nil, function(value) clr "Unsafe" end, function(value) clr "On" end) api.deprecateValue("flags", "Unicode", nil, function(value) characterset "Unicode" end, function(value) characterset "Default" end) newoption { trigger = "cc", value = "VALUE", description = "Choose a C/C++ compiler set", allowed = { { "clang", "Clang (clang)" }, { "gcc", "GNU GCC (gcc/g++)" }, } } newoption { trigger = "dotnet", value = "VALUE", description = "Choose a .NET compiler set", allowed = { { "msnet", "Microsoft .NET (csc)" }, { "mono", "Novell Mono (mcs)" }, { "pnet", "Portable.NET (cscc)" }, } } newoption { trigger = "fatal", description = "Treat warnings from project scripts as errors" } newoption { trigger = "file", value = "FILE", description = "Read FILE as a Premake script; default is 'premake5.lua'" } newoption { trigger = "help", description = "Display this information" } newoption { trigger = "verbose", description = "Generate extra debug text output" } newoption { trigger = "interactive", description = "Interactive command prompt" } newoption { trigger = "os", value = "VALUE", description = "Generate files for a different operating system", allowed = { { "aix", "IBM AIX" }, { "bsd", "OpenBSD, NetBSD, or FreeBSD" }, { "haiku", "Haiku" }, { "hurd", "GNU/Hurd" }, { "linux", "Linux" }, { "macosx", "Apple Mac OS X" }, { "solaris", "Solaris" }, { "windows", "Microsoft Windows" }, } } newoption { trigger = "scripts", value = "PATH", description = "Search for additional scripts on the given path" } newoption { trigger = "systemscript", value = "FILE", description = "Override default system script (premake5-system.lua)" } newoption { trigger = "version", description = "Display version information" } characterset "Default" clr "Off" editorintegration "Off" exceptionhandling "Default" rtti "Default" language "C++" filter { "kind:SharedLib" } targetprefix "lib" targetextension ".so" filter { "kind:StaticLib" } targetprefix "lib" targetextension ".a" filter { "system:MacOSX", "kind:SharedLib" } targetextension ".dylib" filter { "system:Windows or language:C#", "kind:ConsoleApp or WindowedApp" } targetextension ".exe" filter { "system:Xbox360", "kind:ConsoleApp or WindowedApp" } targetextension ".exe" filter { "system:Windows or Xbox360", "kind:SharedLib" } targetprefix "" targetextension ".dll" implibextension ".lib" filter { "system:Windows or Xbox360", "kind:StaticLib" } targetprefix "" targetextension ".lib" filter { "language:C#", "kind:SharedLib" } targetprefix "" targetextension ".dll" implibextension ".dll" filter { "kind:SharedLib", "system:not Windows" } pic "On" filter {} local p = premake newaction { trigger = "codelite", shortname = "CodeLite", description = "Generate CodeLite project files", valid_kinds = { "ConsoleApp", "WindowedApp", "Makefile", "SharedLib", "StaticLib" }, valid_languages = { "C", "C++" }, valid_tools = { cc = { "gcc", "clang", "msc" } }, onWorkspace = function(wks) p.modules.codelite.generateWorkspace(wks) end, onProject = function(prj) p.modules.codelite.generateProject(prj) end, onCleanWorkspace = function(wks) p.modules.codelite.cleanWorkspace(wks) end, onCleanProject = function(prj) p.modules.codelite.cleanProject(prj) end, onCleanTarget = function(prj) p.modules.codelite.cleanTarget(prj) end, } return function(cfg) return (_ACTION == "codelite") end local p = premake p.modules.codelite = {} p.modules.codelite._VERSION = p._VERSION local codelite = p.modules.codelite local project = p.project function codelite.cfgname(cfg) local cfgname = cfg.buildcfg if codelite.workspace.multiplePlatforms then cfgname = string.format("%s|%s", cfg.platform, cfg.buildcfg) end return cfgname end function codelite.esc(value) return value end function codelite.generateWorkspace(wks) p.eol("\r\n") p.indent(" ") p.escaper(codelite.esc) p.generate(wks, ".workspace", codelite.workspace.generate) end function codelite.generateProject(prj) p.eol("\r\n") p.indent(" ") p.escaper(codelite.esc) if project.iscpp(prj) then p.generate(prj, ".project", codelite.project.generate) end end function codelite.cleanWorkspace(wks) p.clean.file(wks, wks.name .. ".workspace") p.clean.file(wks, wks.name .. "_wsp.mk") p.clean.file(wks, wks.name .. ".tags") p.clean.file(wks, ".clang") end function codelite.cleanProject(prj) p.clean.file(prj, prj.name .. ".project") p.clean.file(prj, prj.name .. ".mk") p.clean.file(prj, prj.name .. ".list") p.clean.file(prj, prj.name .. ".out") end function codelite.cleanTarget(prj) end include("codelite_workspace.lua") include("codelite_project.lua") return codelite local p = premake local project = p.project local workspace = p.workspace local tree = p.tree local codelite = p.modules.codelite codelite.workspace = {} local m = codelite.workspace function m.generate(wks) p.utf8() _p('') local tagsdb = "" _p('', wks.name, tagsdb) local tr = workspace.grouptree(wks) tree.traverse(tr, { onleaf = function(n) local prj = n.project local prjpath = p.filename(prj, ".project") prjpath = path.translate(path.getrelative(prj.workspace.location, prjpath)) local active = iif(prj.name == wks.startproject, ' Active="Yes"', '') _x(1, '', prj.name, prjpath, active) end, onbranch = function(n) end, }) local platformsPresent = {} local numPlatforms = 0 for cfg in workspace.eachconfig(wks) do local platform = cfg.platform if platform and not platformsPresent[platform] then numPlatforms = numPlatforms + 1 platformsPresent[platform] = true end end if numPlatforms >= 2 then codelite.workspace.multiplePlatforms = true end _p(1, '') for cfg in workspace.eachconfig(wks) do local cfgname = codelite.cfgname(cfg) _p(2, '', cfgname) local tr = workspace.grouptree(wks) tree.traverse(tr, { onleaf = function(n) local prj = n.project _p(3, '', prj.name, cfgname) end }) _p(2, '') end _p(1, '') _p('') end local p = premake local tree = p.tree local project = p.project local config = p.config local codelite = p.modules.codelite codelite.project = {} local m = codelite.project function codelite.getLinks(cfg) return config.getlinks(cfg, "system", "fullpath") end function codelite.getSiblingLinks(cfg) return config.getlinks(cfg, "siblings", "fullpath") end m.elements = {} m.ctools = { gcc = "gnu gcc", clang = "clang", msc = "Visual C++", } m.cxxtools = { gcc = "gnu g++", clang = "clang++", msc = "Visual C++", } function m.getcompilername(cfg) local tool = _OPTIONS.cc or cfg.toolset or p.CLANG local toolset = p.tools[tool] if not toolset then error("Invalid toolset '" + (_OPTIONS.cc or cfg.toolset) + "'") end if cfg.language == "C" then return m.ctools[tool] elseif cfg.language == "C++" then return m.cxxtools[tool] end end function m.getcompiler(cfg) local toolset = p.tools[_OPTIONS.cc or cfg.toolset or p.CLANG] if not toolset then error("Invalid toolset '" + (_OPTIONS.cc or cfg.toolset) + "'") end return toolset end local function configuration_iscustombuild(cfg) return cfg and (cfg.kind == p.MAKEFILE) and (#cfg.buildcommands > 0) end local function configuration_isfilelist(cfg) return cfg and (cfg.buildaction == "None") and not configuration_iscustombuild(cfg) end local function configuration_needresoptions(cfg) return cfg and config.findfile(cfg, ".rc") and not configuration_iscustombuild(cfg) end m.internalTypeMap = { ConsoleApp = "Console", WindowedApp = "Console", Makefile = "", SharedLib = "Library", StaticLib = "Library" } function m.header(prj) _p('') local type = m.internalTypeMap[prj.kind] or "" _x('', prj.name, type) end function m.plugins(prj) _p(1, '') end function m.description(prj) _p(1, '') end function m.files(prj) local tr = project.getsourcetree(prj) tree.traverse(tr, { onbranchenter = function(node, depth) _p(depth, '', node.name) end, onbranchexit = function(node, depth) _p(depth, '') end, onleaf = function(node, depth) _p(depth, '', node.relpath) end, }, false, 1) end function m.dependencies(prj) local dependencies = project.getdependencies(prj) for cfg in project.eachconfig(prj) do cfgname = codelite.cfgname(cfg) if #dependencies > 0 then _p(1, '', cfgname) for _, dependency in ipairs(dependencies) do _p(2, '', dependency.name) end _p(1, '') else _p(1, '', cfgname) end end end function m.global_compiler(prj) _p(3, '') _p(4, '') _p(3, '') end function m.global_linker(prj) _p(3, '') _p(4, '') _p(3, '') end function m.global_resourceCompiler(prj) _p(3, '') end m.elements.globalSettings = function(prj) return { m.global_compiler, m.global_linker, m.global_resourceCompiler, } end function m.compiler(cfg) if configuration_iscustombuild(cfg) or configuration_isfilelist(cfg) then _p(3, '') return end local toolset = m.getcompiler(cfg) local cxxflags = table.concat(table.join(toolset.getcflags(cfg), toolset.getcxxflags(cfg), cfg.buildoptions), ";") local cflags = table.concat(table.join(toolset.getcflags(cfg), cfg.buildoptions), ";") local asmflags = "" local pch = "" _x(3, '', cxxflags, cflags, asmflags, pch) for _, includedir in ipairs(cfg.includedirs) do _x(4, '', project.getrelative(cfg.project, includedir)) end for _, define in ipairs(cfg.defines) do _x(4, '', define) end _p(3, '') end function m.linker(cfg) if configuration_iscustombuild(cfg) or configuration_isfilelist(cfg) then _p(3, '') return end local toolset = m.getcompiler(cfg) local flags = table.join(toolset.getldflags(cfg), cfg.linkoptions) local withdeps = table.join(flags, codelite.getSiblingLinks(cfg)) local ldflags = table.concat(withdeps, ";") _x(3, '', ldflags) if #cfg.libdirs > 0 then local libdirs = project.getrelative(cfg.project, cfg.libdirs) for _, libpath in ipairs(libdirs) do _x(4, '', libpath) end end local links = codelite.getLinks(cfg) for _, libname in ipairs(links) do _x(4, '', libname) end _p(3, '') end function m.resourceCompiler(cfg) if not configuration_needresoptions(cfg) then _p(3, '') return end local toolset = m.getcompiler(cfg) local defines = table.implode(toolset.getdefines(table.join(cfg.defines, cfg.resdefines)), "", ";", "") local options = table.concat(cfg.resoptions, ";") _x(3, '', defines, options) for _, includepath in ipairs(table.join(cfg.includedirs, cfg.resincludedirs)) do _x(4, '', project.getrelative(cfg.project, includepath)) end _p(3, '') end function m.general(cfg) if configuration_isfilelist(cfg) then _p(3, '') return end local prj = cfg.project local isExe = prj.kind == "WindowedApp" or prj.kind == "ConsoleApp" local targetpath = project.getrelative(prj, cfg.buildtarget.directory) local objdir = project.getrelative(prj, cfg.objdir) local targetname = project.getrelative(prj, cfg.buildtarget.abspath) local command = iif(isExe, targetname, "") local cmdargs = iif(isExe, table.concat(cfg.debugargs, " "), "") -- TODO: should this be debugargs instead? local useseparatedebugargs = "no" local debugargs = "" local workingdir = iif(isExe, project.getrelative(prj, cfg.debugdir), "") local pauseexec = iif(prj.kind == "ConsoleApp", "yes", "no") local isguiprogram = iif(prj.kind == "WindowedApp", "yes", "no") local isenabled = iif(cfg.flags.ExcludeFromBuild, "no", "yes") _x(3, '', targetname, objdir, command, cmdargs, useseparatedebugargs, debugargs, workingdir, pauseexec, isguiprogram, isenabled) end function m.environment(cfg) _p(3, '') local variables = "" _x(4, '', variables) _p(3, '') end function m.debugger(cfg) _p(3, '', iif(cfg.debugremotehost, "yes", "no"), cfg.debugremotehost or "", iif(cfg.debugport, tostring(cfg.debugport), ""), iif(cfg.debugextendedprotocol, "yes", "no")) if #cfg.debugsearchpaths > 0 then _p(4, '%s', table.concat(premake.esc(project.getrelative(cfg.project, cfg.debugsearchpaths)), "\n")) else _p(4, '') end if #cfg.debugconnectcommands > 0 then _p(4, '%s', table.concat(premake.esc(cfg.debugconnectcommands), "\n")) else _p(4, '') end if #cfg.debugstartupcommands > 0 then _p(4, '%s', table.concat(premake.esc(cfg.debugstartupcommands), "\n")) else _p(4, '') end _p(3, '') end function m.preBuild(cfg) if #cfg.prebuildcommands > 0 then _p(3, '') for _, commands in ipairs(cfg.prebuildcommands) do _x(4, '%s', p.esc(commands)) end _p(3, '') end end function m.postBuild(cfg) if #cfg.postbuildcommands > 0 then _p(3, '') for _, commands in ipairs(cfg.postbuildcommands) do _x(4, '%s', p.esc(commands)) end _p(3, '') end end function m.customBuild(cfg) if not configuration_iscustombuild(cfg) then _p(3, '') return end local build = table.implode(cfg.buildcommands,"","","") local clean = table.implode(cfg.cleancommands,"","","") local rebuild = table.implode(cfg.rebuildcommands,"","","") _p(3, '') _x(4, '%s', build) _x(4, '%s', clean) _x(4, '%s', rebuild) _p(4, '') _p(4, '') _p(4, '') _p(4, '') _p(4, '') _p(3, '') end function m.additionalRules(cfg) if configuration_iscustombuild(cfg) then _p(3, '') return end _p(3, '') _p(4, '') _p(4, '') _p(3, '') end function m.completion(cfg) _p(3, '', iif(cfg.flags["C++11"], "yes", "no"), iif(cfg.flags["C++14"], "yes", "no")) _p(4, '') _p(4, '') _p(4, '') -- TODO: we might want to set special code completion macros...? _p(4, '') -- TODO: search paths for code completion? _p(3, '') end m.elements.settings = function(cfg) return { m.compiler, m.linker, m.resourceCompiler, m.general, m.environment, m.debugger, m.preBuild, m.postBuild, m.customBuild, m.additionalRules, m.completion, } end m.types = { ConsoleApp = "Executable", Makefile = "", SharedLib = "Dynamic Library", StaticLib = "Static Library", WindowedApp = "Executable" } m.debuggers = { Default = "GNU gdb debugger", GDB = "GNU gdb debugger", LLDB = "LLDB Debugger", } function m.settings(prj) _p(1, '', m.types[prj.kind] or "") _p(2, '') p.callArray(m.elements.globalSettings, prj) _p(2, '') for cfg in project.eachconfig(prj) do local cfgname = codelite.cfgname(cfg) local compiler = m.getcompilername(cfg) local debugger = m.debuggers[cfg.debugger] or m.debuggers.Default local type = m.types[cfg.kind] _x(2, '', cfgname, compiler, debugger, type) p.callArray(m.elements.settings, cfg) _p(2, '') end _p(1, '') end m.elements.project = function(prj) return { m.header, m.plugins, m.description, m.files, m.dependencies, m.settings, } end function m.generate(prj) p.utf8() p.callArray(m.elements.project, prj) _p('') end local p = premake local api = p.api p.D = "D" api.addAllowed("language", p.D) api.addAllowed("floatingpoint", "None") api.addAllowed("flags", { "CodeCoverage", "Deprecated", "Documentation", "GenerateHeader", "GenerateJSON", "GenerateMap", "NoBoundsCheck", "Profile", "Quiet", "RetainPaths", "SeparateCompilation", "SymbolsLikeC", "UnitTest", "Verbose", }) api.register { name = "versionconstants", scope = "config", kind = "list:string", tokens = true, } api.register { name = "versionlevel", scope = "config", kind = "integer", } api.register { name = "debugconstants", scope = "config", kind = "list:string", tokens = true, } api.register { name = "debuglevel", scope = "config", kind = "integer", } api.register { name = "docdir", scope = "config", kind = "path", tokens = true, } api.register { name = "docname", scope = "config", kind = "string", tokens = true, } api.register { name = "headerdir", scope = "config", kind = "path", tokens = true, } api.register { name = "headername", scope = "config", kind = "string", tokens = true, } newoption { trigger= "dc", value= "VALUE", description= "Choose a D compiler", allowed = { { "dmd", "Digital Mars (dmd)" }, { "gdc", "GNU GDC (gdc)" }, { "ldc", "LLVM LDC (ldc2)" }, } } return function (cfg) return (cfg.language == p.D) end local p = premake p.modules.d = {} local m = p.modules.d m._VERSION = p._VERSION m.elements = {} local api = p.api function p.project.isd(prj) return prj.language == premake.D end function path.isdfile(fname) return path.hasextension(fname, { ".d", ".di" }) end include( "tools/dmd.lua" ) include( "tools/gdc.lua" ) include( "tools/ldc.lua" ) include( "actions/gmake.lua" ) include( "actions/vstudio.lua" ) if p.modules.monodevelop then include( "actions/monodev.lua" ) end return m local p = premake local m = p.modules.d m.make = {} local dmake = m.make local make = p.make local cpp = p.make.cpp local project = p.project local config = p.config local fileconfig = p.fileconfig local gmake = p.action.get( 'gmake' ) if gmake == nil then error( "Failed to locate prequisite action 'gmake'" ) end gmake.valid_languages = table.join(gmake.valid_languages, { p.D } ) gmake.valid_tools.dc = { "dmd", "gdc", "ldc" } function m.make.separateCompilation(prj) local some = false local all = true for cfg in project.eachconfig(prj) do if cfg.flags.SeparateCompilation then some = true else all = false end end return iif(all, "all", iif(some, "some", "none")) end p.override( gmake, "onProject", function(oldfn, prj) p.escaper(make.esc) if project.isd(prj) then local makefile = make.getmakefilename(prj, true) p.generate(prj, makefile, m.make.generate) return end oldfn(prj) end) p.override( make, "objdir", function(oldfn, cfg) if cfg.project.language ~= "D" or cfg.flags.SeparateCompilation then oldfn(cfg) end end) p.override( make, "objDirRules", function(oldfn, prj) if prj.language ~= "D" or m.make.separateCompilation(prj) ~= "none" then oldfn(prj) end end) m.elements = {} m.elements.makefile = function(prj) return { make.header, make.phonyRules, m.make.configs, m.make.objects,-- TODO: This is basically identical to make.cppObjects(), and should ideally be merged/shared make.shellType, m.make.targetRules, make.targetDirRules, make.objDirRules, make.cppCleanRules,-- D clean code is identical to C/C++ make.preBuildRules, make.preLinkRules, m.make.dFileRules, } end function m.make.generate(prj) p.callArray(m.elements.makefile, prj) end function m.make.buildRule(prj) _p('$(TARGET): $(SOURCEFILES) $(LDDEPS)') _p('\t@echo Building %s', prj.name) _p('\t$(SILENT) $(BUILDCMD)') _p('\t$(POSTBUILDCMDS)') end function m.make.linkRule(prj) _p('$(TARGET): $(OBJECTS) $(LDDEPS)') _p('\t@echo Linking %s', prj.name) _p('\t$(SILENT) $(LINKCMD)') _p('\t$(POSTBUILDCMDS)') end function m.make.targetRules(prj) local separateCompilation = m.make.separateCompilation(prj) if separateCompilation == "all" then m.make.linkRule(prj) elseif separateCompilation == "none" then m.make.buildRule(prj) else for cfg in project.eachconfig(prj) do _x('ifeq ($(config),%s)', cfg.shortname) if cfg.flags.SeparateCompilation then m.make.linkRule(prj) else m.make.buildRule(prj) end _p('endif') end end _p('') end function m.make.dFileRules(prj) local separateCompilation = m.make.separateCompilation(prj) if separateCompilation ~= "none" then make.cppFileRules(prj) end end p.override(cpp, "standardFileRules", function(oldfn, prj, node) if path.isdfile(node.abspath) then _x('$(OBJDIR)/%s.o: %s', node.objname, node.relpath) _p('\t@echo $(notdir $<)') _p('\t$(SILENT) $(DC) $(ALL_DFLAGS) $(OUTPUTFLAG) -c $<') else oldfn(prj, node) end end) m.elements.makeconfig = function(cfg) return { m.make.dTools, make.target, m.make.target, make.objdir, m.make.versions, m.make.debug, m.make.imports, m.make.dFlags, make.libs, make.ldDeps, make.ldFlags, m.make.linkCmd, make.preBuildCmds, make.preLinkCmds, make.postBuildCmds, m.make.allRules, make.settings, } end function m.make.configs(prj) for cfg in project.eachconfig(prj) do local toolset = p.tools[_OPTIONS.dc or cfg.toolset or "dmd"] if not toolset then error("Invalid toolset '" + (_OPTIONS.dc or cfg.toolset) + "'") end _x('ifeq ($(config),%s)', cfg.shortname) p.callArray(m.elements.makeconfig, cfg, toolset) _p('endif') _p('') end end function m.make.dTools(cfg, toolset) local tool = toolset.gettoolname(cfg, "dc") if tool then _p(' DC = %s', tool) end end function m.make.target(cfg, toolset) if cfg.flags.SeparateCompilation then _p(' OUTPUTFLAG = %s', toolset.gettarget('"$@"')) end end function m.make.versions(cfg, toolset) _p(' VERSIONS +=%s', make.list(toolset.getversions(cfg.versionconstants, cfg.versionlevel))) end function m.make.debug(cfg, toolset) _p(' DEBUG +=%s', make.list(toolset.getdebug(cfg.debugconstants, cfg.debuglevel))) end function m.make.imports(cfg, toolset) local includes = p.esc(toolset.getimportdirs(cfg, cfg.includedirs)) _p(' IMPORTS +=%s', make.list(includes)) end function m.make.dFlags(cfg, toolset) _p(' ALL_DFLAGS += $(DFLAGS)%s $(VERSIONS) $(DEBUG) $(IMPORTS) $(ARCH)', make.list(table.join(toolset.getdflags(cfg), cfg.buildoptions))) end function m.make.linkCmd(cfg, toolset) if cfg.flags.SeparateCompilation then _p(' LINKCMD = $(DC) ' .. toolset.gettarget("$(TARGET)") .. ' $(ALL_LDFLAGS) $(LIBS) $(OBJECTS)') else _p(' BUILDCMD = $(DC) ' .. toolset.gettarget("$(TARGET)") .. ' $(ALL_DFLAGS) $(ALL_LDFLAGS) $(LIBS) $(SOURCEFILES)') end end function m.make.allRules(cfg, toolset) if cfg.flags.SeparateCompilation then _p('all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)') else _p('all: $(TARGETDIR) prebuild prelink $(TARGET)') end _p('\t@:') end function m.make.objects(prj) local root = { sourcefiles={}, objects={} } local configs = {} for cfg in project.eachconfig(prj) do configs[cfg] = { sourcefiles={}, objects={} } end local tr = project.getsourcetree(prj) p.tree.traverse(tr, { onleaf = function(node, depth) local incfg = {} local inall = true local custom = false for cfg in project.eachconfig(prj) do local filecfg = fileconfig.getconfig(node, cfg) if filecfg and not filecfg.flags.ExcludeFromBuild then incfg[cfg] = filecfg custom = fileconfig.hasCustomBuildRule(filecfg) else inall = false end end if not custom then if not path.isdfile(node.abspath) then return end local sourcename = node.relpath local objectname = "$(OBJDIR)/" .. node.objname .. ".o" if inall then table.insert(root.sourcefiles, sourcename) table.insert(root.objects, objectname) else for cfg in project.eachconfig(prj) do if incfg[cfg] then table.insert(configs[cfg].sourcefiles, sourcename) table.insert(configs[cfg].objects, objectname) end end end else for cfg in project.eachconfig(prj) do local filecfg = incfg[cfg] if filecfg then local output = project.getrelative(prj, filecfg.buildoutputs[1]) if path.isobjectfile(output) then table.insert(configs[cfg].objects, output) end end end end end }) local separateCompilation = m.make.separateCompilation(prj) function listobjects(var, list) _p('%s \\', var) for _, objectname in ipairs(list) do _x('\t%s \\', objectname) end _p('') end if separateCompilation ~= "all" then listobjects('SOURCEFILES :=', root.sourcefiles) end if separateCompilation ~= "none" then listobjects('OBJECTS :=', root.objects, 'o') end for cfg in project.eachconfig(prj) do local files = configs[cfg] if (#files.sourcefiles > 0 and separateCompilation ~= "all") or (#files.objects > 0 and separateCompilation ~= "none") then _x('ifeq ($(config),%s)', cfg.shortname) if #files.sourcefiles > 0 and separateCompilation ~= "all" then listobjects(' SOURCEFILES +=', files.sourcefiles) end if #files.objects > 0 and separateCompilation ~= "none" then listobjects(' OBJECTS +=', files.objects) end _p('endif') end end _p('') end local p = premake local m = p.modules.d m.monod = {} local monodevelop = p.modules.monodevelop local vstudio = p.vstudio local project = p.project local config = p.config local fileconfig = p.fileconfig local tree = p.tree local md = p.action.get("monodevelop") if md ~= nil then table.insert( md.valid_languages, p.D ) md.valid_tools.dc = { "dmd", "gdc", "ldc" } p.override(md, "onProject", function(oldfn, prj) oldfn(prj) if project.isd(prj) then p.generate(prj, ".dproj", monodevelop.generate) end end) end p.override(vstudio, "projectfile", function(oldfn, prj) if _ACTION == "monodevelop" then if project.isd(prj) then return p.filename(prj, ".dproj") end end return oldfn(prj) end) p.override(vstudio, "tool", function(oldfn, prj) if _ACTION == "monodevelop" then if project.isd(prj) then return "3947E667-4C90-4C3A-BEB9-7148D6FE0D7C" end end return oldfn(prj) end) p.override(monodevelop, "getTargetGroup", function(oldfn, node, prj, groups) if project.isd(prj) then local hasbuildrule = false for cfg in project.eachconfig(prj) do local filecfg = fileconfig.getconfig(node, cfg) if filecfg and fileconfig.hasCustomBuildRule(filecfg) then hasbuildrule = true break end end if hasbuildrule then return groups.CustomBuild elseif path.isdfile(node.name) then return groups.Compile elseif path.isresourcefile(node.name) then return groups.ResourceCompile else return groups.None end else return oldfn(node, prj, groups) end end) p.override(monodevelop.elements, "projectProperties", function(oldfn, prj) if project.isd(prj) then return { monodevelop.cproj.projectGuid, m.monod.useDefaultCompiler, m.monod.incrementalLinking, m.monod.preferOneStepBuild, m.monod.compiler, monodevelop.cproj.version, monodevelop.cproj.synchWksVersion, monodevelop.cproj.description, } end return oldfn(prj) end) function m.monod.useDefaultCompiler(prj) _p(2,'%s', iif(_OPTIONS.dc, 'false', 'true')) end function m.monod.incrementalLinking(prj) _p(2,'true') end function m.monod.preferOneStepBuild(prj) _p(2,'true') end function m.monod.baseDirectory(prj) _p(2,'.') end function m.monod.compiler(prj) local compiler = { dmd="DMD2", gdc="GDC", ldc="ldc2" } _p(2,'%s', compiler[_OPTIONS.dc or "dmd"]) end p.override(monodevelop.elements, "configurationProperties", function(oldfn, cfg) if project.isd(cfg.project) then return { monodevelop.cproj.debuginfo, monodevelop.cproj.outputPath, m.monod.unittestMode, m.monod.objectsDirectory, -- TODO: should this be moved into the .cproj options? m.monod.debugLevel, monodevelop.cproj.externalconsole, m.monod.target, m.monod.thirdParty, monodevelop.cproj.outputName, m.monod.additionalOptions, m.monod.dDocDirectory, m.monod.versionIds, m.monod.debugIds, monodevelop.cproj.additionalLinkOptions, monodevelop.cproj.additionalDependencies, monodevelop.cproj.buildEvents, } end return oldfn(cfg) end) function m.monod.unittestMode(cfg) _p(2,'%s', iif(cfg.flags.UnitTest, 'true', 'false')) end function m.monod.objectsDirectory(cfg) local objdir = project.getrelative(cfg.project, cfg.objdir) _p(2,'%s', path.translate(objdir)) end function m.monod.debugLevel(cfg) _p(2,'%d', iif(cfg.debuglevel, cfg.debuglevel, 0)) end function m.monod.target(cfg) local map = { SharedLib = "SharedLibrary", StaticLib = "StaticLibrary", ConsoleApp = "Executable", WindowedApp = "Executable" } _p(2,'%s', map[cfg.kind]) end function m.monod.thirdParty(cfg) local linkThirdParty = "false" _p(2,'%s', linkThirdParty) end function m.monod.additionalOptions(cfg) local opts = { } local options if #opts > 0 then options = table.concat(opts, " ") end if #cfg.buildoptions > 0 then local buildOpts = table.concat(cfg.buildoptions, " ") options = (options and options .. " " .. buildOpts) or buildOpts end if options then _x(2,'%s', options) end end function m.monod.dDocDirectory(cfg) if cfg.docdir then local docdir = project.getrelative(cfg.project, cfg.docdir) _x(2,'%s', path.translate(docdir)) end end function m.monod.versionIds(cfg) if #cfg.versionconstants > 0 then _x(2,'') _x(3,'') for _, v in ipairs(cfg.versionconstants) do _x(4,'%s', v) end _x(3,'') _x(2,'') end end function m.monod.debugIds(cfg) if #cfg.debugconstants > 0 then _x(2,'') _x(3,'') for _, d in ipairs(cfg.debugconstants) do _x(4,'%s', d) end _x(3,'') _x(2,'') end end local p = premake local m = p.modules.d m.visuald = {} local vstudio = p.vstudio local workspace = p.workspace local project = p.project local config = p.config local tree = p.tree for k,v in pairs({ "vs2005", "vs2008", "vs2010", "vs2012", "vs2013", "vs2015" }) do local vs = p.action.get(v) if vs ~= nil then table.insert( vs.valid_languages, p.D ) vs.valid_tools.dc = { "dmd", "gdc", "ldc" } p.override(vs, "onProject", function(oldfn, prj) oldfn(prj) if project.isd(prj) then p.generate(prj, ".visualdproj", m.visuald.generate) end end) end end p.override(project, "isnative", function(oldfn, prj) return project.isd(prj) or oldfn(prj) end) p.override(vstudio, "projectfile", function(oldfn, prj) if project.isd(prj) then return p.filename(prj, ".visualdproj") end return oldfn(prj) end) p.override(vstudio, "tool", function(oldfn, prj) if project.isd(prj) then return "002A2DE9-8BB6-484D-9802-7E4AD4084715" end return oldfn(prj) end) m.elements.project = function(prj) return { m.visuald.header, m.visuald.globals, m.visuald.projectConfigurations, m.visuald.files, } end function m.visuald.generate(prj) p.eol("\r\n") p.indent(" ") p.callArray(m.elements.project, prj) _p('') end function m.visuald.header(prj) _p('') end function m.visuald.globals(prj) _p(1,'{%s}', prj.uuid) end function m.visuald.projectConfigurations(prj) for cfg in project.eachconfig(prj) do local prjPlatform = p.esc(vstudio.projectPlatform(cfg)) local slnPlatform = vstudio.solutionPlatform(cfg) local is64bit = slnPlatform == "x64" -- TODO: this seems like a hack _p(1,'', prjPlatform, slnPlatform) _p(2,'0') _p(2,'0') local isWindows = false local isDebug = string.find(cfg.buildcfg, 'Debug') ~= nil local isOptimised = config.isOptimizedBuild(cfg) if cfg.kind == p.CONSOLEAPP then _p(2,'0') _p(2,'1') elseif cfg.kind == p.STATICLIB then _p(2,'1') _p(2,'0') elseif cfg.kind == p.SHAREDLIB then _p(2,'2') _p(2,'0') -- SHOULD THIS BE '2' (windows)?? else _p(2,'0') _p(2,'2') isWindows = true end _p(2,'0') _p(2,'0') _p(2,'0') _p(2,'%s', iif(cfg.flags.Profile, '1', '0')) _p(2,'%s', iif(cfg.flags.Quiet, '1', '0')) _p(2,'%s', iif(cfg.flags.Verbose, '1', '0')) _p(2,'0') _p(2,'%s', iif(cfg.flags.Symbols or cfg.flags.SymbolsLikeC, iif(cfg.flags.SymbolsLikeC, '2', '1'), '0')) _p(2,'%s', iif(isOptimised, '1', '0')) _p(2,'0') _p(2,'%s', iif(is64bit, '1', '0')) _p(2,'0') _p(2,'0') _p(2,'%s', iif(isWindows, '1', '0')) _p(2,'0') _p(2,'0') _p(2,'0') _p(2,'%s', iif(cfg.flags.Deprecated, '1', '0')) _p(2,'0') _p(2,'0') _p(2,'0') _p(2,'0') _p(2,'0') _p(2,'0') _p(2,'%s', iif(cfg.flags.NoBoundsCheck, '1', '0')) _p(2,'0') _p(2,'%s', iif(cfg.flags.UnitTest, '1', '0')) _p(2,'%s', iif(cfg.flags.Inline or isOptimised, '1', '0')) _p(2,'%s', iif(cfg.flags.Release or not isDebug, '1', '0')) _p(2,'0') _p(2,'%s', iif(cfg.flags.FatalCompileWarnings, '1', '0')) _p(2,'%s', iif(cfg.warnings and cfg.warnings ~= "Off", '1', '0')) _p(2,'0') _p(2,'0') _p(2,'%s', iif(cfg.pic == "On", '1', '0')) _p(2,'%s', iif(cfg.flags.CodeCoverage, '1', '0')) _p(2,'%s', iif(cfg.floatingpoint and cfg.floatingpoint == "None", '1', '0')) _p(2,'2') _p(2,'0') local compiler = { dmd="0", gdc="1", ldc="2" } m.visuald.element(2, "compiler", compiler[_OPTIONS.dc or cfg.toolset or "dmd"]) m.visuald.element(2, "otherDMD", '0') m.visuald.element(2, "program", '$(DMDInstallDir)windows\\bin\\dmd.exe') m.visuald.element(2, "imppath", cfg.includedirs) m.visuald.element(2, "fileImppath") m.visuald.element(2, "outdir", path.translate(project.getrelative(cfg.project, cfg.buildtarget.directory))) m.visuald.element(2, "objdir", path.translate(project.getrelative(cfg.project, cfg.objdir))) m.visuald.element(2, "objname") m.visuald.element(2, "libname") m.visuald.element(2, "doDocComments", iif(cfg.flags.Documentation, '1', '0')) m.visuald.element(2, "docdir", cfg.docdir) m.visuald.element(2, "docname", cfg.docname) m.visuald.element(2, "modules_ddoc") m.visuald.element(2, "ddocfiles") m.visuald.element(2, "doHdrGeneration", iif(cfg.flags.GenerateHeader, '1', '0')) m.visuald.element(2, "hdrdir", cfg.headerdir) m.visuald.element(2, "hdrname", cfg.headername) m.visuald.element(2, "doXGeneration", iif(cfg.flags.GenerateJSON, '1', '0')) m.visuald.element(2, "xfilename", '$(IntDir)\\$(TargetName).json') m.visuald.element(2, "debuglevel", iif(cfg.debuglevel, tostring(cfg.debuglevel), '0')) m.visuald.element(2, "debugids", cfg.debugconstants) m.visuald.element(2, "versionlevel", iif(cfg.versionlevel, tostring(cfg.versionlevel), '0')) m.visuald.element(2, "versionids", cfg.versionconstants) _p(2,'0') _p(2,'0') _p(2,'%s', iif(cfg.kind ~= p.SHAREDLIB or cfg.flags.NoImportLib, '0', '1')) _p(2,'') _p(2,'') _p(2,'') _p(2,'0') _p(2,'') _p(2,'1') -- we will just leave this always enabled, since it's ignored if no debuginfo is written _p(2,'$(VisualDInstallDir)cv2pdb\\cv2pdb.exe') _p(2,'0') _p(2,'0') _p(2,'0') _p(2,'') _p(2,'') _p(2,'') local links local explicit = vstudio.needsExplicitLink(cfg) local toolset = config.toolset(cfg) if toolset then links = toolset.getlinks(cfg, not explicit) else local scope = iif(explicit, "all", "system") links = config.getlinks(cfg, scope, "fullpath") end m.visuald.element(2, "libfiles", table.concat(links, " ")) m.visuald.element(2, "libpaths", cfg.libdirs) _p(2,'') _p(2,'') local target = config.gettargetinfo(cfg) _p(2,'$(OutDir)\\%s', target.name) _p(2,'1') local runtime = 0 if not cfg.flags.OmitDefaultLibrary then if config.isDebugBuild(cfg) then runtime = iif(cfg.flags.StaticRuntime, "2", "4") else runtime = iif(cfg.flags.StaticRuntime, "1", "3") end end m.visuald.element(2, "cRuntime", runtime) local additionalOptions if #cfg.buildoptions > 0 then additionalOptions = table.concat(cfg.buildoptions, " ") end if #cfg.linkoptions > 0 then local linkOpts = table.implode(cfg.linkoptions, "-L", "", " ") if additionalOptions then additionalOptions = additionalOptions .. " " .. linkOpts else additionalOptions = linkOpts end end m.visuald.element(2, "additionalOptions", additionalOptions) if #cfg.prebuildcommands > 0 then _p(2,'%s',p.esc(table.implode(cfg.prebuildcommands, "", "", "\r\n"))) else _p(2,'') end if #cfg.postbuildcommands > 0 then _p(2,'%s',p.esc(table.implode(cfg.postbuildcommands, "", "", "\r\n"))) else _p(2,'') end _p(2,'*.obj;*.cmd;*.build;*.json;*.dep;*.o') _p(1,'') end end function m.visuald.files(prj) _p(1,'', prj.name) local tr = project.getsourcetree(prj) tree.traverse(tr, { onbranchenter = function(node, depth) _p(depth, '', node.name) end, onbranchexit = function(node, depth) _p(depth, '') end, onleaf = function(node, depth) _p(depth, '', path.translate(node.relpath)) end }, false, 2) _p(1,'') end function m.visuald.fileConfiguration(prj, node, depth) end function m.visuald.element(depth, name, value, ...) local isTable = type(value) == "table" if not value or (isTable and #value == 0) then _p(depth, '<%s />', name) else if isTable then value = p.esc(table.implode(value, "", "", ";")) _p(depth, '<%s>%s', name, value, name) else if select('#',...) == 0 then value = p.esc(value) end _x(depth, string.format('<%s>%s', name, value, name), ...) end end end local tdmd = {} local project = premake.project local config = premake.config local d = premake.modules.d tdmd.gcc = {} tdmd.gcc.dc = "dmd" tdmd.optlink = {} tdmd.optlink.dc = "dmd" tdmd.gcc.ldflags = { architecture = { x86 = { "-m32" }, x86_64 = { "-m64" }, }, kind = { SharedLib = "-shared", StaticLib = "-lib", } } function tdmd.gcc.getldflags(cfg) local flags = config.mapFlags(cfg, tdmd.gcc.ldflags) return flags end tdmd.gcc.libraryDirectories = { architecture = { x86 = "-L-L/usr/lib", x86_64 = "-L-L/usr/lib64", } } function tdmd.gcc.getLibraryDirectories(cfg) local flags = config.mapFlags(cfg, tdmd.gcc.libraryDirectories) for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do table.insert(flags, '-L-L' .. project.getrelative(cfg.project, dir)) end return flags end function tdmd.gcc.getlinks(cfg, systemonly) local result = {} local links if not systemonly then links = config.getlinks(cfg, "siblings", "object") for _, link in ipairs(links) do if not link.project.external then if link.kind == premake.STATICLIB then table.insert(result, "-L" .. project.getrelative(cfg.project, link.linktarget.abspath)) else table.insert(result, "-L-l" .. link.linktarget.basename) end end end end links = config.getlinks(cfg, "system", "fullpath") for _, link in ipairs(links) do if path.isframework(link) then table.insert(result, "-framework " .. path.getbasename(link)) elseif path.isobjectfile(link) then table.insert(result, "-L" .. link) else table.insert(result, "-L-l" .. path.getbasename(link)) end end return result end tdmd.optlink.ldflags = { architecture = { x86 = { "-m32" }, x86_64 = { "-m64" }, }, kind = { SharedLib = "-shared", StaticLib = "-lib", } } function tdmd.optlink.getldflags(cfg) local flags = config.mapFlags(cfg, tdmd.optlink.ldflags) return flags end function tdmd.optlink.getLibraryDirectories(cfg) local flags = {} for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do table.insert(flags, '-Llib "' .. project.getrelative(cfg.project, dir) .. '"') end return flags end function tdmd.optlink.getlinks(cfg) local result = {} local links = config.getlinks(cfg, "dependencies", "object") for _, link in ipairs(links) do if not link.project.externalname then local linkinfo = config.getlinkinfo(link) if link.kind == premake.STATICLIB then table.insert(result, project.getrelative(cfg.project, linkinfo.abspath)) end end end links = config.getlinks(cfg, "system", "basename") for _, link in ipairs(links) do if path.isobjectfile(link) then table.insert(result, link) elseif path.hasextension(link, premake.systems[cfg.system].staticlib.extension) then table.insert(result, link) end end return result end if string.match( os.getversion().description, "Windows" ) ~= nil then premake.tools.dmd = tdmd.optlink else premake.tools.dmd = tdmd.gcc end local dmd = premake.tools.dmd dmd.dflags = { architecture = { x86 = "-m32", x86_64 = "-m64", }, flags = { CodeCoverage= "-cov", Deprecated= "-d", Documentation= "-D", FatalWarnings= "-w", GenerateHeader= "-H", GenerateJSON= "-X", GenerateMap= "-map", NoBoundsCheck= "-noboundscheck", Profile= "-profile", Quiet= "-quiet", RetainPaths= "-op", Symbols= "-g", SymbolsLikeC= "-gc", UnitTest= "-unittest", Verbose= "-v", }, floatingpoint = { None = "-nofloat", }, optimize = { On = "-O -inline", Full = "-O -inline", Size = "-O -inline", Speed = "-O -inline", }, pic = { On = "-fPIC", }, warnings = { Default = "-wi", Extra = "-wi", } } function dmd.getdflags(cfg) local flags = config.mapFlags(cfg, dmd.dflags) if config.isDebugBuild(cfg) then table.insert(flags, "-debug") else table.insert(flags, "-release") end if cfg.flags.Documentation then if cfg.docname then table.insert(flags, "-Df" .. premake.quoted(cfg.docname)) end if cfg.docdir then table.insert(flags, "-Dd" .. premake.quoted(cfg.docdir)) end end if cfg.flags.GenerateHeader then if cfg.headername then table.insert(flags, "-Hf" .. premake.quoted(cfg.headername)) end if cfg.headerdir then table.insert(flags, "-Hd" .. premake.quoted(cfg.headerdir)) end end return flags end function dmd.getversions(versions, level) local result = {} for _, version in ipairs(versions) do table.insert(result, '-version=' .. version) end if level then table.insert(result, '-version=' .. level) end return result end function dmd.getdebug(constants, level) local result = {} for _, constant in ipairs(constants) do table.insert(result, '-debug=' .. constant) end if level then table.insert(result, '-debug=' .. level) end return result end function dmd.getimportdirs(cfg, dirs) local result = {} for _, dir in ipairs(dirs) do dir = project.getrelative(cfg.project, dir) table.insert(result, '-I' .. premake.quoted(dir)) end return result end function dmd.gettarget(name) return "-of" .. name end dmd.makesettings = { } function dmd.getmakesettings(cfg) local settings = config.mapFlags(cfg, dmd.makesettings) return table.concat(settings) end dmd.tools = { } function dmd.gettoolname(cfg, tool) local names = dmd.tools[cfg.architecture] or dmd.tools[cfg.system] or {} local name = names[tool] return name or dmd[tool] end premake.tools.gdc = { } local gdc = premake.tools.gdc local project = premake.project local config = premake.config local d = premake.modules.d gdc.dc = "gdc" gdc.dflags = { architecture = { x86 = "-m32", x86_64 = "-m64", }, flags = { Deprecated= "-fdeprecated", Documentation= "-fdoc", FatalWarnings= "-Werror", GenerateHeader= "-fintfc", GenerateJSON= "-fX", NoBoundsCheck= "-fno-bounds-check", RetainPaths= "-op", Symbols= "-g", SymbolsLikeC= "-fdebug-c", UnitTest= "-funittest", Verbose= "-fd-verbose", }, floatingpoint = { Fast = "-ffast-math", Strict = "-ffloat-store", }, optimize = { Off = "-O0", On = "-O2 -finline-functions", Debug = "-Og", Full = "-O3 -finline-functions", Size = "-Os -finline-functions", Speed = "-O3 -finline-functions", }, pic = { On = "-fPIC", }, vectorextensions = { AVX = "-mavx", SSE = "-msse", SSE2 = "-msse2", }, warnings = { Extra = "-Wall -Wextra", } } function gdc.getdflags(cfg) local flags = config.mapFlags(cfg, gdc.dflags) if config.isDebugBuild(cfg) then table.insert(flags, "-fdebug") else table.insert(flags, "-frelease") end if cfg.flags.Documentation then if cfg.docname then table.insert(flags, "-fdoc-file=" .. premake.quoted(cfg.docname)) end if cfg.docdir then table.insert(flags, "-fdoc-dir=" .. premake.quoted(cfg.docdir)) end end if cfg.flags.GenerateHeader then if cfg.headername then table.insert(flags, "-fintfc-file=" .. premake.quoted(cfg.headername)) end if cfg.headerdir then table.insert(flags, "-fintfc-dir=" .. premake.quoted(cfg.headerdir)) end end return flags end function gdc.getversions(versions, level) local result = {} for _, version in ipairs(versions) do table.insert(result, '-fversion=' .. version) end if level then table.insert(result, '-fversion=' .. level) end return result end function gdc.getdebug(constants, level) local result = {} for _, constant in ipairs(constants) do table.insert(result, '-fdebug=' .. constant) end if level then table.insert(result, '-fdebug=' .. level) end return result end function gdc.getimportdirs(cfg, dirs) local result = {} for _, dir in ipairs(dirs) do dir = project.getrelative(cfg.project, dir) table.insert(result, '-I' .. premake.quoted(dir)) end return result end function gdc.gettarget(name) return "-o " .. name end gdc.ldflags = { architecture = { x86 = { "-m32" }, x86_64 = { "-m64" }, }, kind = { SharedLib = function(cfg) local r = { iif(cfg.system == premake.MACOSX, "-dynamiclib", "-shared") } if cfg.system == "windows" and not cfg.flags.NoImportLib then table.insert(r, '-Wl,--out-implib="' .. cfg.linktarget.relpath .. '"') end return r end, WindowedApp = function(cfg) if cfg.system == premake.WINDOWS then return "-mwindows" end end, }, } function gdc.getldflags(cfg) local flags = config.mapFlags(cfg, gdc.ldflags) return flags end gdc.libraryDirectories = { architecture = { x86 = "-L/usr/lib", x86_64 = "-L/usr/lib64", } } function gdc.getLibraryDirectories(cfg) local flags = config.mapFlags(cfg, gdc.libraryDirectories) for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do table.insert(flags, '-Wl,-L' .. project.getrelative(cfg.project, dir)) end return flags end function gdc.getlinks(cfg, systemonly) local result = {} local links if not systemonly then links = config.getlinks(cfg, "siblings", "object") for _, link in ipairs(links) do if not link.project.external then if link.kind == premake.STATICLIB then table.insert(result, "-Wl," .. project.getrelative(cfg.project, link.linktarget.abspath)) else table.insert(result, "-Wl,-l" .. link.linktarget.basename) end end end end links = config.getlinks(cfg, "system", "fullpath") for _, link in ipairs(links) do if path.isframework(link) then table.insert(result, "-framework " .. path.getbasename(link)) elseif path.isobjectfile(link) then table.insert(result, "-Wl," .. link) else table.insert(result, "-Wl,-l" .. path.getbasename(link)) end end return result end gdc.makesettings = { } function gdc.getmakesettings(cfg) local settings = config.mapFlags(cfg, gdc.makesettings) return table.concat(settings) end gdc.tools = { ps3 = { dc = "ppu-lv2-gdc", ar = "ppu-lv2-ar", }, } function gdc.gettoolname(cfg, tool) local names = gdc.tools[cfg.architecture] or gdc.tools[cfg.system] or {} local name = names[tool] return name or gdc[tool] end premake.tools.ldc = { } local ldc = premake.tools.ldc local project = premake.project local config = premake.config local d = premake.modules.d ldc.namestyle = "posix" ldc.dflags = { architecture = { x86 = "-m32", x86_64 = "-m64", }, flags = { Deprecated= "-d", Documentation= "-D", FatalWarnings= "-w", -- Use LLVM flag? : "-fatal-assembler-warnings", GenerateHeader= "-H", GenerateJSON= "-X", NoBoundsCheck= "-disable-boundscheck", RetainPaths= "-op", Symbols= "-g", SymbolsLikeC= "-gc", UnitTest= "-unittest", Verbose= "-v", }, floatingpoint = { Fast = "-fp-contract=fast -enable-unsafe-fp-math", }, optimize = { Off = "-O0", On = "-O2", Debug = "-O0", Full = "-O3", Size = "-Oz", Speed = "-O3", }, pic = { On = "-relocation-model=pic", }, vectorextensions = { AVX = "-mattr=+avx", SSE = "-mattr=+sse", SSE2 = "-mattr=+sse2", }, warnings = { Default = "-wi", Extra = "-wi",-- TODO: is there a way to get extra warnings? } } function ldc.getdflags(cfg) local flags = config.mapFlags(cfg, ldc.dflags) if config.isDebugBuild(cfg) then table.insert(flags, "-d-debug") else table.insert(flags, "-release") end if cfg.flags.Documentation then if cfg.docname then table.insert(flags, "-Df=" .. premake.quoted(cfg.docname)) end if cfg.docdir then table.insert(flags, "-Dd=" .. premake.quoted(cfg.docdir)) end end if cfg.flags.GenerateHeader then if cfg.headername then table.insert(flags, "-Hf=" .. premake.quoted(cfg.headername)) end if cfg.headerdir then table.insert(flags, "-Hd=" .. premake.quoted(cfg.headerdir)) end end return flags end function ldc.getversions(versions, level) local result = {} for _, version in ipairs(versions) do table.insert(result, '-d-version=' .. version) end if level then table.insert(result, '-d-version=' .. level) end return result end function ldc.getdebug(constants, level) local result = {} for _, constant in ipairs(constants) do table.insert(result, '-d-debug=' .. constant) end if level then table.insert(result, '-d-debug=' .. level) end return result end function ldc.getimportdirs(cfg, dirs) local result = {} for _, dir in ipairs(dirs) do dir = project.getrelative(cfg.project, dir) table.insert(result, '-I=' .. premake.quoted(dir)) end return result end function ldc.gettarget(name) return "-of=" .. name end ldc.ldflags = { architecture = { x86 = { "-m32" }, x86_64 = { "-m64" }, }, kind = { SharedLib = "-shared", StaticLib = "-lib", }, } function ldc.getldflags(cfg) local flags = config.mapFlags(cfg, ldc.ldflags) return flags end ldc.libraryDirectories = { architecture = { x86 = "-L=-L/usr/lib", x86_64 = "-L=-L/usr/lib64", } } function ldc.getLibraryDirectories(cfg) local flags = config.mapFlags(cfg, ldc.libraryDirectories) for _, dir in ipairs(config.getlinks(cfg, "system", "directory")) do table.insert(flags, '-L=-L' .. project.getrelative(cfg.project, dir)) end return flags end function ldc.getlinks(cfg, systemonly) local result = {} local links if not systemonly then links = config.getlinks(cfg, "siblings", "object") for _, link in ipairs(links) do if not link.project.external then if link.kind == premake.STATICLIB then table.insert(result, "-L=" .. project.getrelative(cfg.project, link.linktarget.abspath)) else table.insert(result, "-L=-l" .. link.linktarget.basename) end end end end links = config.getlinks(cfg, "system", "fullpath") for _, link in ipairs(links) do if path.isframework(link) then table.insert(result, "-framework " .. path.getbasename(link)) elseif path.isobjectfile(link) then table.insert(result, "-L=" .. link) else table.insert(result, "-L=-l" .. path.getbasename(link)) end end return result end ldc.makesettings = { } function ldc.getmakesettings(cfg) local settings = config.mapFlags(cfg, ldc.makesettings) return table.concat(settings) end ldc.tools = { dc = "ldc2", ar = "ar", } function ldc.gettoolname(cfg, tool) return ldc.tools[tool] end local p = premake newaction { trigger = "monodevelop", -- TODO: I'd kinda like an alias 'xamarinstudio' aswell... shortname = "MonoDevelop", description = "Generate MonoDevelop/Xamarin Studio project files", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "gcc" }, dotnet = { "mono", "msnet" }, }, onWorkspace = function(wks) p.vstudio.vs2005.generateWorkspace(wks) end, onProject = function(prj) p.modules.monodevelop.generateProject(prj) end, onCleanWorkspace = function(wks) p.vstudio.cleanWorkspace(wks) end, onCleanProject = function(prj) p.vstudio.cleanProject(prj) end, onCleanTarget = function(prj) p.vstudio.cleanTarget(prj) end, vstudio = { csprojSchemaVersion = "2.0", productVersion = "10.0.0", solutionVersion = "12", versionName = "2012", targetFramework = "4.5", toolsVersion = "4.0", }, } return function(cfg) return (_ACTION == "monodevelop") end local p = premake p.modules.monodevelop = {} local m = p.modules.monodevelop m._VERSION = p._VERSION m.elements = {} local vs2010 = p.vstudio.vs2010 local vstudio = p.vstudio local sln2005 = p.vstudio.sln2005 local project = p.project local config = p.config function m.MonoDevelopProperties(wks) _p('\tGlobalSection(MonoDevelopProperties) = preSolution') if wks.startproject then for prj in p.workspace.eachproject(wks) do if prj.name == wks.startproject then end end end _p('\tEndGlobalSection') end p.override(vstudio, "projectPlatform", function(oldfn, cfg) if _ACTION == "monodevelop" then if cfg.platform then return cfg.buildcfg .. " " .. cfg.platform else return cfg.buildcfg end end return oldfn(cfg) end) p.override(vstudio, "archFromConfig", function(oldfn, cfg, win32) if _ACTION == "monodevelop" then return "Any CPU" end return oldfn(cfg, win32) end) p.override(sln2005, "solutionSections", function(oldfn, wks) if _ACTION == "monodevelop" then return { "ConfigurationPlatforms", "MonoDevelopProperties", "NestedProjects", } end return oldfn(prj) end) p.override(sln2005.elements, "sections", function(oldfn, wks) local elements = oldfn(wks) elements = table.join(elements, { m.MonoDevelopProperties, }) return elements end) p.override(vstudio, "projectfile", function(oldfn, prj) if _ACTION == "monodevelop" then if project.iscpp(prj) then return p.filename(prj, ".cproj") end end return oldfn(prj) end) p.override(vstudio, "tool", function(oldfn, prj) if _ACTION == "monodevelop" then if project.iscpp(prj) then return "2857B73E-F847-4B02-9238-064979017E93" end end return oldfn(prj) end) function m.generateProject(prj) p.eol("\r\n") p.indent(" ") p.escaper(vs2010.esc) if project.isdotnet(prj) then p.generate(prj, ".csproj", vstudio.cs2005.generate) p.generate(prj, ".csproj.user", vstudio.cs2005.generateUser) elseif project.iscpp(prj) then p.generate(prj, ".cproj", m.generate) end end include("monodevelop_cproj.lua") return m local p = premake local m = p.modules.monodevelop m.cproj = {} local vstudio = p.vstudio local project = p.project local config = p.config local fileconfig = p.fileconfig local tree = p.tree function m.generate(prj) m.header("Build") m.projectProperties(prj) for cfg in project.eachconfig(prj) do m.configurationProperties(cfg) end m.files(prj) _p('') end function m.header(target) _p('') local defaultTargets = "" if target then defaultTargets = string.format(' DefaultTargets="%s"', target) end _p('', defaultTargets) end m.elements.projectProperties = function(prj) if project.iscpp(prj) then return { m.cproj.productVersion, m.cproj.schemaVersion, m.cproj.projectGuid, m.cproj.compiler, m.cproj.language, m.cproj.target, m.cproj.version, m.cproj.synchSlnVersion, m.cproj.description, } end end function m.projectProperties(prj) _p(1,'') _p(2,'%s', 'Debug') _p(2,'%s', 'AnyCPU') p.callArray(m.elements.projectProperties, prj) _p(1,'') end m.elements.configurationProperties = function(cfg) if project.iscpp(cfg.project) then return { m.cproj.debuginfo, m.cproj.outputPath, m.cproj.outputName, m.cproj.config_type, m.cproj.preprocessorDefinitions, m.cproj.sourceDirectory, m.cproj.warnings, m.cproj.optimization, m.cproj.externalconsole, m.cproj.additionalOptions, m.cproj.additionalLinkOptions, m.cproj.additionalIncludeDirectories, m.cproj.additionalLibraryDirectories, m.cproj.additionalDependencies, m.cproj.buildEvents, } end end function m.configurationProperties(cfg) _p(1,'', m.condition(cfg)) p.callArray(m.elements.configurationProperties, cfg) _p(1,'') end function m.condition(cfg) return string.format('Condition=" \'$(Configuration)|$(Platform)\' == \'%s|AnyCPU\' "', p.esc(vstudio.projectPlatform(cfg))) end function m.files(prj) m.filegroup(prj, "Include", "None") m.filegroup(prj, "Compile", "Compile") m.filegroup(prj, "Folder", "None") m.filegroup(prj, "None", "None") m.filegroup(prj, "ResourceCompile", "None") m.filegroup(prj, "CustomBuild", "None") end function m.filegroup(prj, group, action) local files = m.getfilegroup(prj, group) if #files > 0 then _p(1,'') for _, file in ipairs(files) do m.putfile(action, file) end _p(1,'') end end function m.putfile(action, file) local filename = file.relpath if not string.startswith(filename, '..') then _x(2,'<%s Include=\"%s\" />', action, path.translate(filename)) else _x(2,'<%s Include=\"%s\">', action, path.translate(filename)) while string.startswith(filename, '..') do filename = filename:sub(4) end _x(3,'%s', filename) _x(2,'', action) end end function m.getTargetGroup(node, prj, groups) local hasbuildrule = false for cfg in project.eachconfig(prj) do local filecfg = fileconfig.getconfig(node, cfg) if filecfg and fileconfig.hasCustomBuildRule(filecfg) then hasbuildrule = true break end end if hasbuildrule then return groups.CustomBuild elseif path.iscppfile(node.name) then return groups.Compile elseif path.iscppheader(node.name) then return groups.Include elseif path.isresourcefile(node.name) then return groups.ResourceCompile else return groups.None end end function m.getfilegroup(prj, group) local groups = prj.monodevelop_file_groups if not groups then groups = { Compile = {}, Include = {}, Folder = {}, None = {}, ResourceCompile = {}, CustomBuild = {}, } prj.monodevelop_file_groups = groups local tr = project.getsourcetree(prj) tree.traverse(tr, { onleaf = function(node) table.insert(m.getTargetGroup(node, prj, groups), node) end }) end return groups[group] end function m.projectReferences(prj) local deps = project.getdependencies(prj) if #deps > 0 then local prjpath = project.getlocation(prj) _p(1,'') for _, dep in ipairs(deps) do local relpath = path.getrelative(prjpath, vstudio.projectfile(dep)) _x(2,'', path.translate(relpath)) _p(3,'{%s}', dep.uuid) _p(2,'') end _p(1,'') end end function m.cproj.productVersion(prj) local action = p.action.current() _p(2,'%s', action.vstudio.productVersion) end function m.cproj.schemaVersion(prj) local action = p.action.current() _p(2,'%s', action.vstudio.csprojSchemaVersion) end function m.cproj.projectGuid(prj) _p(2,'{%s}', prj.uuid) end function m.cproj.compiler(prj) _p(2,'') _p(3,'', iif(prj.language == 'C', 'GccCompiler', 'GppCompiler')) _p(2,'') end function m.cproj.language(prj) _p(2,'%s', iif(prj.language == 'C', 'C', 'CPP')) end function m.cproj.target(prj) _p(2,'%s', 'Bin') end function m.cproj.version(prj) end function m.cproj.synchSlnVersion(prj) end function m.cproj.description(prj) end function m.cproj.debuginfo(cfg) if cfg.flags.Symbols then _p(2,'%s', iif(cfg.flags.Symbols, 'true', 'false')) end end function m.cproj.outputPath(cfg) local outdir = project.getrelative(cfg.project, cfg.buildtarget.directory) _x(2,'%s', path.translate(outdir)) end function m.cproj.outputName(cfg) _x(2,'%s', cfg.buildtarget.name) end function m.cproj.config_type(cfg) local map = { SharedLib = "SharedLibrary", StaticLib = "StaticLibrary", ConsoleApp = "Bin", WindowedApp = "Bin" } _p(2,'%s', map[cfg.kind]) end function m.cproj.preprocessorDefinitions(cfg) local defines = cfg.defines if #defines > 0 then defines = table.concat(defines, ' ') _x(2,'%s', defines) end end function m.cproj.sourceDirectory(cfg) _x(2,'%s', '.') end function m.cproj.warnings(cfg) local map = { Off = "None", Extra = "All" } if cfg.warnings ~= nil and map[cfg.warnings] ~= nil then _p(2,'%s', map[cfg.warnings]) end if cfg.warnings ~= "Off" and cfg.flags.FatalCompileWarnings then _p(2,'%s', iif(cfg.flags.FatalCompileWarnings, 'true', 'false')) end end function m.cproj.optimization(cfg) local map = { Off = "0", On = "2", Debug = "0", Size = "2", Speed = "3", Full = "3" } if cfg.optimize ~= nil and map[cfg.optimize] then _p(2,'%s', map[cfg.optimize]) end end function m.cproj.externalconsole(cfg) _x(2,'%s', 'true') end function m.cproj.additionalOptions(cfg) local opts = { } if cfg.project.language == 'C++' then if cfg.exceptionhandling == p.OFF then table.insert(opts, "-fno-exceptions") end if cfg.rtti == p.OFF then table.insert(opts, "-fno-rtti") end end if cfg.vectorextensions == "SSE2" then table.insert(opts, "-msse2") elseif cfg.vectorextensions == "SSE" then table.insert(opts, "-msse") end local options if #opts > 0 then options = table.concat(opts, " ") end if #cfg.buildoptions > 0 then local buildOpts = table.concat(cfg.buildoptions, " ") if options then options = options .. " " .. buildOpts else options = buildOpts end end if options then _x(2,'%s', options) end end function m.cproj.additionalLinkOptions(cfg) if #cfg.linkoptions > 0 then local opts = table.concat(cfg.linkoptions, " ") _x(2, '%s', opts) end end function m.cproj.additionalIncludeDirectories(cfg) if #cfg.includedirs > 0 then _x(2,'') _x(3,'') for _, i in ipairs(project.getrelative(cfg.project, cfg.includedirs)) do _x(4,'%s', path.translate(i)) end _x(3,'') _x(2,'') end end function m.cproj.additionalLibraryDirectories(cfg) if #cfg.libdirs > 0 then _x(2,'') _x(3,'') for _, l in ipairs(project.getrelative(cfg.project, cfg.libdirs)) do _x(4,'%s', path.translate(l)) end _x(3,'') _x(2,'') end end function m.cproj.additionalDependencies(cfg) local links local toolset = config.toolset(cfg) if toolset then links = toolset.getlinks(cfg, false) else links = config.getlinks(cfg, "all", "fullpath") end if #links > 0 then _x(2,'') _x(3,'') for _, lib in ipairs(links) do _x(4,'%s', path.translate(lib)) end _x(3,'') _x(2,'') end end function m.cproj.buildEvents(cfg) if #cfg.prebuildcommands > 0 or #cfg.postbuildcommands > 0 then _x(2,'') _x(3,'') for _, c in ipairs(cfg.prebuildcommands) do _x(4,'', c) end for _, c in ipairs(cfg.postbuildcommands) do _x(4,'', c) end _x(3,'') _x(2,'') end end local p = premake p.api.register { name = "xcodebuildsettings", scope = "config", kind = "key-array", } p.api.register { name = "xcodebuildresources", scope = "config", kind = "list", } newaction { trigger = "xcode4", shortname = "Apple Xcode 4", description = "Generate Apple Xcode 4 project files", os = "macosx", valid_kinds = { "ConsoleApp", "WindowedApp", "SharedLib", "StaticLib", "Makefile", "None" }, valid_languages = { "C", "C++" }, valid_tools = { cc = { "gcc", "clang" }, }, onWorkspace = function(wks) p.generate(wks, ".xcworkspace/contents.xcworkspacedata", p.modules.xcode.generateWorkspace) end, onProject = function(prj) p.generate(prj, ".xcodeproj/project.pbxproj", p.modules.xcode.generateProject) end, } return function(cfg) return (_ACTION == "xcode4") end local p = premake p.modules.xcode = {} local m = p.modules.xcode m._VERSION = p._VERSION m.elements = {} include("xcode_common.lua") include("xcode4_workspace.lua") include("xcode_project.lua") return m local p = premake local m = p.modules.xcode m.elements.workspace = function(wks) return { m.xmlDeclaration, m.workspace, m.workspaceFileRefs, m.workspaceTail, } end function m.generateWorkspace(wks) m.prepareWorkspace(wks) p.callArray(m.elements.workspace, wks) end function m.workspace() p.push('') end function m.workspaceTail() premake.out('') end m.elements.workspaceFileRef = function(prj) return { m.workspaceLocation, } end function m.workspaceFileRefs(wks) for prj in p.workspace.eachproject(wks) do p.push('") p.pop('') end end function m.workspaceLocation(prj) local fname = p.filename(prj, ".xcodeproj") fname = path.getrelative(prj.workspace.location, fname) p.w('location = "group:%s"', fname) end function m.xmlDeclaration() p.xmlUtf8(true) end local p = premake local xcode = p.modules.xcode local tree = p.tree local workspace = p.workspace local project = p.project local config = p.config local fileconfig = p.fileconfig function xcode.getbuildcategory(node) local categories = { [".a"] = "Frameworks", [".c"] = "Sources", [".cc"] = "Sources", [".cpp"] = "Sources", [".cxx"] = "Sources", [".dylib"] = "Frameworks", [".framework"] = "Frameworks", [".m"] = "Sources", [".mm"] = "Sources", [".strings"] = "Resources", [".nib"] = "Resources", [".xib"] = "Resources", [".storyboard"] = "Resources", [".icns"] = "Resources", [".s"] = "Sources", [".S"] = "Sources", } if node.isResource then return "Resources" end return categories[path.getextension(node.name)] end function xcode.isItemResource(project, node) local res; if project and project.xcodebuildresources then if type(project.xcodebuildresources) == "table" then res = project.xcodebuildresources end end local function checkItemInList(item, list) if item then if list then if type(list) == "table" then for _,v in pairs(list) do if string.find(item, v) then return true end end end end end return false end if (checkItemInList(node.path, res)) then return true end return false end function xcode.getfiletype(node, cfg) if node.configs then local filecfg = fileconfig.getconfig(node, cfg) if filecfg then if filecfg.language == "ObjC" then return "sourcecode.c.objc" elseif filecfg.language == "ObjCpp" then return "sourcecode.cpp.objcpp" end end end local types = { [".c"] = "sourcecode.c.c", [".cc"] = "sourcecode.cpp.cpp", [".cpp"] = "sourcecode.cpp.cpp", [".css"] = "text.css", [".cxx"] = "sourcecode.cpp.cpp", [".S"] = "sourcecode.asm.asm", [".framework"] = "wrapper.framework", [".gif"] = "image.gif", [".h"] = "sourcecode.c.h", [".html"] = "text.html", [".lua"] = "sourcecode.lua", [".m"] = "sourcecode.c.objc", [".mm"] = "sourcecode.cpp.objc", [".nib"] = "wrapper.nib", [".storyboard"] = "file.storyboard", [".pch"] = "sourcecode.c.h", [".plist"] = "text.plist.xml", [".strings"] = "text.plist.strings", [".xib"] = "file.xib", [".icns"] = "image.icns", [".s"] = "sourcecode.asm", [".bmp"] = "image.bmp", [".wav"] = "audio.wav", [".xcassets"] = "folder.assetcatalog", } return types[path.getextension(node.path)] or "text" end local function xcodePrintUserConfigReferences(offset, cfg, tr, kind) local referenceName if kind == "project" then referenceName = cfg.xcodeconfigreferenceproject elseif kind == "target" then referenceName = cfg.xcodeconfigreferencetarget end tree.traverse(tr, { onleaf = function(node) filename = node.name if node.id and path.getextension(filename) == ".xcconfig" then if filename == referenceName then _p(offset, 'baseConfigurationReference = %s /* %s */;', node.id, filename) return end end end }, false) end local escapeSpecialChars = { ['\n'] = '\\n', ['\r'] = '\\r', ['\t'] = '\\t', } local function escapeChar(c) return escapeSpecialChars[c] or '\\'..c end local function escapeArg(value) value = value:gsub('[\'"\\\n\r\t ]', escapeChar) return value end local function escapeSetting(value) value = value:gsub('["\\\n\r\t]', escapeChar) return value end local function stringifySetting(value) value = value..'' if not value:match('^[%a%d_./]+$') then value = '"'..escapeSetting(value)..'"' end return value end local function customStringifySetting(value) value = value..'' local test = value:match('^[%a%d_./%+]+$') if test then value = '"'..escapeSetting(value)..'"' end return value end local function printSetting(level, name, value) if type(value) == 'function' then value(level, name) elseif type(value) ~= 'table' then _p(level, '%s = %s;', stringifySetting(name), stringifySetting(value)) elseif #value >= 1 then _p(level, '%s = (', stringifySetting(name)) for _, item in ipairs(value) do _p(level + 1, '%s,', stringifySetting(item)) end _p(level, ');') end end local function printSettingsTable(level, settings) local keys = table.keys(settings) table.sort(keys) for _, k in ipairs(keys) do printSetting(level, k, settings[k]) end end local function overrideSettings(settings, overrides) if type(overrides) == 'table' then for name, value in pairs(overrides) do settings[name] = iif(value ~= false, value, nil) end end end function xcode.getproducttype(node) local types = { ConsoleApp = "com.apple.product-type.tool", WindowedApp = "com.apple.product-type.application", StaticLib = "com.apple.product-type.library.static", SharedLib = "com.apple.product-type.library.dynamic", } return types[node.cfg.kind] end function xcode.gettargettype(node) local types = { ConsoleApp = "\"compiled.mach-o.executable\"", WindowedApp = "wrapper.application", StaticLib = "archive.ar", SharedLib = "\"compiled.mach-o.dylib\"", } return types[node.cfg.kind] end function xcode.getxcodeprojname(prj) local fname = premake.filename(prj, ".xcodeproj") return fname end function xcode.isframework(fname) return (path.getextension(fname) == ".framework") end function xcode.newid(...) local name = '' local arg = {...} for i, v in pairs(arg) do name = name..v..'****' end return ("%08X%08X%08X"):format(name:hash(16777619), name:hash(2166136261), name:hash(46577619)) end function xcode.prepareWorkspace(wks) wks.xcode = { } for prj in premake.workspace.eachproject(wks) do local cfg = project.getconfig(prj, prj.configurations[1], prj.platforms[1]) local bundlepath = cfg.buildtarget.bundlename ~= "" and cfg.buildtarget.bundlename or cfg.buildtarget.name; if (prj.external) then bundlepath = cfg.project.name end local node = premake.tree.new(path.getname(bundlepath)) node.cfg = cfg node.id = xcode.newid(node.name, "product") node.targetid = xcode.newid(node.name, "target") prj.xcode = {} prj.xcode.projectnode = node end end function xcode.PBXBuildFile(tr) local settings = {}; tree.traverse(tr, { onnode = function(node) if node.buildid then settings[node.buildid] = function(level) _p(level,'%s /* %s in %s */ = {isa = PBXBuildFile; fileRef = %s /* %s */; };', node.buildid, node.name, xcode.getbuildcategory(node), node.id, node.name) end end end }) if not table.isempty(settings) then _p('/* Begin PBXBuildFile section */') printSettingsTable(2, settings); _p('/* End PBXBuildFile section */') _p('') end end function xcode.PBXContainerItemProxy(tr) local settings = {} for _, node in ipairs(tr.projects.children) do settings[node.productproxyid] = function() _p(2,'%s /* PBXContainerItemProxy */ = {', node.productproxyid) _p(3,'isa = PBXContainerItemProxy;') _p(3,'containerPortal = %s /* %s */;', node.id, path.getrelative(node.parent.parent.project.location, node.path)) _p(3,'proxyType = 2;') _p(3,'remoteGlobalIDString = %s;', node.project.xcode.projectnode.id) _p(3,'remoteInfo = %s;', stringifySetting(node.project.xcode.projectnode.name)) _p(2,'};') end settings[node.targetproxyid] = function() _p(2,'%s /* PBXContainerItemProxy */ = {', node.targetproxyid) _p(3,'isa = PBXContainerItemProxy;') _p(3,'containerPortal = %s /* %s */;', node.id, path.getrelative(node.parent.parent.project.location, node.path)) _p(3,'proxyType = 1;') _p(3,'remoteGlobalIDString = %s;', node.project.xcode.projectnode.targetid) _p(3,'remoteInfo = %s;', stringifySetting(node.project.xcode.projectnode.name)) _p(2,'};') end end if not table.isempty(settings) then _p('/* Begin PBXContainerItemProxy section */') printSettingsTable(2, settings); _p('/* End PBXContainerItemProxy section */') _p('') end end function xcode.PBXFileReference(tr) local cfg = project.getfirstconfig(tr.project) local settings = {} tree.traverse(tr, { onleaf = function(node) if not node.path then return end if node.kind == "product" then settings[node.id] = function(level) _p(level,'%s /* %s */ = {isa = PBXFileReference; explicitFileType = %s; includeInIndex = 0; name = %s; path = %s; sourceTree = BUILT_PRODUCTS_DIR; };', node.id, node.name, xcode.gettargettype(node), stringifySetting(node.name), stringifySetting(path.getname(node.cfg.buildtarget.bundlename ~= "" and node.cfg.buildtarget.bundlename or node.cfg.buildtarget.relpath))) end elseif node.parent.parent == tr.projects then settings[node.parent.id] = function(level) local relpath = path.getrelative(path.getabsolute(tr.project.location), path.getabsolute(node.parent.project.location)) _p(level,'%s /* %s */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = %s; path = %s; sourceTree = SOURCE_ROOT; };', node.parent.id, node.name, customStringifySetting(node.parent.name), stringifySetting(path.join(relpath, node.parent.name))) end else settings[node.id] = function(level) local pth, src if xcode.isframework(node.path) then local nodePath = node.path local _, matchEnd, variable = string.find(nodePath, "^%$%((.+)%)/") if variable then nodePath = string.sub(nodePath, matchEnd + 1) end if string.find(nodePath,'/') then if string.find(nodePath,'^%.')then pth = path.getrelative(tr.project.location, node.path) src = "SOURCE_ROOT" variable = src else pth = nodePath src = "" end end if variable then src = variable if string.find(pth, '^/') then pth = string.sub(pth, 2) end else pth = "System/Library/Frameworks/" .. node.path src = "SDKROOT" end else src = "" if node.abspath then pth = path.getrelative(tr.project.location, node.abspath) else pth = node.path end end _p(level,'%s /* %s */ = {isa = PBXFileReference; lastKnownFileType = %s; name = %s; path = %s; sourceTree = %s; };', node.id, node.name, xcode.getfiletype(node, cfg), stringifySetting(node.name), stringifySetting(pth), stringifySetting(src)) end end end }) if not table.isempty(settings) then _p('/* Begin PBXFileReference section */') printSettingsTable(2, settings) _p('/* End PBXFileReference section */') _p('') end end function xcode.PBXFrameworksBuildPhase(tr) _p('/* Begin PBXFrameworksBuildPhase section */') _p(2,'%s /* Frameworks */ = {', tr.products.children[1].fxstageid) _p(3,'isa = PBXFrameworksBuildPhase;') _p(3,'buildActionMask = 2147483647;') _p(3,'files = (') tree.traverse(tr.frameworks, { onleaf = function(node) if node.buildid then _p(4,'%s /* %s in Frameworks */,', node.buildid, node.name) end end }) tree.traverse(tr.projects, { onleaf = function(node) if node.buildid then _p(4,'%s /* %s in Frameworks */,', node.buildid, node.name) end end }) _p(3,');') _p(3,'runOnlyForDeploymentPostprocessing = 0;') _p(2,'};') _p('/* End PBXFrameworksBuildPhase section */') _p('') end function xcode.PBXGroup(tr) local settings = {} tree.traverse(tr, { onnode = function(node) if (node.path and #node.children == 0) or node.kind == "vgroup" then return end settings[node.productgroupid or node.id] = function() if node.parent == tr.projects then _p(2,'%s /* Products */ = {', node.productgroupid) else _p(2,'%s /* %s */ = {', node.id, node.name) end _p(3,'isa = PBXGroup;') _p(3,'children = (') for _, childnode in ipairs(node.children) do _p(4,'%s /* %s */,', childnode.id, childnode.name) end _p(3,');') if node.parent == tr.projects then _p(3,'name = Products;') else _p(3,'name = %s;', stringifySetting(node.name)) local vpath = project.getvpath(tr.project, node.name) if node.path and node.name ~= vpath then local p = node.path if node.parent.path then p = path.getrelative(node.parent.path, node.path) end _p(3,'path = %s;', stringifySetting(p)) end end _p(3,'sourceTree = "";') _p(2,'};') end end }, true) if not table.isempty(settings) then _p('/* Begin PBXGroup section */') printSettingsTable(2, settings) _p('/* End PBXGroup section */') _p('') end end function xcode.PBXNativeTarget(tr) _p('/* Begin PBXNativeTarget section */') for _, node in ipairs(tr.products.children) do local name = tr.project.name local function hasBuildCommands(which) if #tr.project[which] > 0 then return true end for _, cfg in ipairs(tr.configs) do if #cfg[which] > 0 then return true end end end _p(2,'%s /* %s */ = {', node.targetid, name) _p(3,'isa = PBXNativeTarget;') _p(3,'buildConfigurationList = %s /* Build configuration list for PBXNativeTarget "%s" */;', node.cfgsection, escapeSetting(name)) _p(3,'buildPhases = (') if hasBuildCommands('prebuildcommands') then _p(4,'9607AE1010C857E500CD1376 /* Prebuild */,') end _p(4,'%s /* Resources */,', node.resstageid) _p(4,'%s /* Sources */,', node.sourcesid) if hasBuildCommands('prelinkcommands') then _p(4,'9607AE3510C85E7E00CD1376 /* Prelink */,') end _p(4,'%s /* Frameworks */,', node.fxstageid) if hasBuildCommands('postbuildcommands') then _p(4,'9607AE3710C85E8F00CD1376 /* Postbuild */,') end _p(3,');') _p(3,'buildRules = (') _p(3,');') _p(3,'dependencies = (') for _, node in ipairs(tr.projects.children) do _p(4,'%s /* PBXTargetDependency */,', node.targetdependid) end _p(3,');') _p(3,'name = %s;', stringifySetting(name)) local p if node.cfg.kind == "ConsoleApp" then p = "$(HOME)/bin" elseif node.cfg.kind == "WindowedApp" then p = "$(HOME)/Applications" end if p then _p(3,'productInstallPath = %s;', stringifySetting(p)) end _p(3,'productName = %s;', stringifySetting(name)) _p(3,'productReference = %s /* %s */;', node.id, node.name) _p(3,'productType = %s;', stringifySetting(xcode.getproducttype(node))) _p(2,'};') end _p('/* End PBXNativeTarget section */') _p('') end function xcode.PBXProject(tr) _p('/* Begin PBXProject section */') _p(2,'08FB7793FE84155DC02AAC07 /* Project object */ = {') _p(3,'isa = PBXProject;') _p(3,'buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "%s" */;', tr.name) _p(3,'compatibilityVersion = "Xcode 3.2";') _p(3,'hasScannedForEncodings = 1;') _p(3,'mainGroup = %s /* %s */;', tr.id, tr.name) _p(3,'projectDirPath = "";') if #tr.projects.children > 0 then _p(3,'projectReferences = (') for _, node in ipairs(tr.projects.children) do _p(4,'{') _p(5,'ProductGroup = %s /* Products */;', node.productgroupid) _p(5,'ProjectRef = %s /* %s */;', node.id, path.getname(node.path)) _p(4,'},') end _p(3,');') end _p(3,'projectRoot = "";') _p(3,'targets = (') for _, node in ipairs(tr.products.children) do _p(4,'%s /* %s */,', node.targetid, node.name) end _p(3,');') _p(2,'};') _p('/* End PBXProject section */') _p('') end function xcode.PBXReferenceProxy(tr) local settings = {} tree.traverse(tr.projects, { onleaf = function(node) settings[node.id] = function() _p(2,'%s /* %s */ = {', node.id, node.name) _p(3,'isa = PBXReferenceProxy;') _p(3,'fileType = %s;', xcode.gettargettype(node)) _p(3,'path = %s;', stringifySetting(node.name)) _p(3,'remoteRef = %s /* PBXContainerItemProxy */;', node.parent.productproxyid) _p(3,'sourceTree = BUILT_PRODUCTS_DIR;') _p(2,'};') end end }) if not table.isempty(settings) then _p('/* Begin PBXReferenceProxy section */') printSettingsTable(2, settings) _p('/* End PBXReferenceProxy section */') _p('') end end function xcode.PBXResourcesBuildPhase(tr) _p('/* Begin PBXResourcesBuildPhase section */') for _, target in ipairs(tr.products.children) do _p(2,'%s /* Resources */ = {', target.resstageid) _p(3,'isa = PBXResourcesBuildPhase;') _p(3,'buildActionMask = 2147483647;') _p(3,'files = (') tree.traverse(tr, { onnode = function(node) if xcode.getbuildcategory(node) == "Resources" then _p(4,'%s /* %s in Resources */,', node.buildid, node.name) end end }) _p(3,');') _p(3,'runOnlyForDeploymentPostprocessing = 0;') _p(2,'};') end _p('/* End PBXResourcesBuildPhase section */') _p('') end function xcode.PBXShellScriptBuildPhase(tr) local wrapperWritten = false local function doblock(id, name, which) local prjcmds = tr.project[which] local commands = table.join(prjcmds, {}) for _, cfg in ipairs(tr.configs) do local cfgcmds = cfg[which] if #cfgcmds > #prjcmds then table.insert(commands, 'if [ "${CONFIGURATION}" = "' .. cfg.buildcfg .. '" ]; then') for i = #prjcmds + 1, #cfgcmds do table.insert(commands, cfgcmds[i]) end table.insert(commands, 'fi') end end if #commands > 0 then commands = os.translateCommands(commands, p.MACOSX) if not wrapperWritten then _p('/* Begin PBXShellScriptBuildPhase section */') wrapperWritten = true end _p(2,'%s /* %s */ = {', id, name) _p(3,'isa = PBXShellScriptBuildPhase;') _p(3,'buildActionMask = 2147483647;') _p(3,'files = (') _p(3,');') _p(3,'inputPaths = ('); _p(3,');'); _p(3,'name = %s;', name); _p(3,'outputPaths = ('); _p(3,');'); _p(3,'runOnlyForDeploymentPostprocessing = 0;'); _p(3,'shellPath = /bin/sh;'); _p(3,'shellScript = %s;', stringifySetting(table.concat(commands, '\n'))) _p(2,'};') end end doblock("9607AE1010C857E500CD1376", "Prebuild", "prebuildcommands") doblock("9607AE3510C85E7E00CD1376", "Prelink", "prelinkcommands") doblock("9607AE3710C85E8F00CD1376", "Postbuild", "postbuildcommands") if wrapperWritten then _p('/* End PBXShellScriptBuildPhase section */') end end function xcode.PBXSourcesBuildPhase(tr) _p('/* Begin PBXSourcesBuildPhase section */') for _, target in ipairs(tr.products.children) do _p(2,'%s /* Sources */ = {', target.sourcesid) _p(3,'isa = PBXSourcesBuildPhase;') _p(3,'buildActionMask = 2147483647;') _p(3,'files = (') tree.traverse(tr, { onleaf = function(node) if xcode.getbuildcategory(node) == "Sources" then _p(4,'%s /* %s in Sources */,', node.buildid, node.name) end end }) _p(3,');') _p(3,'runOnlyForDeploymentPostprocessing = 0;') _p(2,'};') end _p('/* End PBXSourcesBuildPhase section */') _p('') end function xcode.PBXVariantGroup(tr) local settings = {} tree.traverse(tr, { onbranch = function(node) settings[node.id] = function() if node.kind == "vgroup" then _p(2,'%s /* %s */ = {', node.id, node.name) _p(3,'isa = PBXVariantGroup;') _p(3,'children = (') for _, lang in ipairs(node.children) do _p(4,'%s /* %s */,', lang.id, lang.name) end _p(3,');') _p(3,'name = %s;', node.name) _p(3,'sourceTree = "";') _p(2,'};') end end end }) if not table.isempty(settings) then _p('/* Begin PBXVariantGroup section */') printSettingsTable(2, settings) _p('/* End PBXVariantGroup section */') _p('') end end function xcode.PBXTargetDependency(tr) local settings = {} tree.traverse(tr.projects, { onleaf = function(node) settings[node.parent.targetdependid] = function() _p(2,'%s /* PBXTargetDependency */ = {', node.parent.targetdependid) _p(3,'isa = PBXTargetDependency;') _p(3,'name = %s;', stringifySetting(node.name)) _p(3,'targetProxy = %s /* PBXContainerItemProxy */;', node.parent.targetproxyid) _p(2,'};') end end }) if not table.isempty(settings) then _p('/* Begin PBXTargetDependency section */') printSettingsTable(2, settings) _p('/* End PBXTargetDependency section */') _p('') end end function xcode.XCBuildConfiguration_Target(tr, target, cfg) local settings = {} settings['ALWAYS_SEARCH_USER_PATHS'] = 'NO' if not cfg.flags.Symbols then settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf-with-dsym' end if cfg.kind ~= "StaticLib" and cfg.buildtarget.prefix ~= '' then settings['EXECUTABLE_PREFIX'] = cfg.buildtarget.prefix end local outdir = path.getrelative(tr.project.location, path.getdirectory(cfg.buildtarget.relpath)) if outdir ~= "." then settings['CONFIGURATION_BUILD_DIR'] = outdir end settings['GCC_DYNAMIC_NO_PIC'] = 'NO' if tr.infoplist then settings['INFOPLIST_FILE'] = config.findfile(cfg, path.getextension(tr.infoplist.name)) end installpaths = { ConsoleApp = '/usr/local/bin', WindowedApp = '"$(HOME)/Applications"', SharedLib = '/usr/local/lib', StaticLib = '/usr/local/lib', } settings['INSTALL_PATH'] = installpaths[cfg.kind] local fileNameList = {} local file_tree = project.getsourcetree(tr.project) tree.traverse(tr, { onnode = function(node) if node.buildid and not node.isResource and node.abspath then local filecfg = fileconfig.getconfig(node, cfg) if filecfg and filecfg.flags.ExcludeFromBuild then table.insert(fileNameList, escapeArg(node.name)) end end end }) if not table.isempty(fileNameList) then settings['EXCLUDED_SOURCE_FILE_NAMES'] = fileNameList end settings['PRODUCT_NAME'] = cfg.buildtarget.basename overrideSettings(settings, cfg.xcodebuildsettings) _p(2,'%s /* %s */ = {', cfg.xcode.targetid, cfg.buildcfg) _p(3,'isa = XCBuildConfiguration;') _p(3,'buildSettings = {') printSettingsTable(4, settings) _p(3,'};') printSetting(3, 'name', cfg.buildcfg); _p(2,'};') end function xcode.XCBuildConfiguration_Project(tr, cfg) local settings = {} local archs = { Native = "$(NATIVE_ARCH_ACTUAL)", x86 = "i386", x86_64 = "x86_64", Universal32 = "$(ARCHS_STANDARD_32_BIT)", Universal64 = "$(ARCHS_STANDARD_64_BIT)", Universal = "$(ARCHS_STANDARD_32_64_BIT)", } settings['ARCHS'] = archs[cfg.platform or "Native"] local targetdir = path.getdirectory(cfg.buildtarget.relpath) if targetdir ~= "." then settings['CONFIGURATION_BUILD_DIR'] = '$(SYMROOT)' end settings['CONFIGURATION_TEMP_DIR'] = '$(OBJROOT)' if cfg.flags.Symbols then settings['COPY_PHASE_STRIP'] = 'NO' end settings['GCC_C_LANGUAGE_STANDARD'] = 'gnu99' if cfg.exceptionhandling == p.OFF then settings['GCC_ENABLE_CPP_EXCEPTIONS'] = 'NO' end if cfg.rtti == p.OFF then settings['GCC_ENABLE_CPP_RTTI'] = 'NO' end if cfg.flags.Symbols and not cfg.flags.NoEditAndContinue then settings['GCC_ENABLE_FIX_AND_CONTINUE'] = 'YES' end if cfg.exceptionhandling == p.OFF then settings['GCC_ENABLE_OBJC_EXCEPTIONS'] = 'NO' end local optimizeMap = { On = 3, Size = 's', Speed = 3, Full = 'fast', Debug = 1 } settings['GCC_OPTIMIZATION_LEVEL'] = optimizeMap[cfg.optimize] or 0 if cfg.pchheader and not cfg.flags.NoPCH then settings['GCC_PRECOMPILE_PREFIX_HEADER'] = 'YES' settings['GCC_PREFIX_HEADER'] = cfg.pchheader end settings['GCC_PREPROCESSOR_DEFINITIONS'] = cfg.defines settings["GCC_SYMBOLS_PRIVATE_EXTERN"] = 'NO' if cfg.flags.FatalWarnings then settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' end settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'YES' settings['GCC_WARN_UNUSED_VARIABLE'] = 'YES' local includedirs = project.getrelative(cfg.project, cfg.includedirs) for i,v in ipairs(includedirs) do cfg.includedirs[i] = premake.quoted(v) end settings['USER_HEADER_SEARCH_PATHS'] = cfg.includedirs local sysincludedirs = project.getrelative(cfg.project, cfg.sysincludedirs) for i,v in ipairs(sysincludedirs) do cfg.sysincludedirs[i] = premake.quoted(v) end if not table.isempty(cfg.sysincludedirs) then table.insert(cfg.sysincludedirs, "$(inherited)") end settings['HEADER_SEARCH_PATHS'] = cfg.sysincludedirs for i,v in ipairs(cfg.libdirs) do cfg.libdirs[i] = premake.project.getrelative(cfg.project, cfg.libdirs[i]) end settings['LIBRARY_SEARCH_PATHS'] = cfg.libdirs local objDir = path.getrelative(tr.project.location, cfg.objdir) settings['OBJROOT'] = objDir settings['ONLY_ACTIVE_ARCH'] = iif(premake.config.isDebugBuild(cfg), 'YES', 'NO') local checks = { ["-ffast-math"] = cfg.flags.FloatFast, ["-ffloat-store"] = cfg.flags.FloatStrict, ["-fomit-frame-pointer"] = cfg.flags.NoFramePointer, } local flags = { } for flag, check in pairs(checks) do if check then table.insert(flags, flag) end end settings['OTHER_CFLAGS'] = table.join(flags, cfg.buildoptions) flags = { } for _, lib in ipairs(config.getlinks(cfg, "system")) do if not xcode.isframework(lib) then table.insert(flags, "-l" .. lib) end end for _, lib in ipairs(config.getlinks(cfg, "dependencies", "object")) do if (lib.external) then if not xcode.isframework(lib.linktarget.basename) then table.insert(flags, "-l" .. escapeArg(lib.linktarget.basename)) end end end settings['OTHER_LDFLAGS'] = table.join(flags, cfg.linkoptions) if cfg.flags.StaticRuntime then settings['STANDARD_C_PLUS_PLUS_LIBRARY_TYPE'] = 'static' end if targetdir ~= "." then settings['SYMROOT'] = path.getrelative(tr.project.location, targetdir) end if cfg.warnings == "Extra" then settings['WARNING_CFLAGS'] = '-Wall -Wextra' end overrideSettings(settings, cfg.xcodebuildsettings) _p(2,'%s /* %s */ = {', cfg.xcode.projectid, cfg.buildcfg) _p(3,'isa = XCBuildConfiguration;') _p(3,'buildSettings = {') printSettingsTable(4, settings) _p(3,'};') printSetting(3, 'name', cfg.buildcfg); _p(2,'};') end function xcode.XCBuildConfiguration(tr) local settings = {} for _, target in ipairs(tr.products.children) do for _, cfg in ipairs(tr.configs) do settings[cfg.xcode.targetid] = function() xcode.XCBuildConfiguration_Target(tr, target, cfg) end end end for _, cfg in ipairs(tr.configs) do settings[cfg.xcode.projectid] = function() xcode.XCBuildConfiguration_Project(tr, cfg) end end if not table.isempty(settings) then _p('/* Begin XCBuildConfiguration section */') printSettingsTable(0, settings) _p('/* End XCBuildConfiguration section */') _p('') end end function xcode.XCBuildConfigurationList(tr) local wks = tr.project.workspace local defaultCfgName = stringifySetting(tr.configs[1].buildcfg) local settings = {} for _, target in ipairs(tr.products.children) do settings[target.cfgsection] = function() _p(2,'%s /* Build configuration list for PBXNativeTarget "%s" */ = {', target.cfgsection, target.name) _p(3,'isa = XCConfigurationList;') _p(3,'buildConfigurations = (') for _, cfg in ipairs(tr.configs) do _p(4,'%s /* %s */,', cfg.xcode.targetid, cfg.buildcfg) end _p(3,');') _p(3,'defaultConfigurationIsVisible = 0;') _p(3,'defaultConfigurationName = %s;', defaultCfgName) _p(2,'};') end end settings['1DEB928908733DD80010E9CD'] = function() _p(2,'1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "%s" */ = {', tr.name) _p(3,'isa = XCConfigurationList;') _p(3,'buildConfigurations = (') for _, cfg in ipairs(tr.configs) do _p(4,'%s /* %s */,', cfg.xcode.projectid, cfg.buildcfg) end _p(3,');') _p(3,'defaultConfigurationIsVisible = 0;') _p(3,'defaultConfigurationName = %s;', defaultCfgName) _p(2,'};') end _p('/* Begin XCConfigurationList section */') printSettingsTable(2, settings) _p('/* End XCConfigurationList section */') end local p = premake local m = p.modules.xcode local xcode = p.modules.xcode local project = p.project local config = p.config local fileconfig = p.fileconfig local tree = p.tree function xcode.buildprjtree(prj) local tr = project.getsourcetree(prj, nil , false) tr.project = prj tr.configs = {} for cfg in project.eachconfig(prj) do cfg.xcode = {} cfg.xcode.targetid = xcode.newid(prj.xcode.projectnode.name, cfg.buildcfg, "target") cfg.xcode.projectid = xcode.newid(tr.name, cfg.buildcfg) table.insert(tr.configs, cfg) end -- convert localized resources from their filesystem layout (English.lproj/MainMenu.xib) tree.traverse(tr, { onbranch = function(node) if path.getextension(node.name) == ".lproj" then local lang = path.getbasename(node.name) -- "English", "French", etc. -- create a new language group for each file it contains for _, filenode in ipairs(node.children) do local grpnode = node.parent.children[filenode.name] if not grpnode then grpnode = tree.insert(node.parent, tree.new(filenode.name)) grpnode.kind = "vgroup" end -- convert the file node to a language node and add to the group filenode.name = path.getbasename(lang) tree.insert(grpnode, filenode) end tree.remove(node) end end }) -- the special folder "Frameworks" lists all linked frameworks tr.frameworks = tree.new("Frameworks") for cfg in project.eachconfig(prj) do for _, link in ipairs(config.getlinks(cfg, "system", "fullpath")) do local name = path.getname(link) if xcode.isframework(name) and not tr.frameworks.children[name] then node = tree.insert(tr.frameworks, tree.new(name)) node.path = link end end end if #tr.frameworks.children > 0 then tree.insert(tr, tr.frameworks) end tr.products = tree.insert(tr, tree.new("Products")) tr.projects = tree.new("Projects") for _, dep in ipairs(project.getdependencies(prj, "sibling", "object")) do -- create a child node for the dependency's xcodeproj local xcpath = xcode.getxcodeprojname(dep) local xcnode = tree.insert(tr.projects, tree.new(path.getname(xcpath))) xcnode.path = xcpath xcnode.project = dep xcnode.productgroupid = xcode.newid(xcnode.name, "prodgrp") xcnode.productproxyid = xcode.newid(xcnode.name, "prodprox") xcnode.targetproxyid = xcode.newid(xcnode.name, "targprox") xcnode.targetdependid = xcode.newid(xcnode.name, "targdep") local lprj = premake.workspace.findproject(prj.workspace, dep.name) local cfg = project.findClosestMatch(lprj, prj.configurations[1]) node = tree.insert(xcnode, tree.new(cfg.linktarget.name)) node.path = cfg.linktarget.fullpath node.cfg = cfg end if #tr.projects.children > 0 then tree.insert(tr, tr.projects) end -- Final setup tree.traverse(tr, { onnode = function(node) -- assign IDs to every node in the tree node.id = xcode.newid(node.name, nil, node.path) node.isResource = xcode.isItemResource(prj, node) -- assign build IDs to buildable files if xcode.getbuildcategory(node) then node.buildid = xcode.newid(node.name, "build", node.path) end -- remember key files that are needed elsewhere if string.endswith(node.name, "Info.plist") then tr.infoplist = node end end }, true) -- Plug in the product node into the Products folder in the tree. The node node = tree.insert(tr.products, prj.xcode.projectnode) node.kind = "product" node.path = node.cfg.buildtarget.fullpath node.cfgsection = xcode.newid(node.name, "cfg") node.resstageid = xcode.newid(node.name, "rez") node.sourcesid = xcode.newid(node.name, "src") node.fxstageid = xcode.newid(node.name, "fxs") return tr end m.elements.project = function(prj) return { m.header, } end function m.generateProject(prj) local tr = xcode.buildprjtree(prj) p.callArray(m.elements.project, prj) xcode.PBXBuildFile(tr) xcode.PBXContainerItemProxy(tr) xcode.PBXFileReference(tr) xcode.PBXFrameworksBuildPhase(tr) xcode.PBXGroup(tr) xcode.PBXNativeTarget(tr) xcode.PBXProject(tr) xcode.PBXReferenceProxy(tr) xcode.PBXResourcesBuildPhase(tr) xcode.PBXShellScriptBuildPhase(tr) xcode.PBXSourcesBuildPhase(tr) xcode.PBXTargetDependency(tr) xcode.PBXVariantGroup(tr) xcode.XCBuildConfiguration(tr) xcode.XCBuildConfigurationList(tr) xcode.footer(prj) end function m.header(prj) p.w('// !$*UTF8*$!') p.push('{') p.w('archiveVersion = 1;') p.w('classes = {') p.w('};') p.w('objectVersion = 46;') p.push('objects = {') p.w() end function xcode.footer(prj) p.pop('};') p.w('rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;') p.pop('}') end local shorthelp = "Type 'premake5 --help' for help" local versionhelp = "premake5 (Premake Build Script Generator) %s" local startTime = os.clock() _PREMAKE_STARTTIME = startTime local modules = dofile("_modules.lua") local manifest = dofile("_manifest.lua") for i = 1, #manifest do dofile(manifest[i]) end local p = premake p.main = {} local m = p.main m._preloaded = {} function m.installModuleLoader() table.insert(package.loaders, 2, m.moduleLoader) end function m.moduleLoader(name) local dir = path.getdirectory(name) local base = path.getname(name) if dir ~= "." then dir = dir .. "/" .. base else dir = base end local full = dir .. "/" .. base .. ".lua" local paths = { "modules/" .. full, full, name .. ".lua" } for _, p in ipairs(paths) do local file = os.locate(p) if file then local chunk, err = loadfile(file) if chunk then return chunk end if err then return "\n\tload error " .. err end end end for _, p in ipairs(paths) do local chunk, err = loadfile("$/" .. p) if chunk then return chunk end end end function m.prepareEnvironment() math.randomseed(os.time()) _PREMAKE_DIR = path.getdirectory(_PREMAKE_COMMAND) premake.path = premake.path .. ";" .. _PREMAKE_DIR .. ";" .. _MAIN_SCRIPT_DIR end function m.preloadModules() for i = 1, #modules do local name = modules[i] local preloader = name .. "/_preload.lua" preloader = os.locate("modules/" .. preloader) or os.locate(preloader) if preloader then m._preloaded[name] = include(preloader) if not m._preloaded[name] then p.warn("module '%s' should return function from _preload.lua", name) end else require(name) end end end function m.runSystemScript() dofileopt(_OPTIONS["systemscript"] or { "premake5-system.lua", "premake-system.lua" }) filter {} end function m.locateUserScript() local defaults = { "premake5.lua", "premake4.lua" } for i = 1, #defaults do if os.isfile(defaults[i]) then _MAIN_SCRIPT = defaults[i] break end end if not _MAIN_SCRIPT then _MAIN_SCRIPT = defaults[1] end if _OPTIONS.file then _MAIN_SCRIPT = _OPTIONS.file end _MAIN_SCRIPT = path.getabsolute(_MAIN_SCRIPT) _MAIN_SCRIPT_DIR = path.getdirectory(_MAIN_SCRIPT) end function m.prepareAction() if _ACTION and _ACTION:endswith("ng") then premake.warnOnce(_ACTION, "'%s' has been deprecated; use '%s' instead", _ACTION, _ACTION:sub(1, -3)) end premake.action.set(_ACTION) end function m.runUserScript() if os.isfile(_MAIN_SCRIPT) then dofile(_MAIN_SCRIPT) end end function m.checkInteractive() if _OPTIONS.interactive then debug.prompt() end end function m.processCommandLine() if (_OPTIONS["version"]) then printf(versionhelp, _PREMAKE_VERSION) os.exit(0) end if (_OPTIONS["help"]) then premake.showhelp() os.exit(1) end ok, err = premake.option.validate(_OPTIONS) if not ok then print("Error: " .. err) os.exit(1) end if not _OPTIONS.interactive then if not _ACTION then print(shorthelp) os.exit(1) end local action = premake.action.current() if not action then print("Error: no such action '" .. _ACTION .. "'") os.exit(1) end if p.action.isConfigurable() and not os.isfile(_MAIN_SCRIPT) then print(string.format("No Premake script (%s) found!", path.getname(_MAIN_SCRIPT))) os.exit(1) end end end function m.preBake() if p.action.isConfigurable() then print("Building configurations...") end end function m.bake() if p.action.isConfigurable() then premake.oven.bake() end end function m.postBake() local function shouldLoad(func) for wks in p.global.eachWorkspace() do for prj in p.workspace.eachproject(wks) do for cfg in p.project.eachconfig(prj) do if func(cfg) then return true end end end end end for module, func in pairs(m._preloaded) do if not package.loaded[module] and shouldLoad(func) then require(module) end end end function m.validate() if p.action.isConfigurable() then p.container.validate(p.api.rootContainer()) end end function m.preAction() local action = premake.action.current() printf("Running action '%s'...", action.trigger) end function m.callAction() local action = premake.action.current() premake.action.call(action.trigger) end function m.postAction() if p.action.isConfigurable() then local duration = math.floor((os.clock() - startTime) * 1000); printf("Done (%dms).", duration) end end m.elements = { m.installModuleLoader, m.locateUserScript, m.prepareEnvironment, m.preloadModules, m.runSystemScript, m.prepareAction, m.runUserScript, m.checkInteractive, m.processCommandLine, m.preBake, m.bake, m.postBake, m.validate, m.preAction, m.callAction, m.postAction, } function _premake_main() p.callArray(m.elements) return 0 end return { "base/_foundation.lua", "base/string.lua", "base/table.lua", "base/path.lua", "base/os.lua", "base/io.lua", "base/tools.lua", "base/tree.lua", "base/globals.lua", "base/semver.lua", "base/field.lua", "base/criteria.lua", "base/detoken.lua", "base/configset.lua", "base/context.lua", "base/container.lua", "base/option.lua", "base/action.lua", "base/api.lua", "base/global.lua", "base/workspace.lua", "base/group.lua", "base/project.lua", "base/config.lua", "base/fileconfig.lua", "base/rule.lua", "base/oven.lua", "base/validation.lua", "base/premake.lua", "base/help.lua", "tools/dotnet.lua", "tools/gcc.lua", "tools/msc.lua", "tools/snc.lua", "tools/clang.lua", "actions/make/_make.lua", "actions/make/make_workspace.lua", "actions/make/make_cpp.lua", "actions/make/make_csharp.lua", "actions/make/make_utility.lua", "actions/make/make_makefile.lua", "actions/vstudio/_vstudio.lua", "actions/vstudio/vs2005.lua", "actions/vstudio/vs2008.lua", "actions/vstudio/vs200x_vcproj.lua", "actions/vstudio/vs200x_vcproj_user.lua", "actions/vstudio/vs2005_solution.lua", "actions/vstudio/vs2005_csproj.lua", "actions/vstudio/vs2005_csproj_user.lua", "actions/vstudio/vs2010.lua", "actions/vstudio/vs2010_vcxproj.lua", "actions/vstudio/vs2010_vcxproj_user.lua", "actions/vstudio/vs2010_vcxproj_filters.lua", "actions/vstudio/vs2010_rules_props.lua", "actions/vstudio/vs2010_rules_targets.lua", "actions/vstudio/vs2010_rules_xml.lua", "actions/vstudio/vs2012.lua", "actions/vstudio/vs2013.lua", "actions/vstudio/vs2015.lua", "actions/clean/_clean.lua", "_premake_init.lua", } return {"xcode", "monodevelop", "codelite", "d"}FFIFH,FF(0FkFDFFMFwFlFlFlFXFnFV @F0{F<,Fp~FF FFFGFFFȴF]F(FF F4 FXFxFpF dFhF-:PF)G8F -G$F3G F4GEFGG8F(^G< FhhG4FnGFG FȘG tFG\FXG$HFG4F0G F8GM FGFGFPGC F H'F01HAdFxCH@F0GHFLH4#F0pH:FpwH@FzH0jFH`FH8FI$ F'I#F,I F9I2FI hFI+ <F8I FXIrFJuFHJ FX!J:F%J:`F)JHF*JAN0FxJF{JFJFJ*F(JF0JFJ&F@J|FJ"lFK\FKLFH-K0FP?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~# #%%%%$%a%b%V%U%c%Q%W%]%\%[%%%4%,%%%<%^%_%Z%T%i%f%`%P%l%g%h%d%e%Y%X%R%S%k%j%% %%%%%%")"a"e"d" #!#H""" %1.2.8Wrong password providedNo password providedRead-only archiveEncryption method not supportedEntry has been deletedCan't remove fileZip archive inconsistentInternal errorNot a zip archiveInvalid argumentPremature EOFCompression method not supportedEntry has been changedMalloc failureZlib errorFailure to create temporary fileCan't open fileFile already existsNo such fileContaining zip archive was closedCRC errorWrite errorRead errorSeek errorClosing zip archive failedRenaming temporary file failedMulti-disk zip archives not supportedNo errorLLLLtLhL\LPL,LLLLLLLL|LlLXLDL4LLLLLLLL0w,aQ mjp5c飕d2yҗ+L |~-d jHqA}mQDžӃVlkdzbeO\lcc=  n;^iLA`rqgjm Zjz  ' }Dңhi]Wbgeq6lknv+ӉZzJgo߹ホCՎ`~ѡ8ROggW?K6H+ L J6`zA`Ugn1yiFafo%6hRw G "/&U;( Z+j\1е,[d&c윣ju m ?6grWJz+{8 Ғ |! ӆBhn[&wowGZpj;f\ eibkaElx TN³9a&g`MGiIwn>JjѮZf @;7SŞϲG0򽽊º0S$6к)WTg#.zfJah]+o*7 Z-A1b62S-+ldEw}ZVǖAOIъ OM~-QJ#SpxAaU׮.7׵Y-6]]wll?AԞZ͢$ Faw$eڪ]]FD(koipvk19Z* ,  m86F߲]qTp0ek*1u4yީ%8S1bSWĔՖk1**ykʬHpo].*F6fcTT"eM©g0&):{ϼkZ> 8$,52F*sw1pHkQ6Fzw]cN̵J #pAF]#l8?1(BOgT~yUbL8^#ܖTZ1ObbSyOIV~P-{b-R4٠~^eGnHl/Su6: #jT$+e?yHf'*b#ٽЧ ?&~?$pi;FBzw[keZ~7 Sv8H 3?r$7jnԄYFܨ |OQ;օ U d S - =G\ p&Gw)` /a߫i5&LsZ<#0zMzFM8,9; :R:(q-v,.7/pXqYs3r%w+OQvrtEux܉~OK }!b|tyBxʠz{.lD~m8onlk[wjR1h58ib?mcf+aQ`צedd"fig HINSKyuJcO NZLݘMFGN@E$DD2AsX@*IBCPhTg3U>uW ַVS:R|P~Q9ZS [fYX4])\ZEo^m/_5qϱ٥s\ۼqދ!K7 kfֶԁ-b3Πjp]$^'~*I@VW<âM˟ŏ{ tDCm-@wm.B+(铜>Td"ŀǼϭ~8y$owJ1}05_K^ iϏ은BI#ƈdX܁T̓cQ: rՆ⩗ fn|xK)o%ƭ/3vUuA?)C:|sĵ@͂ Ͳ;bIUeh"׻_HS1޼^Z4eg Wb27_k%8ם(ŊO}do׸Jj3wVcXWP0qB{߭gCru&op-?'Bs ưGz>2[Ȏg; i8P/ _Y=чe:ZO?(3wwXR @hQ+ğH*0"ZOWoI}@mNП5+#*'G| AH=XX?#1jvʬ`p^Y<L~i/{kHwâ hs)aLoD~Pf7VM'(@ﰤ ہg9x+n&;f?/X)T`D1 ߨMߒ.FgTp'Hq/L0UEc?kǃh6ry7]P\@TN%s7@'>$!AxUʰ\3;Y^U~PGl!;b F2ȂpԞ(Q_V:1X: n3 m:@/)IJNv"2x+ٗ Kx.HҥfAj^y9*O]#kM`~b_R 7zFh!1߈Vc0a"j6nS Nr)Υ{t*F8#vufz`rs"WG9^EMvc΍&DAdQy/4Aڱ&S֚E biLQ<6'5P..T&q]w4.6IE? v\[YI>U!lDa>Ԫ΋ϩ7~8A]&nv|oY yKiw\¹9~$ 66nQfq>,o,IӔ 渱{I .H>C-Yn馑gQz tafw0a, Qmpjc5dۈ2yܸو L+~|-dj qHA}mԵQӅlVdkbze\Ocl=c ;n Li^`Agqr<KG k5Blۻ֬@2lE\u ϫ=Y&0Q:Qa!V#Ϻ(_ ٲ $/o|XhLaf-=vAq *q3xɢ4 j m=-dlc\kkQlabe0bNl{WeP|b-I|LeMaX:QΣtԻ0JߥA=ؕפmCij4ngF`D-s3 L_ |Pq<'A  Wh% of a^)ɘИ"רY=. \;l  tҚG9w&sc d; mj>zjZ '}DhibW]egl6qnkv+zZgJoC`֣ѓ~8ORѻgWg?H6K +گ L6JAz``ègU1nFiyaf%oҠRh6 w G"U&/ź; (+Z\j1,ٞ[ޮd°c&ujm 6?rgWJz{+ 8Ҏվ | !Bhݳڃn&[owGwZjpf; \ebiaklE x NT9§g&a`IiGM>nwۮjJZ@ f7;𩼮S޻G0齽ʺŠS0$6TW)#gfz.aJ]h*o+ 7 Z-1A26b+-Sdl}wEVZOAي»IˬO ~M-JQS#xpaA.U7Y-۩6˚w]]llA?Z$㧲F waރ$Ųe]]DFok(vpi91k *Z  ,8mF6]pTqke0*1¶u4%y<8syjHA}X*ݹ1SbSW§ٖծ1k**kypH]oF*.f6TTcMe"¤0g)&Ůޟ:{kZ >8,$5*F21wsHpQkzF6c]wN̵ׄJ# pȄA#]F8l1?(gOB~TUyLbˁ8#^TO1ZbbySIOP~V{-b-4R^~Ge­lHnuS/:6# $Tj?e+y䏼Hf*'˼Ѝb# &??~p$iBF;[wzek~ZS 7H8v ?3$rj7nFY |OQ; U dؓS - \G=&pGw`)/ ai5&sL <:R=Pe6^X7}o5641W0ճ2k3$k%'1&-[#bML"'{ "!$*x(+)`F(> q-q,v.Ț/7pqXsYr3w%vQO+tru՛E~xKO} |b!ytxBz{l.m~Do8nkljw[h1Ri85bcm?a+f`Qeddf"giH IKSNJuyOcN LZMݥFĚGE@ND$A2D@XsBI*CThPU3gWu>V SR:P|Q~Z9[ SYfX]4\)^oEZ_/m5qs<\kg2z &J8 좞V`a/6i\lU,zB\uHƒ=&FW A+Ox]`غ7W>9q߳!7Kk ֩fض-bѠ3pj$]^Ĝ'*~@IWVÕ<ӂMʏş{ Dt͆mC-@mw+B.(>dT"ş~Ϝ8yo$w1J}50K_ ^ϋiBۉI#dXфTQc:r Р fΫnx|)Ko%3/uUv?A)ġ:C|sд@͉ ;IbeU"hH_S1ފZ^ھ4ge ȋbW72%k_ܝ8Ŵ(}OodJֿjw3XcVPW0Bq{gǧurCo&p-?О'sB zGɠ2>[ ;g/P8i_ Y=嗇e:ϏOZw3(?RXw@ Qh+HZ"0*WOIo@}m5N#+'*GA |􏒨HX=#?X1vjʨ`^pYL'!$UxAׯ3\Y;U^GP~b;!lڇF 2p(ԐQV_:X1: 3n :m@I)/NJ2"v+x xKH.jAf^O*9y]#Mk~`bю_޶ Rz7hFм!10cV"ajحn6 SrN){t*8Fv#fu`zrϮsɛW"G9E^vMcD&dA/yQA4S&ֿ EbLil!>aDƋΪ~7A8n&]|vYoᡱ Kyi׫w¡\~9$66 Qnf>q,o,ӹI 散 I{.C>HnY-Qg̰t zfa deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler +AAA AA AA A A A1.2.8`Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O `Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O A@!  @a`10  @     incorrect length checkincorrect data checkinvalid distance too far backinvalid distance codeinvalid literal/length codeinvalid distances setinvalid literal/lengths setinvalid code -- missing end-of-blockinvalid bit length repeatinvalid code lengths settoo many length or distance symbolsinvalid stored block lengthsinvalid block typeheader crc mismatchunknown header flags setincorrect header checkinvalid window sizeunknown compression method       L,l\<|B"bR2r J*jZ:zF&fV6vN.n^>~A!aQ1q I)iY9yE%eU5u M-m]=}   S S  3 3  s s    K K  + +  k k     [ [  ; ;  { {     G G  ' '  g g     W W  7 7  w w     O O  / /  o o     _ _  ? ?     @ `P0pH(hX8xD$dT4tC#c         (08@P`p  0@`  0@`incompatible versionbuffer errorinsufficient memorydata errorstream errorfile errorstream endneed dictionary?L?LE?L?L?L?L?Lh?LE inflate 1.2.8 Copyright 1995-2013 Mark Adler  #+3;CScsHN !1Aa  0@`@@0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ(nil)(nil)I64I32.%ld%ldeasy handle already used in multi handleUnknown errorSSL server certificate status verification FAILEDSSL public key does not match pinned public keyThe max connection limit is reachedChunk callback failedUnable to parse FTP file listRTSP session errorRTSP CSeq mismatch or invalid CSeqSocket not ready for send/recvError in the SSH layerRemote file not foundCaller must register CURLOPT_CONV_ callback optionsConversion failedTFTP: No such userRemote file already existsTFTP: Unknown transfer IDTFTP: Illegal operationDisk full or allocation exceededTFTP: Access ViolationTFTP: File Not FoundLogin deniedSend failed since rewinding of the data stream failedIssuer check against peer certificate failedFailed to load CRL file (path? access rights?, format?)Failed to shut down the SSL connectionRequested SSL level failedMaximum file size exceededInvalid LDAP URLUnrecognized or bad HTTP Content or Transfer-EncodingProblem with the SSL CA cert (path? access rights?)Peer certificate cannot be authenticated with given CA certificatesCouldn't use specified SSL cipherProblem with the local SSL certificateFailure when receiving data from the peerFailed sending data to the peerFailed to initialise SSL crypto engineCan not set SSL crypto engine as defaultSSL crypto engine not foundServer returned nothing (no headers, no data)SSL peer certificate or SSH remote key was not OKMalformed telnet optionAn unknown option was passed in to libcurlNumber of redirects hit maximum amountFailed binding local connection endA libcurl function was given a bad argumentOperation was aborted by an application callbackA required function in the library was not foundLDAP: search failedLDAP: cannot bindCouldn't read a file:// fileCouldn't resume downloadSSL connect errorInternal problem setting up the POSTRequested range was not delivered by the serverFTP: command REST failedFTP: command PORT failedTimeout was reachedOut of memoryFailed to open/read local data from file/applicationUpload failed (at start/before it took off)Failed writing received data to disk/applicationHTTP response code said errorQuote command returned errorFTP: couldn't retrieve (RETR failed) the specified fileTransferred a partial fileFTP: couldn't set file typeError in the HTTP2 framing layerFTP: can't figure out the host in the PASV responseFTP: unknown 227 response formatFTP: unknown PASV replyFTP: unknown PASS replyFTP: The server did not accept the PRET command.FTP: Accepting server connect has timed outFTP: The server failed to connect to data portAccess denied to remote resourceFTP: weird server replyCouldn't connect to serverCouldn't resolve host nameCouldn't resolve proxy nameA requested feature, protocol or option was not found built-in in this libcurl due to a build-time decision.URL using bad/illegal format or missing URLFailed initializationUnsupported protocolHost not foundHost not found, try againUnrecoverable error in call to nameserverNo data record of requested typeDisconnectedWinsock version not supportedWinsock library not initialisedWinsock library is not readyRemote errorSomething is staleBad quotaToo many usersProcess limit reachedNot emptyHost unreachableHost downName too longLoop??Connection refusedTimed outToo many referencesSocket has been shut downSocket is not connectedSocket is already connectedNo buffer spaceConnection was resetConnection was abortedNetwork has been resetNetwork unreachableNetwork downAddress not availableAddress already in useProtocol family not supportedAddress family not supportedOperation not supportedSocket is unsupportedProtocol is unsupportedProtocol option is unsupportedBad protocolBad message sizeNeed destination addressDescriptor is not a socketBlocking call in progressCall would blockOut of file descriptorsInvalid argumentsBad argumentBad accessBad fileCall interruptedUnknown error %d (%#x)SEC_E_ILLEGAL_MESSAGE (0x%04X%04X) - This error usually occurs when a fatal SSL/TLS alert is received (e.g. handshake failed). More detail may be available in the Windows System event log.SEC_I_INCOMPLETE_CREDENTIALSSEC_I_RENEGOTIATESEC_I_NO_LSA_CONTEXTSEC_I_SIGNATURE_NEEDEDSEC_I_CONTEXT_EXPIREDSEC_I_CONTINUE_NEEDEDSEC_I_COMPLETE_NEEDEDSEC_I_COMPLETE_AND_CONTINUESEC_I_LOCAL_LOGON%s - %s%s (0x%04X%04X)CRYPT_E_REVOKEDSEC_E_WRONG_PRINCIPALSEC_E_WRONG_CREDENTIAL_HANDLESEC_E_UNTRUSTED_ROOTSEC_E_UNSUPPORTED_PREAUTHSEC_E_UNSUPPORTED_FUNCTIONSEC_E_UNKNOWN_CREDENTIALSSEC_E_UNFINISHED_CONTEXT_DELETEDSEC_E_TOO_MANY_PRINCIPALSSEC_E_TIME_SKEWSEC_E_TARGET_UNKNOWNSEC_E_STRONG_CRYPTO_NOT_SUPPORTEDSEC_E_SMARTCARD_LOGON_REQUIREDSEC_E_SMARTCARD_CERT_REVOKEDSEC_E_SMARTCARD_CERT_EXPIREDSEC_E_SHUTDOWN_IN_PROGRESSSEC_E_SECURITY_QOS_FAILEDSEC_E_SECPKG_NOT_FOUNDSEC_E_REVOCATION_OFFLINE_KDCSEC_E_REVOCATION_OFFLINE_CSEC_E_QOP_NOT_SUPPORTEDSEC_E_POLICY_NLTM_ONLYSEC_E_PKINIT_NAME_MISMATCHSEC_E_PKINIT_CLIENT_FAILURESEC_E_OUT_OF_SEQUENCESEC_E_NO_TGT_REPLYSEC_E_NO_S4U_PROT_SUPPORTSEC_E_NO_PA_DATASEC_E_NO_KERB_KEYSEC_E_NO_IP_ADDRESSESSEC_E_NO_IMPERSONATIONSEC_E_NO_CREDENTIALSSEC_E_NO_AUTHENTICATING_AUTHORITYSEC_E_NOT_OWNERSEC_E_MUST_BE_KDCSEC_E_MULTIPLE_ACCOUNTSSEC_E_MESSAGE_ALTEREDSEC_E_MAX_REFERRALS_EXCEEDEDSEC_E_LOGON_DENIEDSEC_E_KDC_UNKNOWN_ETYPESEC_E_KDC_UNABLE_TO_REFERSEC_E_KDC_INVALID_REQUESTSEC_E_KDC_CERT_REVOKEDSEC_E_KDC_CERT_EXPIREDSEC_E_ISSUING_CA_UNTRUSTED_KDCSEC_E_ISSUING_CA_UNTRUSTEDSEC_E_INVALID_TOKENSEC_E_INVALID_PARAMETERSEC_E_INVALID_HANDLESEC_E_INTERNAL_ERRORSEC_E_INSUFFICIENT_MEMORYSEC_E_INCOMPLETE_MESSAGESEC_E_INCOMPLETE_CREDENTIALSSEC_E_ILLEGAL_MESSAGESEC_E_ENCRYPT_FAILURESEC_E_DOWNGRADE_DETECTEDSEC_E_DELEGATION_REQUIREDSEC_E_DELEGATION_POLICYSEC_E_DECRYPT_FAILURESEC_E_CRYPTO_SYSTEM_INVALIDSEC_E_CROSSREALM_DELEGATION_FAILURESEC_E_CONTEXT_EXPIREDSEC_E_CERT_WRONG_USAGESEC_E_CERT_UNKNOWNSEC_E_CERT_EXPIREDSEC_E_CANNOT_PACKSEC_E_CANNOT_INSTALLSEC_E_BUFFER_TOO_SMALLSEC_E_BAD_PKGIDSEC_E_BAD_BINDINGSSEC_E_ALGORITHM_MISMATCHInitSecurityInterfaceAsecur32.dllsecurity.dllUnrecognized parameter value passed via CURLOPT_SSLVERSIONWARNING: Using weak random seed %s:%dHostname in DNS cache was stale, zapped Hostname %s was found in DNS cache timeout on name lookup is not supported Added %s:%d:%s to DNS cache Address in '%s' found illegal! Couldn't parse CURLOPT_RESOLVE entry '%s'! %255[^:]:%d:%255sCouldn't parse CURLOPT_RESOLVE removal entry '%s'! %255[^:]:%d}L(~L\LHTTPrcmdConnected to %s (%s) port %ld (#%ld) IDN support not present, can't parse Unicode domains Protocol "%s" not supported or disabled in libcurl%I64u-, *ALL_PROXYall_proxyhttp_proxy_proxyNO_PROXYno_proxyPort number out of range%s://%s%s%s:%hu%s%s%s[];type=%cIPv6 numerical address used in URL without brackets[%*45[0123456789abcdefABCDEF:.]%cCouldn't find host %s in the _netrc file; using defaults ftp@example.comanonymousCouldn't resolve host '%s'Couldn't resolve proxy '%s'User-Agent: %s Set-Cookie:RELOADFLUSHSESSALLidentityCURLOPT_SSL_VERIFYHOST no longer supports 1 as value!Closing connection %ld Connection %ld seems to be dead! Multiplexed connection found! Connection #%ld isn't open enough, can't reuse Penalized, skip Pipe is full, skip (%zu) Server doesn't support multi-use (yet) Server doesn't support multi-use yet, wait Found bundle for host %s: %p Connection cache is full, closing the oldest one. No valid port number in proxy string (%s) Invalid IPv6 address format Please URL encode %% as %%25, see RFC 6874. %25sockssocks4socks4asocks5socks5h://Connection #%ld to host %s left intact Rebuilt URL to: %s pop3POP3.smtpSMTP.IMAPIMAP.LDAPLDAP.DICTDICT.ftpFTP. malformed%[^ /?]%[^ ]%15[^ :]://%[^ /?]%[^ ]%15[^:]:%[^ ]Illegal characters found in URLNTLM-proxy picked AND auth done set, clear picked! NTLM picked AND auth done set, clear picked! No connections available. No connections available in cache No more connections allowed to host: %d Re-using existing connection! (#%ld) with %s %s hostproxyWe can reuse, but we want a new connection anyway Found connection %ld, with requests in the pipe (%zu) memory shortage%s://%sInternal error removing splay node = %d Internal error clearing splay node = %d Curl_poll(%d ds, %d ms) In state %d with no easy_conn, bail out! Hostname was found in DNS cache Operation timed out after %ld milliseconds with %I64d bytes receivedOperation timed out after %ld milliseconds with %I64d out of %I64d bytes receivedConnection timed out after %ld millisecondsResolving timed out after %ld millisecondsPipe broke: handle %p, url = %s .A* < > { } { } [%s %s %s]fromtoHeaderDataSend failure: %sRecv failure: %sFailed writing headerFailed writing body (%zu != %zu)Write callback asked for PAUSE when not supported!%s cookie %s="%s" for domain %s, path %s, expire %I64d AddedReplacedFALSETRUE#HttpOnly_expiresmax-ageversionskipped cookie with bad tailmatch domain: %s :domainhttponlysecure%1023[^; =] =%4999[^; ]%s%s%s %s %s %s %I64d %s %sunknown# # Fatal libcurl error wt# Netscape HTTP Cookie File # http://curl.haxx.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. rtnoneignoring failed cookie_init for %s WARNING: failed to save cookies in %s host!if!Failed to set SIO_KEEPALIVE_VALS on fd %d: %d Failed to set SO_KEEPALIVE on fd %d bind failed with errno %d: %sLocal port: %hu getsockname() failed with errno %d: %sBind to local port %hu failed, trying next Couldn't bind to '%s'Name '%s' family %i resolved to '%s' family %i Couldn't bind to interface '%s'Local Interface %s is ip %s using address family %i ssloc inet_ntop() failed with errno %d: %sssrem inet_ntop() failed with errno %d: %sgetpeername() failed with errno %d: %sTCP_NODELAY set Could not set TCP_NODELAY: %s Immediate connect fail for %s: %s Trying %s... sa_addr inet_ntop() failed with errno %d: %sConnection time-outFailed to connect to %s port %ld: %sconnect to %s port %ld failed: %s Connection failed After %ldms connect time, move on! schannel: failed to send initial handshake data: sent %zd of %lu bytesschannel: sent initial handshake data: sent %zd bytes schannel: sending initial handshake data: sending %lu bytes... schannel: initial InitializeSecurityContext failed: %sschannel: using IP address, SNI is not supported by OS. schannel: AcquireCredentialsHandle failed: %sschannel: SNI or certificate check failed: %sMicrosoft Unified Security Protocol Providerschannel: unable to allocate memoryschannel: verifyhost setting prevents Schannel from comparing the supplied target name with the subject names in server certificates. Also disables SNI. schannel: disabled server certificate revocation checks schannel: checking server certificate revocation schannel: re-using existing credential handle schannel: SSL/TLS connection with %s port %hu (step 1/3) schannel: SSL/TLS handshake complete schannel: failed to send next handshake data: sent %zd of %lu bytesschannel: next InitializeSecurityContext failed: %sschannel: a client certificate has been requested schannel: received incomplete message, need more data schannel: failed to receive handshake, SSL/TLS connection failedschannel: failed to receive handshake, need more data schannel: encrypted data length: %lu schannel: sending next handshake data: sending %lu bytes... schannel: encrypted data buffer: offset %zu length %zu schannel: unable to re-allocate memoryschannel: SSL/TLS connection with %s port %hu (step 2/3) schannel: stored credential handle in session cache schannel: failed to store credential handleschannel: old credential handle is stale, removing schannel: incremented credential handle refcount = %d schannel: failed to setup stream orientationschannel: failed to setup memory allocationschannel: failed to setup confidentialityschannel: failed to setup replay detectionschannel: failed to setup sequence detectionschannel: SSL/TLS connection with %s port %hu (step 3/3) select/poll on SSL socket, errno: %dschannel: timed out sending data (bytes sent: %zd)schannel: decrypted data returned %zu schannel: server closed abruptly (missing close_notify) schannel: renegotiation failed schannel: can't renogotiate, encrypted data available schannel: can't renogotiate, an error is pending schannel: failed to read data from server: %s schannel: failed to decrypt data, need more data schannel: schannel_recv cleanup schannel: decrypted data buffer: offset %zu length %zu schannel: SSL/TLS connection renegotiated schannel: renegotiating SSL/TLS connection schannel: remote party requests renegotiation schannel: encrypted data cached: offset %zu length %zu schannel: decrypted data cached: offset %zu length %zu schannel: decrypted data added: %zu schannel: decrypted data length: %lu schannel: encrypted data got %zd schannel: server closed the connection schannel: Curl_read_plain returned error %d schannel: Curl_read_plain returned CURLE_RECV_ERROR schannel: Curl_read_plain returned CURLE_AGAIN schannel: encdata_buffer resized %zu schannel: server indicated shutdown in a prior call schannel: an unrecoverable error occurred in a prior call schannel: enough decrypted data is already available schannel: client wants to read %zu bytes schannel: clear credential handle schannel: decremented credential handle refcount = %d schannel: clear security context handle schannel: failed to send close msg: %s (bytes written: %zd) schannel: ApplyControlToken failure: %sschannel: shutting down SSL/TLS connection with %s port %hu SSL/TLS connection timeoutselect/poll on SSL/TLS socket, errno: %d%7I64dd%3I64dd %02I64dh%2I64d:%02I64d:%02I64d--:--:--%4I64dP%4I64dT%4I64dG%2I64d.%0I64dG%4I64dM%2I64d.%0I64dM%4I64dk%5I64d %3I64d %s %3I64d %s %3I64d %s %s %s %s %s %s %s %% Total %% Received %% Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed ** Resuming transfer from byte position %I64d Callback abortedABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_%c%c==%c%c%c=%c%c%c%c&C[CtC@&C[CtC%d.%d.%d.%d%lxgetaddrinfo(3) failed for %s:%d %dHTTPS$]L'C 255 [actual len=%zu] Proxy replied OK to CONNECT request Received HTTP code %d from proxy after CONNECTConnect me again please TUNNEL_STATE switched to: %d Proxy CONNECT aborted due to timeoutProxy CONNECT aborted due to select/poll errorProxy CONNECT followed by %zd bytes of opaque data. Data ignored (known bug #39)%zd bytes of chunk left Ignore %I64d bytes of response-body HTTP/1.%d %dCONNECT responded chunked Read %zd bytes of chunk, continue chunk reading DONE Proxy CONNECT abortedProxy CONNECT connection closed Failed sending CONNECT to proxyCONNECT %s HTTP/%s %s%s%s%sHost: %s %s%s%s:%huCONNECT%s:%huEstablish HTTP proxy tunnel to %s:%hu 01234567890123456789abcdef0123456789ABCDEFdefaultmachinepasswordlogin %s%s%s_netrcOperation too slow. Less than %ld bytes/sec transferred the last %ld seconds%x%sread function returned funny valueRead callback asked for PAUSE when not supported!operation aborted by callbacknecessary data rewind wasn't possibleioctl callback returned error %dthe ioctl callback returned %d seek callback returned error %dThe requested document is not old enough The requested document is not new enough we are done reading and this is set to close, stop send %s in chunked-encodingFailed writing dataSimulate a HTTP 304 response! HTTP server doesn't seem to support byte ranges. Cannot resume.The entire document is already downloadedExcess found in a non pipelined read: excess = %zd url = %s (zero-length body) Rewinding stream by : %zd bytes on url %s (zero-length body) Excess found in a non pipelined read: excess = %zu, size = %I64d, maxdownload = %I64d, bytecount = %I64d Rewinding stream by : %zu bytes on url %s (size = %I64d, maxdownload = %I64d, bytecount = %I64d, nread = %zd) Rewinding %zu bytes Leftovers after chunking: %zu bytes Ignoring the response-body We are completely uploaded and fine Failed to alloc scratch buffer!transfer closed with outstanding read data remainingtransfer closed with %I64d bytes remaining to readDone waiting for 100-continue select/poll returned errorNo URL set!%15[^?&/:]://%c//Switch from POST to GET Disables POST, goes with %s Issue another request to this URL: '%s' Maximum (%ld) redirects followedRe-used connection seems dead, get a new one Connection died, retrying a fresh connect %sAuthorization: Digest %s %.*s%sAuthorization: NTLM %s NTLM handshake failure (internal error) NTLM handshake rejected NTLM auth restarted /../..//././DecNovOctSepAugJulJunMayAprMarFebJanSundaySaturdayFridayThursdayWednesdayTuesdayMondaySunSatFriThuWedTueMonLLLLLLL؛LЛLěLLLLLLLLLLLL|LxLtLpLlLGMTUTCWETBSTWAT<ASTADTEST,EDTCSThCDT,MSTMDThPSTPDTYSTYDTHSTXHDTCATXAHSTXNTIDLWCETMETMEWTMESTCESTMESZFWTFSTEETWAST\WADT CCT JSTEASTEADTlGSTNZT0NZST0NZDTIDLE0A<BxCDE,FhGHIKXLMNOPLQRST\U VWXlY0Z;Zx0N%02d:%02d%02d:%02d:%02d%31[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]%sAuthorization: Negotiate %s Negotiate handshake failure (empty challenge message) application/xml.xmltext/html.htmltext/plain.txt.jpegimage/jpeg.jpgimage/gif.gifLԠL̠LLLLLLLLLxL; filename="%s"------------------------%08x%08x --%s-- --%s--couldn't open file "%s" %s Content-Type: %s --%s Content-Disposition: attachment Content-Type: multipart/mixed; boundary=%s "Content-Disposition: form-data; name="--%s %s; boundary=%s Content-Type: multipart/form-dataToo long hexadecimal numberIllegal or missing hexadecimal sequenceMalformed encoding foundBad content-encoding foundSSPI error: %s failed: %sFailed to receive SSPI authentication response.Failed to receive SSPI authentication token.Invalid SSPI authentication response type (%u %u).Failed to send SSPI encryption request.Failed to receive SSPI encryption response.Failed to receive SSPI encryption type.SOCKS5 access with%s protection granted. GSS-API confidentiality GSS-API integrityout GSS-API dataInvalid SSPI encryption response length (%lu).DecryptMessageInvalid SSPI encryption response type (%u %u).User was rejected by the SOCKS5 server (%u %u).Failed to send SSPI encryption type.EncryptMessageFailed to query security context attributes.QueryContextAttributesSOCKS5 server supports GSS-API %s data protection. confidentialityintegritySOCKS5 server authencticated user %s with GSS-API. Failed to determine user name.QueryCredentialAttributesFailed to send SSPI authentication request.Failed to send SSPI authentication token.Failed to initialise security context.InitializeSecurityContextFailed to acquire credentials.AcquireCredentialsHandleKerberosWDigestrealmNTLM handshake failure (empty type-2 message) NTLM handshake failure (type-3 message): Status=%x XOAUTH2EXTERNALGSSAPIDIGEST-MD5CRAM-MD5PLAINLOGINLLܧLЧL ȧLL TL@L=6\CorExitProcessmscoree.dllrC??330CVisual C++ CRT: Not enough memory to complete call to strerror. /c cmd.exeCOMSPEC??33fmod!DDDDtDDDDDDDDDDDD33/ca/pam/pmLC_TIMELC_NUMERICLC_MONETARYLC_CTYPELC_COLLATELC_ALLxL^ElL$M^E`L$MZETL$MWEHL$MTE@L$MSE  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~_.,=;./\?*Illegal byte sequenceDirectory not emptyFunction not implementedNo locks availableFilename too longResource deadlock avoidedResult too largeDomain errorBroken pipeToo many linksRead-only file systemInvalid seekNo space left on deviceFile too largeInappropriate I/O control operationToo many open filesToo many open files in systemIs a directoryNot a directoryNo such deviceImproper linkFile existsResource deviceBad addressPermission deniedNot enough spaceResource temporarily unavailableNo child processesBad file descriptorExec format errorArg list too longNo such device or addressInput/output errorInterrupted function callNo such processNo such file or directoryOperation not permittedruntime error TLOSS error SING error DOMAIN error R6033 - Attempt to use MSIL code from this assembly during native code initialization This indicates a bug in your application. It is most likely the result of calling an MSIL-compiled (/clr) function from a native constructor or from DllMain. R6032 - not enough space for locale information R6031 - Attempt to initialize the CRT more than once. This indicates a bug in your application. R6030 - CRT not initialized R6028 - unable to initialize heap R6027 - not enough space for lowio initialization R6026 - not enough space for stdio initialization R6025 - pure virtual function call R6024 - not enough space for _onexit/atexit table R6019 - unable to open console device R6018 - unexpected heap error R6017 - unexpected multithread lock error R6016 - not enough space for thread data R6010 - abort() has been called R6009 - not enough space for environment R6008 - not enough space for arguments R6002 - floating point support not loaded L(L еL L0LдLL0LLpLLL@LL8L аL!LxLyLzLL`LMicrosoft Visual C++ Runtime Library ...<program name unknown>Runtime Error! Program:   KERNEL32.DLLFlsFreeFlsSetValueFlsGetValueFlsAlloc(null)EEE50P( 8PX700WP `h````xpxxxxPMMe+000ccsUTF-8UTF-16LEUNICODEHH:mm:ssdddd, MMMM dd, yyyyMM/dd/yyPMAMDecemberNovemberOctoberSeptemberAugustJulyJuneAprilMarchFebruaryJanuaryDecNovOctSepAugJulJunMayAprMarFebJanSaturdayFridayThursdayWednesdayTuesdayMondaySundaySatFriThuWedTueMonSunHH:mm:ssdddd, MMMM dd, yyyyMM/dd/yyPMAMDecemberNovemberOctoberSeptemberAugustJulyJuneAprilMarchFebruaryJanuary???D???@?@W????w?A? ?@??q????@??}?N?@ ????m?A?????q?H?!?????a?Š#4<Xq?BJ=_D?mKF=Ԛ?s7E=@[-?K>d:=g?Z}=\uI=s~Q?g:"(N='?9~$O1=q?n1%=p)k?vʌ=`X:?q.W =Pi?g>M=[?ֲa M=_3?֍,uXO=`Ɏ/?1w<=>'eH?` JJ=x~? Š&=n`Y?˖C=0?]/=# g?uP= ?,lC=5q?ᕎ =@Dӳ?-[@=pt4z? فpnJ=l?i.Eg<y~??O^'=(Tt? x;;=P?RRF=&?XɣN=J@?~=Ht=c?AzU"=nB?U_lj7=]?qBD= h0"ؿ؍ IQn0ؿHn&E:׿E7D57A׿ %@@ֿ*Z+ASTֿrJD@ӑտNT?w3kտr19]ԿFKm8C!`Կ1y2Y@ Կ*(FEO5iѿ4Q!?: пC +pڌXпxO,C"пAri<q~_ϿR v== ~οo6@mPͿ d+>̿9Ȓ[\˿8B'&˿i[JZOʿbnEDE}ɿUgc@H ȿUZdL" ǿ=Dj!ǿVm:A@`3ƿ~%3kcſ"7M Ŀp>)%ÿ\Bjx¿#6HˆQ;`t-¿=]PH0;TaָE&a-#KV\ Vb4M@U@Xx55@캿D=iI^Gי'7AԷUNҪ1GƴO\C@+Bg:IB@Zu}M:(T!1n]vQ<)8h׾o$|f+x2S74U".mœFB*6IKS_ D 5M-Cz1}BKG c?OfFL,sX4I+xm w$VcE?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@?@??????????????????????@????@?? ? ?@ ? ? ? ?@ ? ? ? ?@ ? ? ? ?@ ? ? ? ?@ ? ???@????@????@????@????@????@????@????@????@??|)P!?Ua0 !=+34?2Q =`??7; WJ=`7E?'a%C=MkK?*b<=0ɘP?*,z?=d|S?KT'K=R_V?bF=p^BY?E&= 9&\?߇N9=p _?߭Eb2]A=`?f#I=hb?O2H`3=c?e2a1=ԆLe?2RM=f?A3_:=@0h?[2ieO=i?1rK=k?Σ-=l?̈[8=yQm?>|W8A=՛ko?>qݲN=np?z m{ M=t)(q?m,SD=E`q?}e?=ԩr?}~:fE=PSs?&A=& t?,&8=tt?eѴN@=PSu?^p?o40=!9v?W?N=<v?+#GYM=Hw?qC@=Pex?0 &ے=Xy?8=<8y?!({=H= z?d,GB=6K{?ҝE M=¾|?w31!=L|?^X-F=Dfqsg~7(7s6uE(ruv.E,t]rLvOrȚ p&qC"5FzIqoOjpO|Wp Ȯ/N#D5pO/3N^o I!` 1nDCE"Bnu ^!EWΉm--0lNpCP&`l™J$akN8xj[ -=8Riy~ La8i[٬zF+ghk<@8KHg}7ڒ%gmg1&3{4WfI8e}OA8ӌd_\MP4.dó6D@uc2I{bTWB`b.r}X]La6MŞr<P`;ƥIpη_v<-UF^9M\̢N3e[ݻk>? #JY&-DPZXm4I@@7eWO/jUIlNAi0TWq uIbR|m:K@VNQ?|G¾d0`7O84 fXLzB7CIp4"%H`/G: WI`ȃ1D/!H@%OAA9"Ix'8RؔN;*2]@G?E?@D?C?A?@?>?@=?;?@:?8?7?6?4?3?1?@0?.?@-?+?*?)?'?&?$?@#?!?@ ???????@??@???? ? ? ?@ ??@???????@??@?????@??@??@?????@??@???????@??@???????@??@???????@??@???????@??@?????@??@??@?????@??@????????@????@????@???@????@???@????@???????@????@???@????@???????@??~?~?@}?|?|?@{?z?y?y?@x?w?v?@v?u?t?t?@s?r?q?q?@p?o?o?@n?m?l?l?@k?j?j?@i?h?g?g?@f?e?d?d?c?b?b?@a?`?_?_?@^?]?]?@\?[?Z?Z?@Y?X?W?W?V?U?U?@T?S?R?R?@Q?P?P?@O?N?M?M?@L?K?J?@J?I?H?H?@G?>Y"G=>.ܶlWE=>jۋbH=>^IL#=>(i&I=h>gݟP'E=p>*)D=>&N=x>.;ĝ@=H >Qyu3= >c-=@>Rݡ:==> {M= @>C=` >bߔB= >tdC=$ >9O=>B NC=>j&==>.<=@>`lrG=>!ls1= ?8= @? mN=&?UtQ$=X?PiB{^C=?Gv72=@?qlm+=?!.j7/=d?L C=`?m +=P ?5Od% =?r<(?*Hga2=@ ?CI=r ?sA=* ?GTiA= ` ?KՋD=r" ?Dp`q=L$ ?~G=4& ? D='@?E=)?'P<+?f4±cC=@?qWn{;=?gC i8=?XKD=P?G;R"=7?8΁3,'1D=B'@?:+NB=(?1z@J=*?3=+`?wU4?=,?DO=;.?$b=/p?g)([|X>=H1?>gV=20?OBO=*4?bPA<5?e4=f7@?|[{~*L=9?ٹE=t:?G]C='"?@(6F=? #?'A=@H#?43 A=Ax#?uN}*J=C#?)r7Yr7=]D#?.K="=rE$?r =F0$?3=1Z1=H`$?h|=G=gI$?ܩN:=J$?4e 6=K$?{<9==M%?uYPwH=NH%?-*8=Px%?yF.=-Q%?\9 ;,=R%?29Zd@=T&?~YK| =sU0&?WĻ(J=VX&?RIG=X&?W N=Y&?g'9=[&? D"^=2)$7bmLMӿ( ԏS4_ >L|/ dM4g±82qڜ1ןqaPCQo%;9?_0Cw4g%6L&M;k@ڿ81ABۏ1uB)_ Y/󓎣,:x.Ճ^-?ޯԝI-:]=O>O#w_jُBn(+E -V~|_B}_ACK!ܨY:_5Gt/C$>#Hm- MVn@QU^tA$OÄþiM@K8|;2@(AV64oꬠTC9?&u.~Fs:4Կ J_L II=@0(ן$.G?}3Rʏ3 !|.4*ڟ ඄}3? G"jm >; *O 0 :O 2K;޿ Q`4_  ZD 69* F_ T3ʢK M.֢> @_@? 1\hUXpM&Jx3Ҭx/h 78Lv]EV 3Bv9r_cM*5&Lq3?:R$@܎$=K'\?Ъ{b>$EvCIw8R'FG_j,)+jBD|_ `kA%'r BL TE_GO#i# ;^طH?6(`JJ\HB5``.11\?QDTӾ96оk< xE˾CqTR;ǾdG GgL@_h %? SS@b?Wdy>c*GPAiFC.ֿ?53=?͸)a,?][SqnC?nwtӰY?eus<)kp?&<ߑțuE?Ka<>?5a1xH<lX? aJ.?#Eq<1 ?1j<1Lp!?|眊<dD8`<;f?Ud4ݛ u? gVr/eT'?*mb|L%?2L#FG?AֈDh?ԛƟfNJ?:|”<۠*B?&KVU?An/X0y?c~˛@@? IqI`B `BYnYnexp10?1mm.s,)?'>?i i1mm.s?,)'><i? i<ȿmb<Z" ?.ҿu<ϕk|?c}ؿ,g<ysh:?;8]+޿ ^ty[g?h9; %S ? %L jh2yʿ;f 4݋<Xw$3Ak ł<࿇暳s)f09N,J?8v<uZEeu?F2k Wt-v1-VA`пgY?\ϗb buпP/Ye?&%ѣ@}<P/Ye&%ѣ@}<?gY\ϗb bu?-v1?-VA`?uZEeuF2k Wt?N,J8v<?暳s?)f09?Xw$3?Ak ł<?2y?;f 4݋<?S Ϳ %L jh?ty[gſh9; %?ysh:;8]+޿ ^?ϕk|c}ؿ,g<?Z" .ҿu<?i i<ȿmb<?1mm.s,)'><?UUUUUUſ?UUUUUU?*llV4V>>m0_$@8C`a=`a=@T!?sp.c;`C?i i1mm.s?,)'><i? i<ȿmb<Z" ?.ҿu<ϕk|?c}ؿ,g<ysh:?;8]+޿ ^ty[g?h9; %S ? %L jh2yʿ;f 4݋<Xw$3Ak ł<࿇暳s)f09N,J?8v<uZEeu?F2k Wt-v1-VA`пgY?\ϗb buпP/Ye?&%ѣ@}<P/Ye&%ѣ@}<?gY\ϗb bu?-v1?-VA`?uZEeuF2k Wt?N,J8v<?暳s?)f09?Xw$3?Ak ł<?2y?;f 4݋<?S Ϳ %L jh?ty[gſh9; %?ysh:;8]+޿ ^?ϕk|c}ؿ,g<?Z" .ҿu<?i i<ȿmb<?1mm.s,)'><?UUUUUUſ?UUUUUU?*llV4V>>m0_$@8C`a=`a=@T!?sp.c;`C ? c??-[6?N}X<?]݃?'Z4?e-CS?F?,w?(F_e?X2CQ? ُ㈏?wT?/VW?#(7? L?hC!߶?c(y?-˶?X1Uu??Y.<?PB?>SŎ?6 Ӷ?'P9?z^3? ΂?&1yA?(+_R?mY?}"?ƟlW?P),H?,b??@??c\5j?=Mpm?c+?BpVV?Q9V%?]|=3?.?|_P?%?ػZq\? ,6?5DKBӹ?@IK?Xf?v?'?+3?2y?g/p<?7C ??ED;?h7r?=?(r? EVw?У? ?0SM`??3?/*2?56Yz?Ʊ?Ge?4?%KV?rH?I,+?U&X>?i.?c4?? ?NT?j86?f*"!?~w"?nJR?17!?|GD|??*a?} Ũ<?ƼpAؒ?ZM$^@]>= @Z7@abK?؝Z@t?,@T4s?a g @XpM@D$_@n}in@)M@֐@P(*C? mz@E3&ԿfYeY!@,d&@#7̓B,@@=U&2@UUUUUU@9E47@ @}=m=@@ 8λB@[[@u+E6G@@?@ӸHO3oX ?% #Z."S- >Q!r?M%ᾎ;DŽ cd3>$9t?JyA]VJ]>Q䫢I?ZIο7t`=cH??ZS +ߏ?Y9m|1~-g>b/[E?8QSվ7KǓ>€p?[j3HX& CUx>XzvC?*ɿa#wi#:wB??x#qQ?L yaF5d>2*q?ɾ?c3yƟ0>q澺k?g\>{O>>u>=?)IſX3{9lf??V}X9܈?+*tsJEX*yhU&>3H?ܨ9ԪFr>)(g?VtFcfy>?p6?K=3il??Kk0vB-G? 8dlMV>|s`?Pt"!k?JI>΃+תd?s{c|HY"?X:n>//2?6G^#f??dčDo=z>-Bվy%#(A>ō:?S/|o3fW|aD `N>Fb?kt LR3ec>Df/?@b̰kع??"])E}>r>ľ>nzru>Cԑ?lf6 noP"Q?m˹A>fǰa?+kWZbI#݄,[>=h,?nĠ}P=Ȣ_??+j>&D(>ll?bIJm>gjVa?\yNW> 4w+?UUUUUU??"])>E}>r>>>nz?ru>Cԑ?lf6 n>oP"Q??m˹A>fǰa?+kWZb>I#?݄,[>=h,?nĠ?}PȢ_??dčD?o=z>-B>y%#?(A>ō:?S/|>o3fW|a?D `N>Fb?kt> LR3?ec>Df/?@b̰?k=ع??Kk?0vB-G? 8d>l?MV>|s`?P>t"!k??JI>΃+תd?s{c|H>Y"??X:n>//2?6G?^=#f??V}X9?܈?+*tsJ>EX*?yhU&>3H?ܨ9>ԪFr?>)(g?V>tF?cfy>?p6??K=3=il??x#?qQ?L ya>F?5d>2*q?>?c3y?Ɵ0>q澺k?>g\>{O?>>u>=?)I?X3{9=lf??ZS +?ߏ?Y9?m|1~?-g>b/[E?8QS>7K?Ǔ>€p?[j3H>X& CU?x>XzvC?*?a#wi#:=wB??ӸHO3?oX ?% ?#Z?."S- >Q!r?M%>;DŽ? cd3>$9t?Jy>A]?VJ]>Q䫢I?ZI?7t`cH??fYeY!,d&@#7̓B,=U&2@UUUUUU@9E47 }=m=@@ 8λB[[u+E6G@@@ZM$^]>= @Z7abK؝Z@t?,T4sa g @XpM@D$_n}in)M@֐@P(*C mz<@E3&ԿI,+U&X>?i.c4? ?NTj86f*"!?~w"?nJR17!|GD|??*a} Ũ?ƼpAؒ?߿ED;?h7rۿ=(r? EVw?У׿ 0SM`??3?/*2Կ56Yz⿛Ʊ?Ge?4%KV<?rH?BpVV̿Q9V%?]|=3ſ.߿|_P?%?ػZq\ ,6ڿ5DKBӹ?@IK?Xf䵿vӿ'?+3?2yڿg/p?7C ?>SŎ6 Ӷ?'P9z^3տ ΂?&1yA?(+_RmYп}"?ƟlW?P),H,bſ?@??c\5jӿ=Mpm<?c+?'Z4e-CS?F,wʿ(F_e?X2CQ? ُ㈏wT¿/VW?#(7? LhC!߶c(y?-˶?X1Uuɿ?Y.?PB?_CN?Fn 棿 c??-[6N}X?]݃?m0_$@m0_$@xC8C@DT!?DT!?@gg2LL#F=J47ࢨ:Esp.:3gg2=?`C<<8C8CX<1 "?';<ï&b?,kg<!J?ĂeT1<1y"?z<F#?Va<$ lc? x<nu?cv5<?0N<ߢ#? "$<bm d?gQ<|a7?麏<ac? 0 H_<А$?]U ?<8Ud?|}}?<5盧?~+< ?)0>B<'HR%?I&<^:ȅe?>!ʎ<sl?ecb~q<ۧ?rʀ<F(&?Zn<'`f?47j<㚦?+i U<oX?F.K;<.'?Yhʼn<4lkQg?;+U<3?М m8<&?<S(?Y=t<:@Xh?,n@4`<$?<n?9ܮ<-)?\<Řwi?=<R%é?f@<*B?aw<G^*?m(<<2;j?PE<?Ҳ?<w*I?n'$<23?z7<[>t?V-Ai<?`DTb< ;?S.<TR*?)R<2k?,%ً<r?SC? <H?Zxgf<`/-?#<މ7m?w <悆a?_"C<lX^?@<{Х/?$8^<]hNp?bX*<?}_Ͼ<s?pt<hf2?$V<4{#s?Ug <?w<J.?IZ <*Ow5?.@<FHv?N <!?j<v(?z"<i68??!<Uۊ<o]2'?I<Рi?G<o? Ιn<9[? |^<.?>oj<._p?1S<X?l<~?o.x<%3d?{=4 L?V!=b#?@g = a?Gz =]ư?6 =oJV?J b='4?/t><w?a`<_?a e=F``?/f =#&?5SmT4<W?Rz< ъ(?vY<k?pY. =y?8'<KuC?j<{ =2<5?ýd =x?"a =@ic?%[9=?kRF<6DC?ş ܬ_<5Z?ȡk*=3?*+xi(<G&?r ly=:3S?z j<[?'<;!?h=<?:<sd?3 =? ?{!mB<<>? *2=2?cMyoG=Vsw?8K$<}?Cl<Ϲ?-<'F?ɕ{<$R?܊)B<#?<c?? ~<F]?&= /?94E<? T9?9* )<l?e/?B6!F=u0wu?M떐 =k`(?<4=?Kp=G"zI?$}Tw5< [?ߪb<Ka?aF7=V j?Ty<R߂e?M]-e<$[?3<Ễ?QZo =n6)}?, ,?؏?M?x%q? ?/xbJ?Ȉb?uÏ?(Z?t?{}2F??_2?>T^?u ??4td? Z?( ?WIY?d?{?|:?S9?s? ?K???l.?Z3?;E?2:@?>?@@?"Ir?64?@Û??765@Z?&+-?w'?Q?Gpt?2&?X9Ш?Bq?/? ?vɛ?Mj$?3?s? b里?V?% S?Vѩ?ߖ%@?U>?2,|?ܜm?Vkށ?9?I@|?P3y??}>v?H|As?#?(b;?탿7?]o-4?Ph0? H,?:5)?Iٓ\%?f,!?갸%?N?$k?oay?*??Y ?$??(?a?9y?9 9R?%R?F?@I?j T?0ұR?VDD?oWsg6?UJ(?>t?2̄λ ?1_?$*2?[ێ?N)?V?l$G~ٮ?+6?tF4؎?,~?"n?<փ]?|ߠL?l6;?6**?|59?:?HK?s7 ?I-?$z?9\?>|.~?-W?^\sY0?:Rp7?mbzA?G4's?IyȊ?%=_?C\2?Ou?m.?M?nw?KK'F?l^?:" ?Ѭ?}6lw?:@?7Z8> ?$ f?e')lW?zD@ [?jq?PJ?FB<'HR%?I&<^:ȅe?>!ʎ<sl?ecb~q<ۧ?rʀ<F(&?Zn<'`f?47j<㚦?+i U<oX?F.K;<.'?Yhʼn<4lkQg?;+U<3?М m8<&?<S(?Y=t<:@Xh?,n@4`<$?<n?9ܮ<-)?\<Řwi?=<R%é?f@<*B?aw<G^*?m(<<2;j?PE<?Ҳ?<w*I?n'$<23?z7<[>t?V-Ai<?`DTb< ;?S.<TR*?)R<2k?,%ً<r?SC? <H?Zxgf<`/-?#<މ7m?w <悆a?_"C<lX^?@<{Х/?$8^<]hNp?bX*<?}_Ͼ<s?pt<hf2?$V<4{#s?Ug <?w<J.?IZ <*Ow5?.@<FHv?N <!?j<v(?z"<i68??!<Uۊ<o]2'?I<Рi?G<o? Ιn<9[? |^<.?>oj<._p?1S<X?l<~?o.x<%3d?{=4 L?V!=b#?@g = a?Gz =]ư?6 =oJV?J b='4?/t><w?a`<_?a e=F``?/f =#&?5SmT4<W?Rz< ъ(?vY<k?pY. =y?8'<KuC?j<{ =2<5?ýd =x?"a =@ic?%[9=?kRF<6DC?ş ܬ_<5Z?ȡk*=3?*+xi(<G&?r ly=:3S?z j<[?'<;!?h=<?:<sd?3 =? ?{!mB<<>? *2=2?cMyoG=Vsw?8K$<}?Cl<Ϲ?-<'F?ɕ{<$R?܊)B<#?<c?? ~<F]?&= /?94E<? T9?9* )<l?e/?B6!F=u0wu?M떐 =k`(?<4=?Kp=G"zI?$}Tw5< [?ߪb<Ka?aF7=V j?Ty<R߂e?M]-e<$[?3<Ễ?QZo =n6)}?, ,?؏?M?x%q? ?/xbJ?Ȉb?uÏ?(Z?t?{}2F??_2?>T^?u ??4td? Z?( ?WIY?d?{?|:?S9?s? ?K???l.?Z3?;E?2:@?>?@@?"Ir?64?@Û??765@Z?&+-?w'?Q?Gpt?2&?X9Ш?Bq?/? ?vɛ?Mj$?3?s? b里?V?% S?Vѩ?ߖ%@?U>?2,|?ܜm?Vkށ?9?I@|?P3y??}>v?H|As?#?(b;?탿7?]o-4?Ph0? H,?:5)?Iٓ\%?f,!?갸%?N?$k?oay?*??Y ?$??(?a?9y?9 9R?%R?F?@I?j T?0ұR?VDD?oWsg6?UJ(?>t?2̄λ ?1_?$*2?[ێ?N)?V?l$G~ٮ?+6?tF4؎?,~?"n?<փ]?|ߠL?l6;?6**?|59?:?HK?s7 ?I-?$z?9\?>|.~?-W?^\sY0?:Rp7?mbzA?G4's?IyȊ?%=_?C\2?Ou?m.?M?nw?KK'F?l^?:" ?Ѭ?}6lw?:@?7Z8> ?$ f?e')lW?zD@ [?jq?PJ?F1|MCatan2#Ex$EDU$EU$EU$EDU$EDDDDx$Ex$EDDBB8B.?0gǓW.=??0C0CU I? Ͽu}MUſUUUUU?Sz?????????????B?B???r?r?????N?N?????B?B?????H?H?????b?b???????F?F???????B?B???????V?V???????z?z?F?F?????????R?R?$?$???????t?t?J?J? ? ?????????\?\?6?6???????????b?b?B?B? ? ???m?Lyc>=*p%??C;0=|?Ix"<=`` ә?yM==orO?+C==v?R1=PQ ?Ӏb=@P?5M[g?=V?d+[7=?nB>= kz*?w#8=0nط?C#7={?D i00=ˮf?j -=x)?}z= ? 0$=HV?o=X a?;M_8=@? 5=?^@'=L$?/r(==ɥ%?Nl,"=@\r??t8=85R?ӇӜ=L. ? >)g=Ը3U?Ӱ== ?hXg+=og?X=ذ0?{fHn=<w?y5s3R6=)?a8< O4W?4bV0=L?4@=@?Xۓ4=Tk?>_(=?*o=@[c?,=$4b?dO"=lx?#608=ě&m*?ɉh"0=בl?n6ѯ{<9[P?cezb<$?F 8"=8B.?0gǓW.=??BBxPD?X1=??0C0CΗ5@=)d U5j%5j?~@5wzA.lzZ? |?Q-8>=޶W?0 k8=ޮp? x9=>.ښ?pn5=Yح? Q*=c??b6=Y?T?=>?W!=@-32?Dz=p(?vP(=`?US?>=e?g7=`ŀ'?bͬ/=^s?}#=Jwk?zn=N ָ?LN9=@$"3?5Wg4p6=T?Nv$^)=&?.)<lB?M%=`j?w*= <śm?E2=ެ> ?E=t?? =OQ?w(@ <0?Ac 0=Pyp?dry?=St)?4K >=$?QhBC .=0 ub?-0=?a>-?=?Й,<(lX ?T@b ==P?3h,%=f??# =V ?ߠϡ6=Y?z $=G? $l35=@n?[+3=Rŷ?sdLi==p|?rx"#2=@.?|U2=lԝ?rF=a? 4=Y?sl׼#{ =`~R=?.i1=,? =vX?=p?h}s"= E[ ?%S#[k=7H?j=!V1?}a2=jq?20J5=?5=x¾/@?"B <1=iz?\-!y!=X0z?~b>==:? #.X'=HBO&?(~=xbb? .=Cq?y7i9+= v?:=0 ?2ض8=xPD?X1=??Q?Q?????????]?]?P?P? ? ?U?U?(?(?`?`?_?_?????z?z?1?1?p?p???(e?(e?@#?@#???`?`?hk?hk?,?,?x?x?????N?N?x?x?p?p???~?~?HN?HN???????p?p?Xi?Xi???????????8?8?s?s?pI?pI?&?&?????o?o? *? *???`?`?Z?Z???0?0???PY?PY???`?`???pm?pm?/?/?????8C8C0<0<+eGW@+eGW@B.?B.?:;=:;=ѱt?ZfUUU?&WU?{?Mu{<`w>,g5RҌ<2ؼcnQU Zsni?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~united-statesunited-kingdomtrinidad & tobagosouth-koreasouth-africasouth koreasouth africaslovakpuerto-ricopr-chinapr chinanznew-zealandhong-konghollandgreat britainenglandczechchinabritainamericausausukswissswedish-finlandspanish-venezuelaspanish-uruguayspanish-puerto ricospanish-peruspanish-paraguayspanish-panamaspanish-nicaraguaspanish-modernspanish-mexicanspanish-hondurasspanish-guatemalaspanish-el salvadorspanish-ecuadorspanish-dominican republicspanish-costa ricaspanish-colombiaspanish-chilespanish-boliviaspanish-argentinaportuguese-braziliannorwegian-nynorsknorwegian-bokmalnorwegianitalian-swissirish-englishgerman-swissgerman-luxembourggerman-lichtensteingerman-austrianfrench-swissfrench-luxembourgfrench-canadianfrench-belgianenglish-usaenglish-usenglish-ukenglish-trinidad y tobagoenglish-south africaenglish-nzenglish-jamaicaenglish-ireenglish-caribbeanenglish-canenglish-belizeenglish-ausenglish-americandutch-belgianchinese-traditionalchinese-singaporechinese-simplifiedchinese-hongkongchinesechichhcanadianbelgianaustralianamerican-englishamerican englishamerican$vMENUvMENUuMENUuMENAuMNLBuMENCuMZHHuMZHIuMCHSuMZHHuMCHSuMZHI|uMCHTluMNLBXuMENULuMENA?տ?2n{a>?? M=?H{? {4r>?Pא?"">?u[?* >??G0_(>?4wb?i^^?(>?0?p3>?@?FM>?8M?BV>?d?}Ba.>?ȴ ?d>?g?ߊ>?@?f\*>?~e?-f>?]%?D G?>? ?\>>?X?1 #>?E?h>???ⳇ>??$ 49>?x8?k0H<>??rش8>?8fm?"m>">?ħ?[?k?"%>??݉@fR8>??T:>?T!?3&F >??<[#>?%?Y:/(A6>??N2>?8O?r!' >?r?8{K>?p?9l9$>? G?aj i9>?T|?'\|#<>?$?}dj#>?Wn?׈MVx:>?,?18o,>?D$? c/ >?@ |?x7|1>?|?9>?p #?IAu=>? s?xٴ4>?p?edf&.>?,?fA>?h*?v2>?$gN?RE\K>?q?'^IE>?DΒ?&aH>?L?&KrQF>?,?#/'>?إ?]Xc?>??Ԯ}>?e.?IdWA>?K?ΐ?>?Xg?4*A>?_?[džJ>??10H>??hc#]G>@,*?Qx F>@@p?ekR.N>@?Ӿn@>@b?O>@$Q/?CJO>@@E?G>@[?3E{A>@Tp?SfIS:>@X΅?B6)1<>@@3?>ځ7>@$?s(N>@@?V 6f=>@(?{>@@(W?-Jg >@?"aPK>@xm ?,Sڤ6>@?6hb">@@-?k,<>@X>?0=>@O?׀IXH>@-_? @>@@n?2E>@P~?=ő8>@lj?[j&,>@L7?x82>@@?c#VB>@0?7ڨ.Y>@P?[p&>@ؔ?h4MA>@@?EplE>@+?o$E>@h?\*K>@?-?B>@@P8?(l|@>@p!?u@J>@@p-?V1> @89?5>@ @ @h)P?R`DOG> @T[?9%K> @Mf?/<>@ @q?Ò?> @{?42G<> @L?Â|/> @Y?s @>@ @k?Òa@> @XS?x(3u8> @?vO,ib> @ȥ?&L͒C>@ @?}L> @X?Lo> @x?-Ϡ9> @s?6FID?9>@ @8J?gsL> @d?y> @?>&09C>@? @@(J?IV C>@`w?^@N>@?#%@>@s?MK>@@D'?ήQ->@.?9 !G>@6?.1>@>?.1NcB> @cE?sǔ1>@@LL?nHN>`@HS?W$>@8Z? Ȃq;>@a?N/[7>@(h?=mC>@0oo?H75M>@Hv?P.#> @|?G7>@@*?#42I>`@?ooJ>@?-#>@?h% F>@@?Rx^D>@PP?s@>@4L?P_! #> @4?:#G>@@L?qg:&J>`@Hɹ?5L$.4>@\w? !1C>@? [<>@D?<=@? ~=@y?B> @?~.4>@@h?u|8>`@E?A8yL;>@h?41C>@{?-+oF>@$?xO>@s?՝mT2>@W?=> @-?î\=>@@?\==`@ ?j\&">@X? 1D>>@?#O#`I>@?}0>@?F\IE>@t{#?ׯ,B> @0'?E ]$>@@,>,?ކ?5>`@0?iIqE>@4?ha;>@9?AD>@.=?̤KFw=@DMA?=@`E?apI0H> @gI?:->@@cM?%Q>`@@UQ?Ly5ښoE>@;U?vg0/>@Y?jv UG>@\?yK>@,`?A%My>@md?H> @ h?pM>@@0k?k}<>`@ho?f7O>@r?}O>@v?+ iI>@@z?bB'=>>@`}?ZM>@?1M> @a?R~=@@t?QNT B>`@x?W3cL>@ g?+(=@D?qJK>@L?;,*>@8!?D>@,O? E> @Du?in]D>@@?%3F>`@P?^F"VM>@?}30}->@@?~F y;>@?l R(>@躰?\7`>@?dg;> @?;Sv@E>@@<|?M>`@Y?|};2>@,0?@$?̯/p">@?\(0>@|?[s$F>@I?dӔV> @T?0)LK>@@h?)5G5>`@XY?|zJ>@@?W޾L?>@0?6:>@<3?QB>@x?7o/M>@Q?KcZ0> @?z-A5>@@Z?"BDcI>`@?`I.>@ L?Ld%>@ ?"l"w =@(??!>@?j^J>@8?ϞH0> @LL?%C>@@T?J+N>`@d?;l>0>@B?^{v@>@Ȋ?@Y˕B>@@?Tl0>@ ?w4n4>@G?oN=;> @h|?L{/>@@< ?Bnu5>`@ ?`,+>@d? 5>@$?l >@C?~+^M>@^?PKQD>@,u?^{#tF> @|?^4K >@@?4O >>`@?XEړ J>@?(gԹ,>@ ?43-spF>@"?P`E5+*>@$?=Q QD> @-DT!?\3&c{#Tw=:zc%C1 PAPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADp 11o2I4t444E6\6h6767<7W7p7777)8~88888!9+99:A:o::::(;5;d;;;_<`=q=}=>$>Q>z>?}???? 4S0{001j374S4\44.5==> ??????#?'??0pE011111G2243r3333404C4^415 66$6n6.8888Q9_99k:);t;;;;k<<=*=^=r=w== >>.????????@<00 020=0O0Z0x0}00+12:355555555555*6P022 222222"2&2*2.22262:227333^4444445!5@5_5m55555(666788Z9999|::::H;e;; <$<4<|<<<<< ="=@=R===.???``0 0/0:0K0224555555555566666668r89:5:\::::::;>;G;;-=V>?p?0I01k3M4h445n8@88^9n999:1:J:c::::4;i;;;<<;<<$=)====>?`N0u00Y11 22223C3%4@4S4`4m4444444449556^66666 7I788999k>h0q277'9D9t999:$:0:?:M:^:w:G;b;;;;;<<@>k>>>>?g?l?{??0g0000 1=1I1\1{11122223+3V33334444*585C5R5W5~5555555555556$6;66O7778819:?:[::::;;*<<<<[=|======== >>7?F?R?e?t???@q0v000001'1172233526Y99 :::<1=n=B>v>>o??PY1!22233/44S5608H8\889,9@93:U;;n<1>>>>>>>>>??u?4'1E3366x788995::::C;k;P===>?<01k11*234406T668888L99;<<5>>??$(23f3333T4z46778;= l313e36~666:::::::::::::::::::::::::::;;; ;;;;; ;$;(;I>?>c>t>>> ?6????????@(090|00000000011#1,151s1111222$282a22223p333/4P444]5h5y55t66/77"8o88889 9*9F99:k:::;<><<= =3====@>R??P00132 33*34P556}66788888889999"9'959:9E9J9U9`9q9|99999999999:$:F:i::::q;;;;;;;;<<,<<<<>>?!?v?`003n3/4G44@5{566T7B8[889:a;<<=p 12`55789e;|<===034l57::::;;;";,;6;<;B;M;S;;812.35378%8=v==0#1:6<?&?$2c25677799;=>>h1344k4t44444444444 555(5<5H5T5]5q5}55555555556*686D6M6o6k8x888}>>>122o558>?8>0M013"34b55569 ;(;6;;<<>?_??Pr12|345k6o6s6w6{666666666666666666666666666()12-37333Q4[46666z92=7=,3&3<3344557788 =r===> 60^0 22u556+7a777778 88/8J8a8888888888888899$9-9:9H9Q9\9h9:;;;;<(<-<4<;=E=L=S=Z=a=h=o=v=}===================> >>>>%>,>3>:>A>H>O>V>]>d>k>r>z>~>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>?? ??????"?&?*?.?2?6?:?>?B?F?J?N?R?V?Z?^?b?f?j?n?r?v?z?~???????????????????????????0000$0.080B0L0V0`0j0t0~00000000000001 11A1H1M1W1a1k1u11111111111111112 2222262:2>2B2F2J2N2R2V2Z2^2b2f2j2n2r2v2z2~2222222222222222222233 33333L3333 4474i4n4x44444444444444555"5,565@5J5T5^5h5r5|55555555555555666&606:6D6N6X6b6l6v666666666666667 77 7*7C7t7788&808:8A8`8g8q8{88888 99999 9$9(9,9094989<9@9D9H9L9P9T9X9\9`9d9h9l9p9t9x9|999999999999999999999999999999999::: ::::: :$:(:,:0:4:8:<:@:D:H:L:P:T:X:\:`:d:h:l:p:t:x:|:::::::;$;+;1;6;C;J;U;m;x;~;;;;<><<<<<<<>>>?@x@2K2U2 4&4A4\4w444444444 5#56?77>888899999:%:2:>:F:Q::/;;;(==X>>>>>?a?v??P00G00 1N1T1[1`1e1z111'2M2`22223347444F5X5j5|55555555 6606B6T6i6{666669i;;;<<=o={====>C>V>>>?????`0M0^0m00<2Y2j222222*3B3T33M4g4l4{4444J5g5s555556]6c6s6~666x777*8=888899*9<9N9999<<<%>7>u>p0b01!355O8V88:;;;;>>m>>>??< 0?0000044855)8-8185898=8A8E8I8M8Q8U8Y8]8a8e8i8m8q8u8y8}888888888888888888888999!9%9)9-9195999=9A9e9i9m9q9u9y9}9999999999999999999999999999):-:1:5:9:=:A:E:I:M:Q:U:Y:]:a:e:i:m:q:u:y:}:::::::::::::::::::I;M;Q;U;Y;];a;e;i;m;;{<<===i1111#2223/3O3c333 4$4^44444E5556667 77P7c78n8889-9L999::?:R:d:w::::::::: ; <=<<<=o===$>+>R>6?N?g?~?????????l90`0001=1112333334)404:4444+5V56666677)88888888888889a:";;-?5???,q000M1235677j8:9^999:+;>1E23 4$4(4,4044484<4@4D4H4L4P4T4X4\4`4d4h4e555H666808`8r8w8~88889 :":E::::[;;T>[>a>>> ???>?G??0]0000w1111C2223/3R3\345@5n556*6V6j6}66666 7*7D7t7z788888888899-9#;b;{;;;<|<<<<<<<<= ==.=i======0>J>Q>e>>>>?W??\0000[1e1l1>22 3l3333o4445E5\5~5555 6676M6666Q7q777788+8R8g8888 99&9@9j999999 :0:{::0;[;;; <===>#000R1112'3333333333333333333333333334"5M5555-6<6i6q66666%7`7777778)8Q88888%90999J:Y:::#;|;;;;;;>5?P?V???060Q0^00001[1g1o1111222 3"3C33334R4h4{445L5k555555"6866*7Y77788$858S8p8}888888)9A9P9:::::B;;<2>>>>>>>>>?P}0 22H3[3 7g7R8<999o::::;;;T;n;;;;;;G?? 0,0&1[11 222S222283J3Q3d33334o4444445*585555566&656@6L6_66L7779h999999g;;<2>>;?R???0!171?1{22293B3O3Y35E66667d77888%9u999 ::2::>;c;;;-)>2>;>@>X>>>>?!?A?S?{???@00'0000012@2e223C3T33B4K4W4f4s4|444d5|55555 676w666667W7j7o7v7T8m88T9j9v99999~::::4;I;};;>T>l>}>>>0?|??P|+0D0c00112227334555 6#6{6666666677.737[7777858a88889,996:::;?;;<<<==>>???`d0011C2J2\22 3*3933B4i4467C778J8891:x:::; ;;4;;;h;;"<[q?p0}0$1}11m22233!3(3/363=33334464F4O4Z4s444444 5.585V55666#7B778X8w88888888"9990:N:v:::&;];t;;;<4>4???l0 1s1111111222222343q3334465e5555566667f779::k;; =2=o=====I>??p0123I333Q556/7n77777 99]9g99999P:W:]:::;;$====>">U>i>p>y>>>>?=?V?[?`???l0{22222222303b3h3r3{333I4l44444515M5j55555N67799:B;;[<<<< =|======0K1U1_1z11111111 223 3%313s3~3334444 5(5Z5i556v6~668*88888999z999:<:::: ;+;h;;;;>>>>>?!??1122222233"3)30373>3E3L3z333L4444"535D5P55555>6T666777*727F7W7g7{7777777777838:8A8G8`8s8{8888888 9'9/9C9N9Y9t999999 :k:::;;*;;;;;;<4l>?U?Z?t???@000011D1P1p11122#2;2G2n2s22222 3"3q3{33>4G4T444g55555555550656?6y6~666757;7J7777:8l888888888 9999 9$9(9,909z9999999::$:(:,:M:w::::::::::;; ;$;(;z;;;;;;;;;;;5>>>">0>5>=>C>Q>V>>>>8?=?D?I?P?U?c????1(131V111;22222E3K3e3t33333333344%4/4U44444456696@66#7*7L7S777778]8899-:3:<:C:e::::;;;!;&;B;L;b;m;;;;;;;;<*<1'>?00"000000000p1:22)33333b4n444b5n555e6q666e7q777j8v8:::;";>;;<<<<<=$>B>b>>>G?a?j?r?|$11102L2o222222334:4D4444+55667B778888(9R99*:3:G;;;;;;;;; <>>>S??!0(0J0Q0l2g3334 5567788)828r8888919<9N9a9k9r9y999999:G:Y:d:::::;i;y;;;;;;;2<<<<==+=B==>>^>i>{>>>9?C?U?w?????? l030000000"1j11 22223 3323r333444X4c4p444-5G5T5555556H6R6667#8~8F9:??04335%6y666 727<7f7q7w7777<<<w>@P3334`4f4|44444I5567799I::::e;;;;======>>>?PT0234$45[555"6@7\777l88889K9m9w999: <<<=N>[>>>Z?????`D0<0001B113~666 778\9~999j::::V;l;;;==?p0L0d0k0s0x0|00000000111 11Z1`1d1h1l1111122 2-2W22222222222233366M7S7g7z77777888,8`8m88889J9:::;F;Q;[;l;w;7=H=P=V=[=a====>c>o>>>>>$?+?@??????D0F0X0000000011"1(141:1C1I1R1^1d1l1r1~111111112H2N2x2~22222R3u3333444*4/474=4D4J4Q4W4_4f4k4s4|4444444444444444445 555%5.5N5T5l55555"66777777777778)818C8P8V888899 :::0:G:U:[:~::::::::8;;;;;<<<= ===g=p=|====> >>S>\>h>>>??H00"12j3:4k4444~555R6|6666d7v78<9Z9999 :=>??0902u4y4}444444444444 555667 7777#7*71787?7F7N7V7^7j7s7x7~7777777777778996:<:A:O:a::z;; <<<$<<<< =!='=D 0c00 6699 :: ;<<<=u====>>:>K>X>_>o>>>>>?000H2Y22222222 33-373J3n3333]4z4425Q5555566"696R6n6w6}66666667[777F8 979999::;3;;;l;u;;;;;;;=R======>>.???o?w???0(010<000 1K1R1111I222'333334W4555567Q777778899::;;;<<&>>>>???C?L?U?k??????????|0 00Y0]0a0e0i0m0q0u0y0}000001|111e222225=5566677777?8h88888 :':G:N:r::>W>w>(K1m11111232V233s444;;X3{44166677+888 9999':O:;;;;P>`>>>???E000011$192E2U2a2~222233333 44#4B4]4f4n4[555526:6F666667u777778 8888899'9c99999;;;;;;$<1<]5>=>I>>>>>>?8? 00001"161@1^1j1v1111111122 2T2^2f222222223 3D3S3[3a3x3~3333P444{556666666Y7e7y77778878G8S8b8)91999A9I9g9o99999 :):p:::::::;;;;; <+01"3=3S3i3q334W555N667v718C8U8{88889:; ;;;,;F;e;};;;;;;;;;;;<&<0<`<=>>>>>??#?2?8?Q?Y?c?p?x?~????????@T0 000'030@0G0R0Z0b0k0t00000K1X1q1~1111!2N2{222223E4Z4y6O7~7P`3.4P4b4t444466666E66666677,7>7P7b7t777=::::;=T>j>t>~>>>???`8$080L000y111334444 5d5555"656d6s6`;pX;;;;;;;;;;;;;;;;;;;;;;<< <<<<<<"<&<2 ??>00122222f3^5s5778!9699999:#:;:[:::: ;8;e;p;;;;;>`>>>>>>>>>>>>>>>? ???)?d?~??X111/222233Y4f444456678)8888 9?9K9Z9f999$:|::;&;;-<<>@p4d566666"7d77889u: ;;;;;d<{<<8=,>4>>?\^0d01 111122F5]5888888888888j999o:w:::::;;Z>k>z?$11112222 3(3y33= t3z3p2t2x2|2222222@6D6H6L6P6T6X666666666666666666666666666666666777 77777 7$7(7,7074787<7H7L7P7T7X7\7`7d7h7l7p7t7x7|777\;`;d;h;l;p;t;x;|;;;;;;;;;;;;;;;;;;;;;;;;;8?>>>>>>>>>>>>>>>>>>>?????? ?$?(?,?0?4?8?(>,>0>4><>@>H>L> <<<< <<<<< <$<(<,<0<4<8<<<@>> >>>>> >$>(>,>0>4>8><>@>D>H>L>P>T>X>\>`>d>h>l>p>t>x>|>>>>>>??(?L?X?\?`?d?h?l?p? T0001 111$1,141<1D1L1T1\1d1l1t1|11111111111333333 3$3