pax_global_header00006660000000000000000000000064131473372070014521gustar00rootroot0000000000000052 comment=fd36b3595eb2ec8da4b8153b107f7ea08504899d statik-0.1.1/000077500000000000000000000000001314733720700130175ustar00rootroot00000000000000statik-0.1.1/.travis.yml000066400000000000000000000001701314733720700151260ustar00rootroot00000000000000language: go go: - 1.7 - 1.8 - tip install: - go build -v - ./statik -src=./example/public -dest=./example/ statik-0.1.1/LICENSE000066400000000000000000000261161314733720700140320ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2014 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. statik-0.1.1/README.md000066400000000000000000000035751314733720700143100ustar00rootroot00000000000000# statik [![Build Status](https://travis-ci.org/rakyll/statik.svg?branch=master)](https://travis-ci.org/rakyll/statik) statik allows you to embed a directory of static files into your Go binary to be later served from an http.FileSystem. Is this a crazy idea? No, not necessarily. If you're building a tool that has a Web component, you typically want to serve some images, CSS and JavaScript. You like the comfort of distributing a single binary, so you don't want to mess with deploying them elsewhere. If your static files are not large in size and will be browsed by a few people, statik is a solution you are looking for. ## Usage Install the command line tool first. go get github.com/rakyll/statik statik is a tiny program that reads a directory and generates a source file contains its contents. The generated source file registers the directory contents to be used by statik file system. The command below will walk on the public path and generate a package called `statik` under the current working directory. $ statik -src=/path/to/your/project/public In your program, all your need to do is to import the generated package, initialize a new statik file system and serve. ~~~ go import ( "github.com/rakyll/statik/fs" _ "./statik" // TODO: Replace with the absolute import path ) // ... statikFS, _ := fs.New() http.ListenAndServe(":8080", http.FileServer(statikFS)) ~~~ Visit http://localhost:8080/path/to/file to see your file. There is also a working example under [example](https://github.com/rakyll/statik/tree/master/example) directory, follow the instructions to build and run it. Note: The idea and the implementation are hijacked from [camlistore](http://camlistore.org/). I decided to decouple it from its codebase due to the fact I'm actively in need of a similar solution for many of my projects. ![Analytics](https://ga-beacon.appspot.com/UA-46881978-1/statik?pixel) statik-0.1.1/example/000077500000000000000000000000001314733720700144525ustar00rootroot00000000000000statik-0.1.1/example/README.md000066400000000000000000000005001314733720700157240ustar00rootroot00000000000000# How to run? Run `go generate` to create a statik package that embeds the binary data underneath the public directory. $ go generate Once the statik package is generated, run the web server: $ go run main.go Visit [http://localhost:8080/public/hello.txt](http://localhost:8080/public/hello.txt) to see the file. statik-0.1.1/example/main.go000066400000000000000000000007421314733720700157300ustar00rootroot00000000000000//go:generate statik -src=./public package main import ( "log" "net/http" _ "github.com/rakyll/statik/example/statik" "github.com/rakyll/statik/fs" ) // Before buildling, run go generate. // Then, run the main program and visit http://localhost:8080/public/hello.txt func main() { statikFS, err := fs.New() if err != nil { log.Fatalf(err.Error()) } http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(statikFS))) http.ListenAndServe(":8080", nil) } statik-0.1.1/example/public/000077500000000000000000000000001314733720700157305ustar00rootroot00000000000000statik-0.1.1/example/public/hello.txt000066400000000000000000000000151314733720700175700ustar00rootroot00000000000000Hello World statik-0.1.1/example/public/img/000077500000000000000000000000001314733720700165045ustar00rootroot00000000000000statik-0.1.1/example/public/img/friends.jpg000066400000000000000000002071361314733720700206510ustar00rootroot00000000000000JFIFdd ICC_PROFILE mntrRGB XYZ $acsp-)=ޯUxBʃ9 descDybXYZbTRC dmdd gXYZ hgTRC lumi |meas $bkpt rXYZ rTRC tech vued wtpt pcprt 7chad ,descsRGB IEC61966-2-1 black scaledXYZ $curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Kmdesc.IEC 61966-2-1 Default RGB Colour Space - sRGBXYZ bXYZ PmeasXYZ 3XYZ o8sig CRT desc-Reference Viewing Condition in IEC 61966-2-1XYZ -textCopyright International Color Consortium, 2009sf32 D&uC  !"$"$C" Y !1AQ"aq2#3$4BRbcrs%5DSTCEUdt&6FV; Q!1ARBa"2bq3#C4$D ?񩂃;Aq0 nj%oɀ,؟ }谸϶"⯶nt1;(%6!%V6@"lҞ',<@׭v @uTItinNp>ʖxkio1gݗy/2q&@Ŏ^uŒ'k  VqV'z'im8%@؂!sLLƍ[Qخbv]̮'CHC9fhՍdn ¸Bv:-I=kaxg}M7 !KBN-GhIHiDBhAC M("tnB( o XR56:@wd&3HȲ^}y[@!>lzwڦI$EL,.E+.'By?aR)]v˛='ʞ5cQ!OR\L$`\Pw҂Zm%_|*I+FZDۈ4lC(??(`OglrauVܒw& DqU+ZfT!w>b_M…n1FGU^m`mv03i!$x^8@G+w'|ӀApax~7;AM w(xM${ kIo *WdcC}F8ܤbUt!7J=ء{ AXO }^+X2tC`F;3i ᓧdA;#$m.IߺM+QGk:x@"{M$o $^0 k{a : l;Vl 'X.W7 q:wp ~DoI0. !{I ߺl2bU ma> JM %$aIoRLi ;U:,4} _A`B :B;* H. :!lX\fH0ֵɼAX<\tH)xK9 AoQ4jכ4d5nzI$"I.erA)OE=$v(p1s}Lp*4Ye)'Tr"&2$dT;tc8](ZM3 렀S7BAثA^a`$/ ;o VВ# (Zt:B7ׄR1 6R֐7;sy⒔D)Q(B~q^m9BwPv<$ҌCR!CFxFUHa#rDHF:Sk͍1$ ʜ+3}\_GMf;XLT ze-D 88+T]V8$}CNFˁbh|  LG7*vfMt|}p޻@gРHdR 90aY.O84X I,X[XW9鹁p{-(sUaX#m 0SA=w0wBmp-5n&׏Mp$c :Al(o@`_^".AC_[X"t+K0RyA.b`W.# xgBn@m  >op Aik@7؂']  {E+7P@q7<6 GsDO! ^ NP 6'H]bw-‰ГHMu}D W Mko{"a @x@;q#FrT,hl Q0uNw A`.@s< //6Se-`Ϋ$F8&\rAEחyε,wL$Ő.~/T W!AIQI8CϜ$G($7QWDDxzYA.YBP(s m㺟R\zGIʝ˾:uUۭ7:VG᣼}ϡnM^40 &ܠAq@C!RZ~أ9ndI IԂ P&e펺D&'JTbF׆2ow;UKi9%U* Dec6J@0O)8cVzAv%Y'yc s%$ t.TI"ѤyFի,bq|ya`NDv@F{c/ o(_WwM(X+N2l[\h8'xNM&qdxD@~zB P5&c}`D#H]Dpo({C{` mp` n6v0,;G|&  2km }}`X\X !4A{av S[{mp!+H#45&㙀9 [Ah"l*㕠Fh@') n4 @R@KHM$H`=/D#8WoeB u7X"F\{|x௦W -v!t}p>+鶰V0fd0AyK@K  C $+xi ؂LBAӺ ADiӌI r*:•k Af!cI:%'7Ų򯅴6%ee͝/2v#F{ymunqsjihR֕iS{qq%'F̍MZH~^xGbRR]EC0=:VT "ۈI$EaqIT,!JjTlQn$pjl`mB̓,}PI.'m)7i'x]6{A%00j9^;k}`({m :z `[kim݃NxtHJu'04tf$솄6R,Fʣjp;uc"BoDaALn8no PV0-W^ i0[4Kb#~"`o 0H76>fB #>k! <`!JBJT e0!AI$ڶCt)P]R L6J'SR5t8JK-/5i#8OfǾ2;tnP#j8+qdoW } \+OaZ_ @c܂({@dߌ7k z+5 ݄Úp6 Ѐ/h% #BZqIA BhN]8\4 N{ }mby\1} ^`[Hl`aF[0pv q8BFAy- " mm*ǀ#4'^-,@E`o@i0 6KCdv^ a͡6$H8(snd RM%!{L$c61ST-#g87!߉k)4T%  vR~Tgs >CK(p{0#BLov\} "YY e;,₝ w"Nm(IS 9ΕEL%$q6Y㡪tۚFx :_gH p Ot0MR!XT?%d DRS@̅oeaٴr iwd,' x""P|pJHNbh'L+K= QQ4rT~uEF.osɵ]ܲHTn>O$^3BW*)\AglRoEy:SaHTWR=yN ?( Kеi~@_Du촱%635Y xbg΅D!]rhyF%KQ Gz)z4H7YSDb:3" p0]@)5ԘexWR)nTi6`IJ?XhUF9ONUU^5c$ʼn !ik9ζ7ŔEhS[RKb6W6ol@ .}mdTD@JʼEm#x2ҷA(Bi B /١]_o҂s^iNaVm702@s!GOo4:ÝXS CEDҭ6 zqAkFHWJa#PWti"v570bV :vH .v3cЂV*wꅵUMd;" :YEĎéU-b^;U4g)DỊ֓PD&JR{![)#R7 ~1&|U5HEaHõɪ@](aDdĿRoVSv{E(+t0d8I d_#nZ? (og2*Ba\uLLȬMnSLRlܶ3 yB8OtmTXp> h.ѽ?P2^PIXY:1eWPF>N& j}.ŠѓA !޸?x5,ֺ0xV!Sf^Vw%kȰ  IMfvc*V^H3n']仜S3)tӵꎕaIs 7^0&T> O[k.SB'8z/ʁ6A V M) xyZGIr f; ˖|7 }dK@:..SjW`ܭ._& ]N;G5P YO| eV"}g[ޚ{kA,yd]ĻU*G>?OW7/rzQa[?DĻEje_t)A2WPP n}&%״TlK$X}ߪ\濌 cݏAg;, 3FWBZ1e^UvJaOv귷"؈5TXRM;kgo մ/Sg“՛o|jM'V]Cqՠ˼8~ؙnQ+~b݄:A7b!4LZc7RShWb*%"vyk%nO8D.EH M JL:%J E !i6~ufwgN"|)ʛTlʵxEVCrI l>%@k x:JYrf9m9f05%N7}l-KLSDF:j>h=f"5'~MT#V6#0dt3$zÛ$ W6bB{A0nnM?btHTt3Jkd-F5뿌<ܭe=nNDcki7(8IueCt4_[`q/E)>T4co;)`íEF_ro%I^j؇!(BA$ӧ}a/TG/ b'W jN] }bk?h%`SwrR oR=J0˓pE+ eN $}P& =%Yh6t7n닛l4@7 i(לTbǐO&Sz&DN.e)K}IJi ,!`5sֻ5sj_~'ŇQfԬ#5q[Uh\UW"2GL%T֦}m&*XK䀑}%)Pm *P#oLrOf^`]~=2 CJgpuƟ83Ui{8j\NTOJ7)R,=a΀I( R߇im{4YW(O,N߈h^ingnT)6W~xkaM J婋S\f&ƞu3UN$MoHMC;sa?uK,|QO,T'N?8`y^51Ŧr%u)b.RV¡8*:M9n -.oRC##WM>!Q~Lu֜hnYXu4JYpl腊vmyE GS>x̦߫Z)YѵTHJ ͸?f9j[Y./kȹyi0.;Y:'HLaC4EC9pvtdǕi6kt߃ԣrt^/fy%@4Pj?36uL,\%R\e ["CJ8.#Njx_Эy'%Y~y3NT} o-$CzlVԕvys)!$7FR!6oP#$*YS&^Y*)´NQO\/I|VJJ+vgno \R kuh\ZNw$RCfEteJ,@\[M6pl=,$\-%'-E+>R)I߽>+veN_y9iƔ29TSJQVae2kz_ S{6֜|"a"q ZI!s uiNby eGQ5feld.tdK3>`TSm*vvY[2cJK~%%8OmF_WtVI2r?V̸ӣG}U7%gU%s|R$BmJ}@D(zځI׶#T=rO! $ZJQkW=֛4߶YX!av*5%9t8\"@D5LQ1☝B(ܫHKjt<'@Q yJ@~Vϫ-GX# ΋X~1[LP@0Ll꘡m*x2]7Zp~g^CBY6(o)e W s-Xz :ˆ~6d.Ynh8WvXy*pMSE6,'͆Ui_Q#rBѻtpv`̪t"XobQDg֊|96ls0׍ 8ԡVUX^6Mm+clM93Ry|PU4ͿJ(aݜ-3$C&g|b6J~EZ. bݰȄS-R&y>0xNwO+ dC jngEVL:XZ<'UCvxNڟG%2<1i< [>09' 3]}PT}4EEӤSGz\ZacɭwoskL=O/,Z-eϲ{BHTTGZ:S4Ãɵso%S-Sw-ob0kUCh/R,5+im[)/y6c%${ Y&;bJO0ٿCg[$Qaēa@hN+7FkYCoD=OaMk|Z| Tmj"miƤ/J0tMnuOҹoFCɕn&GO%R}^JReCM^46V"Gȏ>? ޿xC1U.W҉Jl*)?3ﺆI/GaZ6׆s|MM+@]%a}2zI}C*7KẀ?#aTIzrW Y)l.Oyeҿ}^4GIPTNÕJo'[_[vW|Vj3~<˦y 3#5x )CO]ٔW҈W)ߥ!~R?v4thQ_])%^KhCٜx@e>*tZ,CKˤvX&>LC+ y*2Y(?v)N6jӐ)&Q`ν?s~q0y35'{6U7c5:PRL3]JM;4؟3cԴWֽɯ[.Pm҅rRe? q6 aIx(sId:N˯D$ S(>OkΰW90K)Ĺ]mJPJ@qx_":f6jGL Ȅ6vEG>o ,dpTNF,$v$^^C\':m~U@]^p*"^NE,%%,`6~{b;^IׄJ;[ݞt.%6:0/[* ߜgS+%Hzh_}Ht!_;@M婒[ W֨R)`o6ͯh=OSEFe\9s@JбijӉ>?+WjiK}6R-:ƣG F+M1\W]o-Sd21\`RByt-j%zLrTk3_F})n\ZS?%NR&fMʂE_O͏u2VI)maN$9l|HZG/%Adw CKXKP7tJ *";N*p>x•xi~( bamVorȯ &;z3 hP[.%-#v}Pa`2#4zTZq%X1)P[&Ղ^K#C%a`E W9yw&X iP=iw3i}uCQ,.sC!3B矙pĴ`C* ]w>V]ͪ\ ܏@^m q3dPT2R5;H"6<Uf :?5HRlv էIºuZІ k$^@WFqdF~U'ooL}fx!<ɕ*R^KT E5tPz? ?2('iC=^9m#T,:ʴTFeYSgbdJӣPR'ּn\j0*>؈rb+ǧ T-&]k#u*ou}1)tP#) S*ԏK&]k::(suA}F feGycjqȓ5z%w7heHo3 eH2~Uj~T(6Dvd+`SIbn_ziM+IzJ}k$zP:":ߩJ]6r>[Mt2DfN *Y}^rVH8c兵_/ 5%ֻ2љF+CM ͘(n}#튉ix 9Pʘ\K]!<}k.E0gK 7RݑE(BNon+>0 e#^K.^%W6PΝL( bS=3yC톲_zkɢ.`Qc=SɻO*M2tS izXFKɠ{ ]W'XΗ36@B͕SRw 6jqVodUhY;퀥{UŭV U&mЦ0UW4j)Rp`ʕ{w*O)}*n\q(MZ0cuqFé*+ Lܤ8ib],U`k(ϼ<$L2ľ yqJXdʾƲ:{!tSqW%HdC,(y a+Ar}Oc[ % ߔH1*) 6JJyC e ɑ}'%eAJ+pCglrVtq$}mZ[9)n]b+-eZU"5uP%OK]Folu7XfsG4r:NtO#Wn3P>a<cVA_h򑠏TaN UJJP KE*6@ C^J%-n8gfrpxk~OVid%N0YP\gm;]Y*]Iz|q*<ɗ'% ]5wsY:ε7 bQHԥiJ2l MǗ*Naz{dQ:RBQ+IXE玖)[wLnaJ6YWpKm\7&+\=ꐷ*DjUgqdDDz\O2F$ ޸r V*]'폛IPԒ|[ae#$8QqD,۝U+]-3nOӇG#l+3.ou'~v3`:Ku)^0m3q19oRpm0^?;|ϓb0RGgfl2qwg>wC{pD+ĥ#QB0]Ḷr Txh@ygR6N̑0P . VOr^P\HiĤ C]X ƞf^q8;qQy~1.2IfЮ_Upp~w>q8?+BӇCOqi΋ZKeʝ9jMUdP|ރNLM :|!Q)AI >2cYbI\?*䏿#QKeQL {`[2:Q&MY[bM2QFI&JTԧ2' O-Wd^iwa'`{:q񯥆 ݈q,Y˥ [cZL&+ZBl.i-!;D4bAzuh4{ꗵweiI+&T$]F,6)LiuYe%U7?8v5sde;n # Ez\Q+Q~k*U&. >~׶+gRŋkX$dV ^$kj cE0w6h׮g!pqGAEUrUhs\:Ǹs?fYmж]m6*-(5=ZNҬQWk&SUS pPm5X,=U_Hqn'eޑUoJR~Ǟb=P9k(6b'1rai25P}Ǩ6(aĒEQ1?6QyT?#lI9#퇛$q>٢lCUr' 'oڈУ}϶mD1m|5'D8ܝ`qo7dHq ߶09Bf >DlXQkqrNFIK]sTiPJ.vqNm.llV* /">VYj5|arB=+%ВBuIF9lӏEXeswڛG*RhJxiųhNNL=1,J5ɔha!A.6v2Už-Zm̨"eVJ( \'+dNTG7/e&#*ɮE&aOfHJr۝ ՀpjmTIe467 #Ѕjt&?WQA(obB|CJufOó _0%jWm+RKW';9]pH)5f?#UZ$F MKr5NTj3o;ky`yZ5{$vBM>96R&nh.aiP joXr0ddk~n|=LZ{>\3|-yK}@ :zîa;R\Q'(!텅"ޚ>PAE7Uѿ-buŀkl=+Cq! K̃_cW;Cl,߫po ryOcl2$9R!+emޯ\g%u>0ߝOcGŋmkk%kӯs?(?|?u)OE5AK K(zZ {GI?S2.'GЗH,}G%: Pe^+~[RSae]Z+dǨӆ!W* )s3IPmHXZ@{>D:C҂jlX}~Um|#2~d6F?fEj+0ll/dZȜTq,̪T.懌|ç意%[EḘ nQJU-Bǹ f (2eO4JJlŊYw pakUM&+[>$- 'GqMhTM%*<u TtXk5GܮT'_C's|6tS~f$tW'܀Wz[84 THM iizzG$"fBgdxͳv^&ᤛW > u,vT.}zX`}֦ۘqQЯ*Mʰ0hYCE+Fm2{GH֕4?x-9' muBv)Xh>OԺUt*0Jo#*Y׭ 8SԿDCUv4Y>(q`!3+7#!BEŒmr2.-qkqCY:rqLv8X(̌˹n ײ=6bJJoa?rqdޟ:-0C񑜸QRXuC#%ĎQ:_bL\sT%Xʜs+7oOBM9BJo#x5گlJn)mJV'5|(w^d+@/u.I4sCROq-IP1_ukj $uHRӘZ)#xYt)"R=n>ȋ7ƒuC޻}g@5SP'aFS} O$R*r'֌k Ϩ&b um|%N{~VG o]oWDC$0\mٖD'x[pwZ8SEg0-3风/7In`IK7K {~>1x)wݔGIH& ޏ9[*eJWo:E4T|mGsв4-\;? wZp!y>"mxp 7A UΆ'i9{# b#oG| >REku3q!{J' 3rFmiC Wk3a AO>z8-ǹ<o MYs3BGSM^gvֿBI!V\`S\|"6{V~u&m'i/4@9a`[sh)-rQ_#Z,w!~p5zN?tFBӔ,\F| \֧xéu?l_.7K5F~05h_OC ocTh[jP;e~gU7Mg?'+407s B.Y3y:m-8aDD}U =|FÍ.:۝%\d'F䆭U&bu3M & 9t8֒ iUPRҔ5ggr"bUn ̎|Qu>}[?VU=O@qV/1#ONz J_N3J1AM&˫X†Hik*QtQV?1B\ԋ)zIT,L KWK6KƓdqPgёE/ΛH\z<֯c<з #7^'jeܷ{2֭~O*IJ{UNkjk 0WW/?r²,LA?Oᄈsz{rPB[ '<86D֏5gRjO µ7OUN-yܘ?uiS OixY/ZF0lW&9VlόUQU_ORjaim/a,x.rЬW[M?,>1]p虦au)pU.+Jƹ/8Aօ]0=VDvbe@W?ԅJ+G;.uOҙ594H (-umaxZmIwCDT*&6ߜ2 2,E ZuobτKcU̳(e  9TITE,XZAmwKC򸇠aa:YUEU͐u-ԖWbQ3SYUJY7j(?H$}JuT!R0:ˋcϳ>^ "i{ԧMci{PC)XJJ8iQTH56^=Ҋq> jE9oPz褸F*_E)0 Qd}0PWq|- K BKgbMݩMt!ePxyx(ۙP%)'[qo*9k6K:v({'> bp*vHF1,wJ<ͥB#@Nk7Bb"EhZJ~?FX9A?\))SK }b*$ITZ Dm)E/"4%2=Pe%]&oaFp=6yۇ;ʤ%y 0˯XÿʕZ89jZ){CO;B,=y/ >Z">g'Q" 4d0ZX[XF^Sw0܊?u_0hr#הmZ|ٴ]g{o'QRKL4Rb whv08I3×£.N"υ_tx:%k^?YTB>}~1䄨/ޝ~1M5]pTw񅠩GxWi\[IKrb9UOC~1κ-Y$`黑AW{yN?|Ae6b9Sر@Lis8C񅠭JlbPڕ$y^0LuvWU΁2'Ӌ^NE5oZ}kv~MvO)pxw;`,~^0ŪH 7 LZSd႑tߌ%gev- Ex˜*ByT,"?:o 1mʎWaH釫kVlWoܧH$)OkqXb|M2J*$q(A7o#N&`L4 ܃6׍(ШsOƽP%Z4G>^1[2˪^2RʗDnܼ>0=Ū$ ^xJh|U<}L.˥W%SN+xChG%t Pt)|sEmb}LOΫ P1@?ͅ"8ZCtplD6o+On'&;Ex@7h_`)Si[G v_C \l=zGTNr9@SeBmM/a~oHϝ?aPaN0 niHSǴ(cR: z9D޳ 8{pK%?zLhPTw;+mo>s { IP@q0% (?jSyF>ܩԈy?(s(a+*7Q5=$?YPoEzeyqʸcf;uae7'*@|רď=Ͼm9x+ mU>T_01n pʬ+Be+po1bcuA~ H: =0x6i^0p{U`xsr6"?kacQ8RϨĚSaH0དô1 0h0?9{_9(4@4tP(KDЉ t뱃pgQ.H~CQ%&;7㾐h(EƖ +R-% IO2FߨOtyīndvas#YjBu.MoJS|!ȝ0g!:R H6N_~SFK >8G<WP܃1;xUZj2ʲ6pCQy9̏ aQ#~_`g2t($ky*~X8I(XDq)a! A%Inf񇊍"X@.^DRڥ6HZX@#]:RIy{g"T}oHI$FZh(fM GjtT),̰l1$\p6[EQ,ւaYa~*6JfOuBCtSU-%fI"j8 Ӧe,R2Ӭty>&o.@s2mhAӜZC;f̩DSJ%}t1ʪʌF&MK,V98k{n9c uSM[x&[Oqo6lf~PRUYRlmA)C@-9A$j-&m:P+3w)<- ({k+-Y2ͭ;YHg 2Po;az Ӕ^ƔOkN t\ǫV~d % :YH%o4ՓȼZ.ꕟ$_@5t;GgLWCj>J5XXtdvA{U$XK"Yo՚U pua\bBIL#V ` "%N օ !I9 u!(ypVE:* *adXxjBrѝkRy۔v #w'3T[mE;)Q{JFo'uBN>y;= qIr8Fsg]>˴\T:RvEh%ڢ "PQ7pT7nw*ĜԹ~I0e*)GrW:K/ݯggΊ1ukQ}y|abNO<ƿZ=Ul݇3 N O4?~{["=Kd&jg3S _']4jKI>LNSCFz= s(kW5^ʰJt*0NpfWzCnTjI3~(K8NČ;Nɶii *ʰm,yV $SaYХR\!>#JcbE )YRY.[*Z4όI0)8GlIjOOuM:z3K,Fi+^r_DuT&{p8w+w``(ݎo~#6SA}Pp&k15:=k?dK?k(W?!ih.)-E4NJ ez,~p}=fGBFC~l JGrDv' bAkUi0Zp$ n_۸cm!>Jo"BZp%P d?O(a,Hu8L>0M +YdR;[9ߒ`MX76ã bB*;όiY`D~o% ;F 鮶JzeM|C D|"[ "z꒔f}hRuJ#9B[xttE#*W !T4q\ T o u$J21F*Q%%Vx4<*EZT(`m|_S̶"(e*82Ζp  @JRWLN F k^AV:Ih[mn Hdg>gJuUܴxAX BzEFQs"VOLf,AR;[26loW8'ތĶj25fC$(n >i#{ihZ[bS0xAMؔf{CT&5\r䄧1VSs}m}04ʔL`6M{D"<7E\ #U({e9L6ۖJ ؗR@"1y 6Uc+bs Pd&U5TWz ٖ̮lݗfUJMy :9# TS]5JsO2'Z5I6ʑ5PP[ĺO=j3Ρ]A[fG320Pf(Lf6ÀA[&Qk#DH2u0΋*]pZ&z!MÍs*bWU3 s 0͞'̽~ /(>vd2Mh8'W}9NxB+aqt>LUκo+.sӟW(Ok\OREN]MfBwα L\W3? nsxAO/2z~O[5 D9XH<" f_JQYk񅳗Q[Yt.mc P ;F=j_8ToCJ aQ}$wArx7 >1;1u.wq's~LV"0~p f.m.j\g U?.MVFG ^"9u ޅ!0NKKL̲6q?,39-od_aC/zloC]E,Ls+`i!sRd8 a85Ȅ҉O Y6=@3<=6͏7hhd-oD (0!-.6T6EmS@F q5a&D"CGmGfFӠ:*avF%&D~>qhE+ W1mItzeAa$_5?r)Eȁ 4]||"8iˤ:|׶cU4ma>BO%>e>Zq&YJxRX7~isGDjHȋF[|#2ĭSPB$%V Hu"([Fo PQ&F 12`m^%dC-]=b-F9LN|1*I ' ^#:\Mτh?;XTf~tUqRMB;}Pp* 9a9?0 Jk_]\yƖqRʀ8azgV IJt&V)LM m> 3{kzb1S^]hbsjzK*nukl5Ͼc$1[}Z^!HהVXHq&E{j]ljې`?0]s(mlU`*\Z7GOS]}imѰ`嗅3 ZmZqqaYP9XG#yUFi])ҼRdQYyQЍ6:ieꕚwĚЫsvXy)6Xp$i\,1ZL@.DŮ oėc% m{^!5jiɰ26C|G Zͤד9gRa@10bOy+]D5K6 MpIy1~ժ[8:RZ0."\T)'YP?IPg@nc \}n@#hp_z1T5i6-JHtT 0"y:|r/׺hjr?{Mɝ?5By:rxl 0iȅBk󲃕c^Z9Kl?\>r@ZAF/ZlT%o(Zej75qH6}n;{=ܕQ@UZHKJ+jA Q6PlNU`t@RhU4bXZs/b4>0 R=Vh:~ul~㨯SQ31PCl0m*2T9$ZiʄeRG{TKRXsϘj-KJ7;vĬ6E $N4jn980h -nqJQom>M.SS"бfv=?OniJmQ*frܯEq&0v'*B`UfINh]a!nQLDPk)E:E)D?+iflgPЗ[[[1M aDZXS) uI܎4Z{7RBkikJ2ˢBrIm)^M^=Q[g,İ@KM8ւ4VYJlLBP4RK)8f8r鳯-(4Q)]⭇o$LKKɺmpA*Z"viMuѱ|c"^RzqJZWK0Ek@!#-Aﲇ*:˃3kJPB1'jw4];ph@);\&/}@B?EA>Fl\VN|}}PJ1_QFhkL4'թM'^2e\Qe& 7GsTRl*vzA ~ ⋗m| u3+5)?[!*=Zk6]\Q\![-Q'ʧj֡4|`סʩԼ{a*NfNTۗNa5RTteOy4; *,E3UM O̓\_Ex\4 FZfk52z2̺ZzF\2e*qNOjz[ZTh͗(FdB)! y>{5i}I`ph3L &90k[/T*)hIiTNa *))X5`Y3x5e:#Njҟg_oUٔ{!|=q-LŵyoMK#jJm- $U Zl} 8qB2_=32^m4< 4jT{i(Z]ijUPzBs.Ee,"R]l*0;ZZ%,rOI|Vԝ ԐH  jǚ:iuVeu^u[\#oqS6(5} Ua'3Bz~oI՛ߣڀ8A/EȍjR ߢm Edd$6-Hez-70jE lhVw‚.Q?eh֛/c'f6;R#AMb -˖=鈩==ܥ>[$z V)eT-ZBo_l;1RJQ*Q XܔRVV*f mB!hSܨ)UJ]92(yOn+)0N:#8̀6?hD0VI3NQ%(byP%PiRw"1Y1(8nj򖧙Nu8I?/ȠP%B/%o*>z!Kl~ML̦R_0aO-J f~o % G$ d=.973Mz!JZeb4U%6LXvG@R6|z%fJk2=H_:d7KltB61By:V䏾Bko4Q50|!iI9oO5yZ0MbNlS73mXԼNzKX~i> eΧmj(ۭM^| ==23DŽ),4 bkTFjEK A0M7+29妵%R[b$fmV x>R\WTܦֱ;%+FgZm?Zw򘐜^BRB;" RѸ6v3Pߚ_$`)$U%An bYXr|ݒL-ȕr^^{i[s(b>/WTt7p7n6iQoX3cf͏5ŵ%V8T[f}(YƤ4"гBd~RIߔL~g/& RAV 2#VT$~ȅC=.D'& #s]~=dԹeU78~ȟ ﰂqHB Օ"*CV%z)e 5sԭKyMDe *c굣yHSܴjY*- m AOJGX#NF{j3+37SjjaD!d\E=fŮIJP3t%Oԥ-U8( [7`"j36A Al,-{QiVN!ny7Y*1,dNcvXlq*닂ׁb8~Ecge-+9 =^Fi!'Ъ][et|nfQJ߉OUu5#4lI*Yb^DrNĩ:K[l*%AvPn\@i]7d:ZmҔʩY@N<0hQ٢(sXwTFF,bx$ӵNQŪ %ؚm $ʕTmklCAR3XPk׌N+I WL6\\[MV;=Xwⵑ|cHA/npjTe_TWJ|`qCL%T=5vAn ԩӯ,@F6>B*-6;o4k>J]atbee{f4T8yCiӉhA7:X 3ALkB@I\3q\Z{wA6dh8F&;,&a"KCh+ZR m@SjJҭBn =V+IKdT>s};&YKFd"/rz-ѨL"U>T?)?,eRV[`%$e'LOhJI>핚[uJ7 黅sI Q*'S*bX[",A Ȟt5br{9 XrB?:$dg 4shrV"C[X+?dyuܳF HW:g3yUSsk0=նUVJ݌/}ڎ'[QF GsT31x'&)cM/YI0c=mkJKy.8*RJJ^ I[kx(- Z*S+Qm 5VyרOD*=lVk;N B@'xQ*Rfq I}f@ =LuިKMbm T|dYy:]]HRe[xM+*ǜDKGxfZiɶ</"RFg)M)=߹5#YU6MHĦ?<*6oj[>^\ܩz*j[T~Twv{?,~fms&%XdEt̳sgOmyE/'A*vV$KU}2 IIrD^H1JU tH3Kid=ÉJ_Wt. *'XB1F:/5J9'/ K;gNO#KeVӌد.p3[Z2Tg5jz3upz4!Lġ .SmO8 @[Xq-7mP=:\ҺZ`NVy<1,ˀ!jI@^+IJA" <j+'6bӅՉ2LUHKqy"djnĆGBO Uo&jI}\׭b&%nje-b 5E?Q_k&%XSbXYA};!k6g5tJ؎X1H"ΝF́ HK~ Wet0Jzgea,+v~u-ȍJY+55(oK8P鏝OeJL)4]G@a!WU0ork!K|c-I~۸O">GWOLeu>0t)VOfAF~H0hg6^ &bNGJ'6)K4,2KbTt.6oIH e'?Q!f1:u ^ [*KhIMbL˵ѱ"-{mNӡns_Tlk?dZsXzAg[RYANA%WENL')h lRXBrSVӗ0H&. zwpGD<p#>ǜZqQ \J"yqRn+rMF]~Rʼ*p$Ą 8/r4 OLɽ8fִrJ@h9z+riLM4Y=[.8Eʊjs /<K@9 jOm;D$f“Rl;Qa􎠫V4C8s&&\RV'XRN[[[u%HnRJmN)lI?Ci p:蹶p1&+s)Vͷ<\R lZs$\ CYL*qO#zUsײ—7x160V_I4R@ I<~g'eTm(&Z7wqĐIcITg%).^]Fk^L& JEct,D^Yd ")2Ӓ-#[1I-J2ލCɶ2a7TH% $~ TYۥq2HR#MaSpbwJN%Zu\l)*{Ey{ %:*lf ߥG+gN۷rhfK'un:6e<_{M; /nuAMMtlnms' ^ɔg_S?_sJ4rA=0F%RŝJ6/Rh@ECm>[&]솝SS51r&=0\HSϯ[ŽWጳڛN*%c-nʸUѺ66TBj%K%S'(&o;~E} ;bJz5R͎oVLs)uHPj>^]jbYeس#1m$WɰVo4ZT%)Q.M7XyVҢ:i& H\U$.X*-n:!_bPБ{NYZJƊ9<)HPQ@1UfqH;ZmVU_UiκjR;&P+JRHjgzUd4dW8\x#K6 um IC .6R󃗀6pNN:+.P7V 6̷H!SϭU)X];'*rHq $֧ 1V\[D#b(BGL_MTkZ+-qKܷfq0zs&R_|bE<ہ0KIB\ =Z=Š.Kܵ/T`v'[QPG,>1UT -p&(^uvtvU~%UR\|`mҼ (%Mm`M GNRl!RH)@-A3Jpf zZr#d^d7fKuš.yvVM|<(ZuӇ2Q:tio7]}͸ۈc69nW̶ӯ*emɼ6fx}ݙPBsT+-JMa̘ԣ"m1HiɆqNbnlt%o_Td,Ժ(\67Wo<;n:~@9buˇ^D]nP؝*9 G, =`kX >}IW!u;|z(,a'm>x6pYjS6Ö':s]X&SiLB</*E=s!} @eGp^Sч+Dr)^ST:Ak2os\Cu =I${ZU* 6x@Ui.!@RD #.AK^GEasfg>TK{};V}tJdE|#RZzfiR}iNb\sZ%+o=QB`4qتkϓ@}o[%IV[BZjSrS"ڃLumL T}w+y2 ,]Dᜨ!pmn- 4NWqȌ[2fdqW5a@v u,j3T`h&*YK(3~m)5 =κW0 6QS@;|0TeY)8~}Ss!2`Pu0h)t \h ">0Kcd%'Cڧ :^\ͰYeH;Mn)J^SR]ur%n(*~<# `ECZdPqc KT9О>9(7PԺRk~ <-Un&CY]0h15($ep4 cW5ڔۏjHċ'eBtݽƭ^Mʎ/=QQe]1#Y?T.T@T^vb]iO6!8T ,N^LE?SĞʸu~lxJ-JI%8yGs;%@_ɅA }z Sy᧪GyӰ 0("8!M]@Xr/扸[GkγNRzUs2X]9)Ll YbeKF]:Ę{![/ u\[ƅ%Sbmkzn%RGjQ#:㈕̰k\U21petc3!ɆPsg,f.2FS⩙4KBRokDg)Wi raQKeteKE #>X)I^yVbʶlcz+Ayl{#EJJ9["PA7iR⯛VMz崲IS]WwUR>Br'wTbo PJ`u~dv$S]򛾸~RW3Xw3M-Jm:~t9MGOxsUDZkY.fF*DrzyuZ}.C-K eJCfr+;10?vaGQrHPj[6L)h.['3rUޱNt2gajM8tj~N+, At8HhJTTeӥhbf\kpe `X+L,afgW{p;ԳJy+j7 SY@'_0F7RSt$0ԔĄ\M[8sFh!juAStM/ YvB&r\ơ'x 6txDUBS%%A󜈹 o]#UI#O^ȍ}З)ū)Rw JʵMp  (z@^$Yi; "z \HeD$Lzʽ>4\AQd`uR$iv~O:M{% ւ Q_bqwu! :Jҵr\F,oK lC?z_btt<㒩BYkQ).,zYSyZ $5$8Vɧ$8ͱ;j]bq|ti]-7N]KA٦ ;UjHg, Σ? L "2率BA-)q{!Fdirۄ4Bw7 JNȵ2&[*^U 'Gr0ur*񧞰nh_a-\k$+#~V_,cJeG1`^y.mpjol}xz{Ga+-\=։e-Q]>IYbLSY%ZM{sjkF;W`l.㘩S3F]aQ~7M vR+7zDsFP;!ʽtY{Jj^]r%)SUsuW)@ 4ͮ\@&El*R\@rvYc5ʺAe_-]ɗ+u$$f)Muq'9$|DWi59KZtT0$mĺs|2mxV2vj*)?rZG\&Cʭ4T$6]G(Kp>bL~Gjq/2ZV[5IJHo]zrruS3S8Q)K 8.W˵ގY%jL MT ^̹/yENb NYIi Eo~b8,H%q~fQ-͛m~ػ)k}@H9;!>'FUr` F [n)viHDH6in&BF|r q *NHR?Yj0܈<Ҫjaօ DdHba-n]#ѓ4eqSq%5K2qnʜ#Qpw$ؒHΞȷ֥AiFGp4jIL9OXq΅IXkM;q_hE͠OT40X*ֹP=?1\ɦV<:#Jh5pft'NZAgԏ&nDt!Y $}pkjOaB8ZY1gA*4L!J3G'E '_=́<^*ʟՖ  6~<ڽǤq$f%g*N(R6X]1s&aD߆ ל%Sqa6@΀{N:U;O ѵpd928yyt%oz_k,ESU^Ճ4V}2)6]( d/%@4dq$>< m_=vƹb6eftNJL@_b"ux8Miʬs9M%6fT񋅎?oK9(ˍƥ (i7 XS7#lőY%2R)Pb|~(Y^kIZH HQ4W^Vmi"زW)`RV mJTx {C λ }=xmΩi`ʻU9Q]XjLABi7]Ry"GF%,KScH$fbs;SW{0it_j ӌXd"t ׺/GP.S8{UA+6\q.l=M'(RUJB:A*Z,4Him*Z&ɔ/#HTMCz4UJe/"OnnbeIwRߝJ|;*#*uMbs IJd6gm[eVqaUĪe[H94*Twp"ND]NnWmm2lg%ْWhN븚P] Ђa-lrИZC)iɦB\ T/;0{Tin0sMK=ﻝ ;N-\g.)Ͼm0Үj=1Zu.,M- i7(qQr~P[o[Ghewn&vx@C \WF0Ŵ[ߥ{#gGG, $[hv/bG _}kh4`{:w~dCE< ı/gV1(LO5.ӫРtbWa;-ÿ27qfZTӏ8R@ :8Ҩ'DJ}YQAbJ;4zOEJAJ%v- ZP &1m ~/U 8T9pLLML\4Rw 12D.\ӹ< =uq։&Z׈J2Ɗc(nȇn.*병fQ%*yffeȔy0䔺`ZKI=PDd505w&d RC6IIQ}LY]ӥC9rl*̱} >3"Ph*q||"J?LĂ[@Sje9 ꑦjDzTQ80i{v!Y 5J*ĸPK|lmޙdJE%M)O*F|4fFYʸD@_쁨1ޟ(&X)t:e7DKi}) "O#>O|"=8@&*/m׷ I'Ad;ΧOasi4+@{61hG-&y N jQZ)$%{M#9nA"'oֈP@&s tZ)1nrR4t酦IPߧ гZ>)/U6m$mNi5jYJLۛ(9?O5fY奦m,̸-a79 - 4?,RnS XUR7I4M\8.RpNMuS%DĈGړOyVp~iWUNÁ:`IW2`_r|c%'׹tJG,?#)O*nBnrcQIu^rWʦyUMMBPxLqL{zN ,f'k{"1g L3%cPni/DaYT:ξ=$N7ȓ֤EMͽ4q]u!}I6Q4®Vg8gаq*Ǩ(T)-hZL' ɔ!-4&.8e"lSxR͎⏏pS2Y+;,l!dr$;sh8RoR$TYB[?TIi6K"绮\ %2J:Y)Uc<ǵ9z&PvgeX9쐝\YW'DBqnd_KKR&RYm]E,m=F4?,VTG N(m~QE]Qz7ɥNZz˨PR[Į!\ԗV\#=hüVzU!]ZJQ!7Mӗ٭:H{T e²_s UA6n㡰rH:`)_(#(qY źbU)Kn%CL?d">̺( dۥ9,FSR-\@*Y+=p_ٝvЫu˟Kݵ̺S+ L2jRNSL \Y&*Mp5S YR-M6} W;e =n$]MMr"-8ͥƔb#NeX֗0sֳ^Xc쎬!E=2JM:Odz:j{UQj٠pCEci@od<0vd&8kJ,!]SiR482.=P4Pfꐞ+y)'/^Vhe7).ؤpP)ndV9IUjtrC֨h/%ZQSy<$%^5xs:PwD+qK5mEu(JE%Fh4y}ޑs/؎Z(/bZ[sRSְ@WqhڏT֗ڐ{6fƘ#1/3޼53`@tRjFN\U:ߓ)d;3+s7R^׸B< viݼ{:ik Hce%Ԟyl;1=qbʨ }5RRUTKSOQɕ^Ѩ, g8BRomt쌬Tja)NaCOTg:IӪ e\QMyg&_9lfR*Si*P/] =@kSuAmٙI*uD 6ѺI"ĂA'l'OEޥMbIϤ3_;0DKiBZdg%'1*'DoZ-jJ`Wgnl=Zy ,hE8!O%dͣ]0> ee d! M:渕dY IFΔ(ttq:S-8J'G5Pi)JFȻXY/֨JyZBWTa tGq K(aMdN0h仉&v*'8?֥x#*vsfy^Ab>aJ.W_O>< $E V4aZ&jQ:eQS]Sqp qnLL)酄E8:pkBӃ)=0vybvkE`ҍnu1sM' &jtxBեx#$qPq>FxD5x2Af3^ô\gbٔRJvJE)f+^}38z>+RyvY>cVq%o14rD|NtAIN+)P)a 0{'`-o(iu\7l[*Qmlk rn¥u\!i  Q;Ե _` 㾁]Қ?PDe%(unQƔ҉NVek32l̽ꛔ!N&hxAZy}l%pt:p}>u#0v)gB4Ut^6>'{p[{ʧ=W40Ң* Mƀz|/IlT}1ZsT+iPx*..m)ls}UWrgPiU"ug*6Zù2Pi7aKM҅6I)&uXRԣZαӀ+MW,/"V*.9FS*(a}5MVGNbT7r#QV||jC :6" Ů>@%:G9p^+{RiYG)KPm-$Lem a'Ou )Ic=hwO6.XRn9MJn#o: OtSd^T6[BIJQL@)aIfe+ŜvJ+IJVAB50u٬%*)10ԕ'CIP;Bhm LD8RD@ q)p:Č^y7] .":JϬJW?D3䵶g=<%I.!|aW.O,z^c =o:7.#ndݒq3eÑ:5-NMRL˩%OԞ2aq;:wŲURH[ 6̨blFrVCYXH7D%e:?>r*Rf bOyA2lz0P &ݻ5C>Jri>0a2zwnϱ_fԳ8=.t vE (9SX" Of'~sxΟR>eo_tTڃg()g&JdG'DLQsr'Q8V®VBeZI wb<>KAaYQ#L,niiRϖ%VyҊ(vEJ;(XUk/(rRn1O3)VjSҊKiGžMΧQ+BuA{2/MMFE&D%4R5 :$G`RayP(n7볓/*Tk͔ MΧ^4.ҭim[Moi&f'nf5 :f~1% t-FY,fZ9,]eHBƗ nb盕q穩u('(i1L}{?qIOyjN8}f/K9-JRe(mNG[̧–l|e.'^fc8IcO%SUPm~؀ZO i&uAfY8EV`P_~;4'4{C*ʾY ç*NN6cUAhy&\jEZ<>lCkZ}6Zcg^&Tvx#>t`'>rm>iQmY2}xB)<V44 VeDe7.IO(+*$\F >M2]У=0AKRZ_xJq9+5.ehpmQ%-*} b^ܭWK%9ֵJ'5bDJ--QrnBu_ihil6-}b-`#楥¥%kiߊyfS~} VrLKPu\de M%Y+.XV]S )4SKTbYoNSNKm,J:ajunrcqqz ̙yYFa5uvZW4lj7つ+9I80UogSV˂ :(J5g=z(a"х z*f{aa#Iuw7{Oc&5!ـ+6N|ُEz] oPړ0<暽>.,_ (V)ij z+/#%C?$# VRD+jy|&=m _dAET?fm3UɆҴNT^# d8Zf!鹊˓sNǖnI^q$F==S3*y/;Ƴ KV]78FVY'V39)8Qmҹ3) A)*fҥꅵ,GbFХzvTl5M FW{ooDT++rsg=[C23UIKOqi8[ ѝe!D(Po}ӧ6\Ay+PLk4YOVUEa,.u JeRzTŖE|Lτ,6˄94[I7 8|ٹXѦioW#N(Y{x>IOL!O*x }r\eV0Ĭ%2mK6,j= [n.xKd+=/:>ǚYf^JO):j=c1U#=&i.rL AWG|δB ^}§(u"T% =]pjۖY@ 'Il1miLe}+dwlk%0|s9!hc:0J1m~/{Å V쩤`ç-T: gOx< 4a<^G(|`}ͩm xxܩf\XCGF''(i#(.x!':i R<{J֡ /: q=&xb}%pCj5srTWj.&\O%1汼)ioM~ =k>h =,RKMrUΕa[j*Du'8($4xFgxK7τ%.O`0.d"$8'f 4(6>hƬfXF42ּ\Jܪ],hh:ʢ@T9Nw2m; ?Pmi6 2n{V|Ud=7*tdMGK^C^aF7JJ$ ͎ZY>K*ͶE|Uv%594A=_(%Sd[60h2侫oSڠ%z;>1Ra:M˜Oz K,L^Kּs­5Bvėnp0޿JX9ͽGxFVr$)io.{heX.r"HKm/ 4PJ<%*nŵx@!c|=OC*jIH'}mVIYe9GP&%,;Gcx⏁0mfY@:Q9m5ghQ˟D%IBv%2 tܸU+ms2GIS4Y"]#}P<_4#˧cIy! %Z IJ{d-v[+zKQL,zy >[|Z2{G)̛]=_=r9^, y ~GG)`l~|yLHzDnI=hy[ Bua$Bϓ:B|M<"/~ST$jH[ӊS\5'&҉IlM>y⪣GR-џq&e#Gb0?#sKIp3, )@R:aNvo٥g#l$WaުŊl{!WZmQ,<) ho*Jr&5O~'hZBŅκj"r=L+ɽ@ly_bn]ҥ%܀4Ó\(i&.:pMog 2-&FaoJ6$nnbB*NVNgt HJ'D.>T@ /-Ծb)GnW Q*\U?ib]B^X77ɬ(yjB1}Y"RYT岈wE\^<=V1+%+F}Oq; U|OJn(rc֜ &V.5%2oj٩V(RzI\´ڨNǜZLEi&Im )4H䜟y_l6 ! sQsU J)/$EJ6u,uˤqNϺm/@@؆\SwX^a5)Q:KHԩCqƗ`G$n^YRS|NrLd\eM-5єyI$Llt 1FAy8$P-~1 fI =RҥJIЧQnǮ-sL5^.`X bEQ̲o-N^%E(1W/th"&CbEz}xx:G44jR#a12+kϤ6$:#(eb9m/R|CPZZRq=4c>Z:xIW"]Ol+{EeXĴ UII8\miq*Tp}b<09 œDTK )*Chb#HZ9dsR`rn^\ OLQ>]E/bZX#|+"O_qVncd-ȭM+ܛ=jGU0*o~ 7#ʝ"%,0>B({ E̹b>g&@[Y7g 9z%pYK:򊑕Nu]uZ[m|sJ@0jR>seDsΜiX%0rv=ypʉ㑈Y eIE`xm;4f'~JTԳj$8b.Ӡ+1U:JBHӚc7UYSW]ilSn)$ز@DqdMϥVJl )W))׺!ך/T2] ԁa ʷ;#X*eڕd)ܠ%!H"7톞C.Z6fq)VƬt,^'i,_0x8A [Iό@/% Vs[0 ~OHDRfj%KeSJO/ےu-TzҰ'鸯23M:nvKAek "kz44eꡈۭKL:Au2aHԣڬd10u1ǃXyBm_L嚿= Rqd~8y1Y{t*Hڬ35E#)NMjE*Z$527CGus[φTg8Gi5 BpY]Jcd#κpځ=Х =j9$"'Sj=.ȥRA[i3nRTVq-)@e6;;8PgĿ9Y+>^Uu턕iErCô%s Z&`ӨXn}9pxLoX9,pG>l1UT_4ζI;(q5Fݿ^aC?wb\NlJ%pu,9vivPRjEhe {9qmSjF^zQ&&ZIR͖ɽjxnAbzn`* ~ּLVLR.ێ$0b)Az$ZHVK`zqyIy=ҵ?|<#;E*zrNQԴÖ H؃mIhAp(xj)@_xv `zi7 ?X.uiju2RAԬ8?xJE$)B 8S"~ԧS3 VG r!Ql$Uk*'Qp kWeql|9Il)m$t)׎s!$ؓ@7BzF,+L69’y!ﶰ* C0gm 66Q|1*n "1[h&mI_-5FMqLhl{)$`ylg#S=;OsCDE?DiG΍\bA儶ˠ6ѡv˸[^$(uu87r(-PopUAG3xR'<Qm(%ilTtMO~Vc]rN.\a.UOM)'Utpyr ڤ̨ŤhSrrt2p+$u/*8=;B/:p!ה2 Tm\wq7g;hTdSݠ&nn]N:*sΕ{?LѦe=+OJ!Tr|\}ئ;sl/$]'g|H Z.*$;X0U+y܇_PB,5 P$:e0Zɸy>B̜XSAɼęYAbKqG>-&3S\fo &q틆-Tp6,% V[gR5FeC({͚KAJΠ^&r0B^q U~P>K WZ%E:RsL%R x]LV=5hNOL%$#3EcfIՄI2vXtqXRPݟaIzBɈ;sqjݛeReq*0޸bҩy9ZeMq6:CufIJTl:BP]B˵Χ_bZ|L:OTZ'(g}Wg::>&%2S}=j NL,g21JeJK*}jnT{t/NJӝ\'Ri7IT~VQŝ%Ur',;hSnS֥m[@u pu?},h'dA;(sx]Z8mS'C}cZFITKV5N\L]oEw<2Ah{J!6t}V *_-3c9ӹ$EiU,aM J8{"RJ&el} U렴=oNr8J7:Cmr qH̄M+22mEJ Ƅ%% 1MA)Jͭa<}cT'P^NGXtOKGV]t-9VPn*\+)=<^1֬=^Xr+b #e@YGSSv!S/rq^0MfcPqSaIzÒ :Dm[>ϊ'|LN9?2[(h79J"c䚙SIrj1.]9vc>UY@ތtIPyؙvf`yCx`4:`5"0{*Ci'MBuI Bm{ #Ał-x-֥%Z'@G8iXe]Q8)J[1Jo<{}THM~Y.@=@_XQ]y^6GqVS 8E8C+^`o:ź .Y]+N#HZ Fd#x}NQE!%W(rF] 3 2Jw( g2R[|RjҊ)4,VqclDnB4QrK"zZ_[i)Dq-n5Evy8_NK4S?#%w%-5 ؁9OU9Ft7)EnLJ5DT*/O!an!'t$\jc­䓻u2{)O72l*%2ˈ]Ҝ: ֽ Ra{˒A-d"rlmoP]Oͥ1H*\)K)d(AXTkRmT!K0%ce)2 XBq QpoGӍZq CVU%BDG{+@W:ie-mxus+8͗ݣL-Ҥ̩P?d`dŕqo뮝{TOJﲩu2H$ipcOi񡷶d uv5?8TV ʫrt(I%;'ꢓ&8"G;xTivą$ )^]l!m@٭_3'Hk6B3nq[зdFVDKqEg;Ŋ%OXID&4EsEwV"醴n $؝8BRlBoJ j$z\𭮐{{a7x("4'M`M%AdduHQ<"L+#m\2/k v=hmfk π-ѨO9wm ٤И#(Ņst G6i鵭C:n"G>ˎRq%KK7+a|c]$N^:tAvWq5I~IbjlSIodEĝﻙgr35*zeeV }1/irq]!)5 uDoRRx%ԉjQrZeB`=&)8Am&\,t:/*s$9M530K0O]$xBCt5H(RTH(G0_8ǨG)u>CXb6^PSIo2J\ 0+K 1F{JcRQ:hbVWFФr qG3$*N1]?,j49U:&RNXoL[+,+esAM9'*TIyýwwyJjNW_\Hq-4lO8@*ZO[ 9PbXr<NȩϠ$kN+nreSyJt+/lRTtJЬ^d;ntH7EAw~rM~-EƝJ]{^ 8mPOyL۹`v:NTx;Um^#SZZ*BG&JNO Pl֫%#ô:"o8&(-VQlt&,SṃP$1i9~vZal<" I[މ&):\Pm;7'N^3Osvp 4;Gucp!;<%Z[^ 4K 'MЕ nA^Zv,K8O|6FS-EPu:Ak %[C r 0a߲m6͠fJm . LE4_ 7BDۥpm[VG1ZQ*eyRTTۉ_b׾KB4i!e9T_հӼqwƽ}"2j{| TRsb:kC$yEK t%m>tۈ Sq7>*yEΟ*&Pdm^#1 mk|8z3-xY*ͻ*Hm2IC-YHL_a-;&L2t&"3;䌻IM!Hu<\EJ5> >'$u2ݗi>:eah|X}~X@HSJW?ON+^w>%/yRaKzH :a5$*4NT2.wZpܴjU&ZuK.J<.Ey1Ys}=%KT}!i:haai:3=f "С'D][gW yԲZLC>p" iG6q! SfzX"X̶`n*)֚ե3s:ɑ9H9ljyMKׅvueegN6>].b[ %!%K|6=#hhʛ3Im̍Vfòֿ7Lqk,NeZraʞuר˟<4Vd+qZ#u>]ǻlgs~IL"(Rq1aɨפ%^CeC Tj8 *i9ә_o,bR 8f2Ig3uFo2O[-:e$X[IJ,2 {qTKii`DYq$jla,IHqlaL̇V+=jt:WTPqXaƩ{u)S* nd<ؒ'HtGfqU-܎Wk(+q559Ս\+%G/1"r:2W5y mo2ަVަO%mI!tk\,p/ EsIII)! $Ụ̄Y֌tV\b~.Iڌ*PQi+4n&{gؖ}$.YhJRA兹^u. 64LiUYͳ8]_H A ZW 6>4E5%yKVi` 'H(aY]]^5nf7(ٕJ9N.T#hOqڬ7rKs-!W'M8 /?q5Pmi?Qx:y+)c;9꫙VWIjՙ9ߪnljrH s'^\Fem*sUHLb.9G Z;dzTQw#UPTh%'l'1c Z}rI,bFa'Ea*&;U:5z{SSesS UEc9ҋE?(SjT129Hlګ~ёvИ4Uc3f&KOOr! 7C{Lrr_TZDG KaJUk"ru S+0W1jǠnGJUi-2)ISĮӓѭ_>xnwk  XY@^!#Ha|I|&7kI?:B6@<{A2tZ-OL&bl !YtZ䰕eX;c\79\H8WTZ Jh0EBe3.As \L)ZwA}([JH|A!5hxd0;e] NE( 8x@ Cu4VPc)g&et߄7u:AhBXq[oꆔ@ A2n!|)Eoe|FoBM̤L$ M)3_$$8:t:uZd'M/[|в 6c&wM(|j$/!WY~NQ)Y |'Ş6F 7 D2`5 .&=ko)IW+Plw Ź!Gԛ0 GGRG)(w1=>A/=!5yE[,yD10o4B~ 6%ˆCj D tGT<1%*Wo:t1DNL:LЕ-ED'. G%/N'~CW<m F.J~NisEikh) H B Agyt$2H,- c0 GyYy! y\IIT%mZG`@vYR0ĝJR1rsRC.Sf ;߉Ju"F$lq'33 ) iFT,ÔG҉V$0P G9`1;ITdJNׁ:lwZ? Bs`\L #!L"ߌ#gTGf Eԇh#W$0dk >@0 +$ C2o@FLstatik-0.1.1/fs/000077500000000000000000000000001314733720700134275ustar00rootroot00000000000000statik-0.1.1/fs/fs.go000066400000000000000000000072761314733720700144020ustar00rootroot00000000000000// Copyright 2014 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package fs contains an HTTP file system that works with zip contents. package fs import ( "archive/zip" "bytes" "errors" "fmt" "io/ioutil" "net/http" "os" "strings" ) var zipData string // file holds unzipped read-only file contents and file metadata. type file struct { os.FileInfo data []byte } type statikFS struct { files map[string]file } // Register registers zip contents data, later used to initialize // the statik file system. func Register(data string) { zipData = data } // New creates a new file system with the registered zip contents data. // It unzips all files and stores them in an in-memory map. func New() (http.FileSystem, error) { if zipData == "" { return nil, errors.New("statik/fs: no zip data registered") } zipReader, err := zip.NewReader(strings.NewReader(zipData), int64(len(zipData))) if err != nil { return nil, err } files := make(map[string]file) for _, zipFile := range zipReader.File { unzipped, err := unzip(zipFile) if err != nil { return nil, fmt.Errorf("statik/fs: error unzipping file %q: %s", zipFile.Name, err) } files["/"+zipFile.Name] = file{ FileInfo: zipFile.FileInfo(), data: unzipped, } } return &statikFS{files: files}, nil } func unzip(zf *zip.File) ([]byte, error) { rc, err := zf.Open() if err != nil { return nil, err } defer rc.Close() return ioutil.ReadAll(rc) } // Open returns a file matching the given file name, or os.ErrNotExists if // no file matching the given file name is found in the archive. // If a directory is requested, Open returns the file named "index.html" // in the requested directory, if that file exists. func (fs *statikFS) Open(name string) (http.File, error) { name = strings.Replace(name, "//", "/", -1) f, ok := fs.files[name] if ok { return newHTTPFile(f, false), nil } // The file doesn't match, but maybe it's a directory, // thus we should look for index.html indexName := strings.Replace(name+"/index.html", "//", "/", -1) f, ok = fs.files[indexName] if !ok { return nil, os.ErrNotExist } return newHTTPFile(f, true), nil } func newHTTPFile(file file, isDir bool) *httpFile { return &httpFile{ file: file, reader: bytes.NewReader(file.data), isDir: isDir, } } // httpFile represents an HTTP file and acts as a bridge // between file and http.File. type httpFile struct { file reader *bytes.Reader isDir bool } // Read reads bytes into p, returns the number of read bytes. func (f *httpFile) Read(p []byte) (n int, err error) { return f.reader.Read(p) } // Seek seeks to the offset. func (f *httpFile) Seek(offset int64, whence int) (ret int64, err error) { return f.reader.Seek(offset, whence) } // Stat stats the file. func (f *httpFile) Stat() (os.FileInfo, error) { return f, nil } // IsDir returns true if the file location represents a directory. func (f *httpFile) IsDir() bool { return f.isDir } // Readdir returns an empty slice of files, directory // listing is disabled. func (f *httpFile) Readdir(count int) ([]os.FileInfo, error) { // directory listing is disabled. return make([]os.FileInfo, 0), nil } func (f *httpFile) Close() error { return nil } statik-0.1.1/statik.go000066400000000000000000000126001314733720700146440ustar00rootroot00000000000000// Copyright 2014 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package contains a program that generates code to register // a directory and its contents as zip data for statik file system. package main import ( "archive/zip" "bytes" "flag" "fmt" "io" "io/ioutil" "os" "path" "path/filepath" "strings" "time" ) const ( namePackage = "statik" nameSourceFile = "statik.go" ) var ( flagSrc = flag.String("src", path.Join(".", "public"), "The path of the source directory.") flagDest = flag.String("dest", ".", "The destination path of the generated package.") flagNoMtime = flag.Bool("m", false, "Ignore modification times on files.") flagNoCompress = flag.Bool("Z", false, "Do not use compression to shrink the files.") flagForce = flag.Bool("f", false, "Overwrite destination file if it already exists.") ) // mtimeDate holds the arbitrary mtime that we assign to files when // flagNoMtime is set. var mtimeDate = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC) func main() { flag.Parse() file, err := generateSource(*flagSrc) if err != nil { exitWithError(err) } destDir := path.Join(*flagDest, namePackage) err = os.MkdirAll(destDir, 0755) if err != nil { exitWithError(err) } err = rename(file.Name(), path.Join(destDir, nameSourceFile)) if err != nil { exitWithError(err) } } // rename tries to os.Rename, but fall backs to copying from src // to dest and unlink the source if os.Rename fails. func rename(src, dest string) error { // Try to rename generated source. if err := os.Rename(src, dest); err == nil { return nil } // If the rename failed (might do so due to temporary file residing on a // different device), try to copy byte by byte. rc, err := os.Open(src) if err != nil { return err } defer func() { rc.Close() os.Remove(src) // ignore the error, source is in tmp. }() if _, err = os.Stat(dest); !os.IsNotExist(err) { if *flagForce { if err = os.Remove(dest); err != nil { return fmt.Errorf("file %q could not be deleted", dest) } } else { return fmt.Errorf("file %q already exists; use -f to overwrite", dest) } } wc, err := os.Create(dest) if err != nil { return err } defer wc.Close() if _, err = io.Copy(wc, rc); err != nil { // Delete remains of failed copy attempt. os.Remove(dest) } return err } // Walks on the source path and generates source code // that contains source directory's contents as zip contents. // Generates source registers generated zip contents data to // be read by the statik/fs HTTP file system. func generateSource(srcPath string) (file *os.File, err error) { var ( buffer bytes.Buffer zipWriter io.Writer ) zipWriter = &buffer f, err := ioutil.TempFile("", namePackage) if err != nil { return } zipWriter = io.MultiWriter(zipWriter, f) defer f.Close() w := zip.NewWriter(zipWriter) if err = filepath.Walk(srcPath, func(path string, fi os.FileInfo, err error) error { if err != nil { return err } // Ignore directories and hidden files. // No entry is needed for directories in a zip file. // Each file is represented with a path, no directory // entities are required to build the hierarchy. if fi.IsDir() || strings.HasPrefix(fi.Name(), ".") { return nil } relPath, err := filepath.Rel(srcPath, path) if err != nil { return err } b, err := ioutil.ReadFile(path) if err != nil { return err } fHeader, err := zip.FileInfoHeader(fi) if err != nil { return err } if *flagNoMtime { // Always use the same modification time so that // the output is deterministic with respect to the file contents. fHeader.SetModTime(mtimeDate) } fHeader.Name = filepath.ToSlash(relPath) if !*flagNoCompress { fHeader.Method = zip.Deflate } f, err := w.CreateHeader(fHeader) if err != nil { return err } _, err = f.Write(b) return err }); err != nil { return } if err = w.Close(); err != nil { return } // then embed it as a quoted string var qb bytes.Buffer fmt.Fprintf(&qb, `// Code generated by statik. DO NOT EDIT. package %s import ( "github.com/rakyll/statik/fs" ) func init() { data := "`, namePackage) FprintZipData(&qb, buffer.Bytes()) fmt.Fprint(&qb, `" fs.Register(data) } `) if err = ioutil.WriteFile(f.Name(), qb.Bytes(), 0644); err != nil { return } return f, nil } // FprintZipData converts zip binary contents to a string literal. func FprintZipData(dest *bytes.Buffer, zipData []byte) { for _, b := range zipData { if b == '\n' { dest.WriteString(`\n`) continue } if b == '\\' { dest.WriteString(`\\`) continue } if b == '"' { dest.WriteString(`\"`) continue } if (b >= 32 && b <= 126) || b == '\t' { dest.WriteByte(b) continue } fmt.Fprintf(dest, "\\x%02x", b) } } // Prints out the error message and exists with a non-success signal. func exitWithError(err error) { fmt.Println(err) os.Exit(1) }