From 6b32998322304d2634bfd997ad1a2cd9e62c2ebe Mon Sep 17 00:00:00 2001 From: Preston Holmes Date: Wed, 23 Apr 2014 10:36:50 -0700 Subject: [PATCH] initial commit --- Info.plist | 103 +++++++++++ LICENSE | 13 ++ README.md | 77 ++++++++ app.nw/IPythonConsole.png | Bin 0 -> 11604 bytes app.nw/app.icns | Bin 0 -> 92295 bytes app.nw/node_modules/sleep/.jshintignore | 1 + app.nw/node_modules/sleep/.jshintrc | 33 ++++ app.nw/node_modules/sleep/.npmignore | 4 + app.nw/node_modules/sleep/README.md | 25 +++ app.nw/node_modules/sleep/binding.gyp | 10 ++ app.nw/node_modules/sleep/build-util/tools.js | 88 +++++++++ app.nw/node_modules/sleep/build.js | 113 ++++++++++++ app.nw/node_modules/sleep/lib/binary_name.js | 58 ++++++ app.nw/node_modules/sleep/lib/index.js | 35 ++++ .../sleep/node_modules/mkdirp/.npmignore | 2 + .../sleep/node_modules/mkdirp/.travis.yml | 5 + .../sleep/node_modules/mkdirp/LICENSE | 21 +++ .../sleep/node_modules/mkdirp/examples/pow.js | 6 + .../sleep/node_modules/mkdirp/index.js | 82 +++++++++ .../sleep/node_modules/mkdirp/package.json | 38 ++++ .../sleep/node_modules/mkdirp/readme.markdown | 63 +++++++ .../sleep/node_modules/mkdirp/test/chmod.js | 38 ++++ .../sleep/node_modules/mkdirp/test/clobber.js | 37 ++++ .../sleep/node_modules/mkdirp/test/mkdirp.js | 28 +++ .../sleep/node_modules/mkdirp/test/perm.js | 32 ++++ .../node_modules/mkdirp/test/perm_sync.js | 39 ++++ .../sleep/node_modules/mkdirp/test/race.js | 41 +++++ .../sleep/node_modules/mkdirp/test/rel.js | 32 ++++ .../sleep/node_modules/mkdirp/test/return.js | 25 +++ .../node_modules/mkdirp/test/return_sync.js | 24 +++ .../sleep/node_modules/mkdirp/test/root.js | 18 ++ .../sleep/node_modules/mkdirp/test/sync.js | 32 ++++ .../sleep/node_modules/mkdirp/test/umask.js | 28 +++ .../node_modules/mkdirp/test/umask_sync.js | 32 ++++ app.nw/node_modules/sleep/package.json | 46 +++++ app.nw/node_modules/sleep/sleep.cc | 70 ++++++++ app.nw/node_modules/sleep/test.js | 12 ++ app.nw/package.json | 14 ++ app.nw/start.html | 167 ++++++++++++++++++ app.nw/test.js | 63 +++++++ py2app/nb.py | 17 ++ py2app/setup.py | 19 ++ 42 files changed, 1591 insertions(+) create mode 100644 Info.plist create mode 100644 LICENSE create mode 100644 README.md create mode 100644 app.nw/IPythonConsole.png create mode 100644 app.nw/app.icns create mode 100644 app.nw/node_modules/sleep/.jshintignore create mode 100644 app.nw/node_modules/sleep/.jshintrc create mode 100644 app.nw/node_modules/sleep/.npmignore create mode 100644 app.nw/node_modules/sleep/README.md create mode 100644 app.nw/node_modules/sleep/binding.gyp create mode 100644 app.nw/node_modules/sleep/build-util/tools.js create mode 100644 app.nw/node_modules/sleep/build.js create mode 100644 app.nw/node_modules/sleep/lib/binary_name.js create mode 100644 app.nw/node_modules/sleep/lib/index.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/.npmignore create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/.travis.yml create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/LICENSE create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/examples/pow.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/index.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/package.json create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/readme.markdown create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/chmod.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/clobber.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/mkdirp.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/perm.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/perm_sync.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/race.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/rel.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/return.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/return_sync.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/root.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/sync.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/umask.js create mode 100644 app.nw/node_modules/sleep/node_modules/mkdirp/test/umask_sync.js create mode 100644 app.nw/node_modules/sleep/package.json create mode 100644 app.nw/node_modules/sleep/sleep.cc create mode 100644 app.nw/node_modules/sleep/test.js create mode 100755 app.nw/package.json create mode 100755 app.nw/start.html create mode 100644 app.nw/test.js create mode 100644 py2app/nb.py create mode 100644 py2app/setup.py diff --git a/Info.plist b/Info.plist new file mode 100644 index 0000000..7616293 --- /dev/null +++ b/Info.plist @@ -0,0 +1,103 @@ + + + + + BuildMachineOSBuild + 12C3006 + CFBundleDevelopmentRegion + en + CFBundleDisplayName + IPyApp + CFBundleDocumentTypes + + + CFBundleTypeIconFile + nw.icns + CFBundleTypeName + node-webkit App + CFBundleTypeRole + Viewer + LSHandlerRank + Owner + LSItemContentTypes + + com.intel.nw.app + + + + CFBundleTypeName + Folder + CFBundleTypeOSTypes + + fold + + CFBundleTypeRole + Viewer + LSHandlerRank + None + + + CFBundleExecutable + node-webkit + CFBundleIconFile + app.nw/app.icns + CFBundleIdentifier + org.ipython.ipyapp + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + IPyApp + CFBundlePackageType + APPL + CFBundleShortVersionString + 32.0.1700.107 + CFBundleVersion + 1700.107 + DTSDKBuild + 11E52 + DTSDKName + macosx10.7 + DTXcode + 0452 + DTXcodeBuild + 4G2008a + LSFileQuarantineEnabled + + LSMinimumSystemVersion + 10.6.0 + NSPrincipalClass + NSApplication + NSSupportsAutomaticGraphicsSwitching + + SCMRevision + 239963 + UTExportedTypeDeclarations + + + UTTypeConformsTo + + com.pkware.zip-archive + + UTTypeDescription + node-webkit App + UTTypeIconFile + nw.icns + UTTypeIdentifier + com.intel.nw.app + UTTypeReferenceURL + https://github.com/rogerwang/node-webkit/wiki/How-to-package-and-distribute-your-apps + UTTypeTagSpecification + + com.apple.ostype + node-webkit + public.filename-extension + + nw + + public.mime-type + application/x-node-webkit-app + + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5c420da --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2014 Preston Holmes + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..94d5873 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# IPyApp + + +This package currently serves as a proof of concept for bundling IPython notebook into a standalone executable application. + +There are basically two components to bundling this. The first is to take Python and IPython and any other python libraries, and bundle them into a platform executable. + +Then wrap this executable in a [node-webkit](https://github.com/rogerwang/node-webkit) app to provide the web UI to the notebook server. + +Current this POC is limited to Mac OS using [Py2App](https://pypi.python.org/pypi/py2app/). + +However node-webkit is cross platform, so as long as an executable can be created (ie py2exe), then this general approach should be cross platform. + +## How to create the bundle + +First, create a virtualenv and install IPython, py2app and any packages you want included. + +Then cd into the py2app directory and build the executable + + rm -r build dist; python setup.py py2app --packages IPython + +Include any additional --packages + +This will create a nb.app executable in the dist folder. Copy this into the app.nw folder. + +Next download the [node-webkit binary](https://github.com/rogerwang/node-webkit#downloads) + +Right click on the node-webkit.app binary that you downloaded and choose "Show Package Contents" + +Copy the provided Info.plist file into the Contents folder of the package, and copy the app.nw folder into the Contents/Resources folder of the package. + +You should now be able to launch the app by double clicking. + +The layout of the app should look something like: + + + + IPyApp.app + └── Contents + ├── Frameworks + │   ├── crash_inspector + │   ├── node-webkit\ Framework.framework + │   │   ├── Libraries + │   │   ├── Resources + │   │   ├── node-webkit\ Framework + │   │   ├── node-webkit\ Framework.TOC + │   │   └── node-webkit\ Framework.tmp + │   ├── node-webkit\ Helper\ EH.app + │   │   └── Contents + │   ├── node-webkit\ Helper\ NP.app + │   │   └── Contents + │   └── node-webkit\ Helper.app + │   └── Contents + ├── Info.plist + ├── MacOS + │   └── node-webkit + ├── PkgInfo + └── Resources + ├── app.nw + │   ├── app.icns + │   ├── IPythonConsole.png + │   ├── nb.app + │   ├── node_modules + │   ├── package.json + │   ├── start.html + │   └── test.js + └── nw.icns + + + +### Similar projects: + +* https://github.com/liyanage/ipython-notebook - A similar project that uses node-webkit, but does not bundle the python environment, but provides an alternative to opening in the browser. +* https://github.com/mangecoeur/ipython-desktop - A project to embed IPython notebook into a native Mac App using OS X only web ui views + + + diff --git a/app.nw/IPythonConsole.png b/app.nw/IPythonConsole.png new file mode 100644 index 0000000000000000000000000000000000000000..06ea47b7feae077796a5bad03b28238ae182fab5 GIT binary patch literal 11604 zcmeIYRal!(^ezg;ij~sf+Cp&+?rtqkaCdiiD;}h{ySKPIMS^=M?oyoME<64G_dfgT z+?~sFk(Dp=e6wa{y=#`uL@FsrW1E*)p1x|00PK9wz= zTVraZ8cne^swW`ENFlv}4E;j)|6~|0_X`z~w+|68R5NDcV`Lu4jv&CM^#^kSz?S$) z&e(D7o8zwp(lpO^SRsi)@E8f~?>pewv@0ub)vK@VJsQ7us%oftXlVSdeDJ@r(sp+H z*>>8w{(Knl_jx_)x%-h60jGEK1Dq;(o{+qJ3@#IR$?;QC6VTedjvyIdynu@5eglmSeW- zPmwI6?yqk0*_GS<$?0N!(*XzLg^*pFW;1$AQq!>Q{Rcz&#HMb#Ep`oDO_MTeoS>e!WTZ6@ z{M7pxZK4qZ6}4X!by`#ErVttC$)Y#%eGtQLATboB4o8I(;a?#w%QsV{&`|3Fx!=#>^puynQ_;VWuGS+J{u7QJyu6*C*{)kKTKtqbG`6 z#`#apokp@{3zknXaK6?I)C?SQ0Q+fKTQTPd%&Zkkt#JRZfNeql>dO_qc^nj zPwK2y|F61%zCaF9%6u4-8E*pd`iL^;|BuvGl@Nl3AWme~74sA2241^<+J+;2qnP}R z*(5rtGumqihSV8c6wVyM96=XBMxNHme>_;*U`z^63QtlS^RT_yoRETH(gt!Oo42o* zo;PUy0OQ!Ln+iDr$cljw->n#zxxIjq()V zHSH{QS~!ePUjBbZ@e9AOU~26K7>ojnoaigijt(N#G=b~0n}-=REw52Ru8A$AR$#4{55rhAO6)`xpjTKDrI!*@LG zXl#N1ExTkT)Z9pfaevaVaI7?gpr`OTM62@uU3NJ{7_;%FIBbEmudZZL^IL4$?8xr_ z8}+0aMdH?-nBOqD#W~CAK+zk?%lMi7Kv4@hix`;RY;3on=J_V-bBLNInkF1b3=hVd zCOp&)emD)03`%sQpTO_1`~x2p@PAmfl^FK$bLogmziz+!>xOm@6FwLC-m-L+K9lRU zZtZlpJo9_|t{z`_{{8mt3B7vW<8Fv%2a-=I-6_=Vv?MeLNBC*mG2Zg0NT}7hmd(6o zevK~~zE_n^jfVOX$77*;`*Vd`SWAaRAY+>QHL^c+cnf4Nq3kiB!N<)0O(9hhHcN5*b(>ia98G8FRR7hZ(`2 z6c+~Il!Cu0$Xw?7Lys;2dj8wvubw8ae>o$})5?iMIKw#Aiy#r>n-{b_Mh*)#FJc#l zY3;WiZ4Q4KUMKj?K%sPbFvoBP38bicnZexw@^QV?TjWr-MK@u=%uXD&BEbbYPibix zPx$KBYWwToZhgO9+!ms`Fk+c2T0CC6okH49A0(Bir!$1xD}h&VefJdVZ;saQp9Cda z{eW=A3>S*IcRg`rJ_|<8h5yOJtPfUJboBaa(MN@U>i>dI%-s6+M`Q`y1~@2(=NMDi z`#Ar!+5iBSoW5zq_9_Y}D1K9mS8;WQ@Zh|cyYBs}w~mVJt0ZrDN>-c)WwupV4tkL& z3C>&h86dRa$;^;bU-R?xE4x}ci(#72_8K5uZ@X`|RkJ%-{rJajnEuV&2H|T6I&@3; zl^pB)p7^WVucMsJfNfW<$`jquZvC8)fKGS2(vNd`dV1b|oi9P~&7+WR|H8lWFQKC+ zMEm4v{CVrU&V{Yklj#-}FZaTN_cZGZOC2?s8se-gn)1dGWRh{vCftks^0;H3b5)@= z{HsUf>HST`@FAOOi!hJz9d7t;jVnNeN-hu0TsCU0f|*atcI-0PWpUZ#_ zEH}?g1EVCri^^&I=9Dch&W^$3N|j93r(V(+sbF|=mX-X)kG$sM^HdP8J)hG~mLu+t zgbNz;T&Q|5co%Zf;?k-hkLR(0N2gL038f%XMQuDkR%odm!x3-kRcb6y#I*Y+=k*Cg!xK37WN}kt;e=2G;Mi>cL0fxyIVGoT3q{H#K5zZ@ zVCp#+a4=!wXz#g`WxB-pcm`*Obxb?dN3i?9K<=PH-B$&cP?& zv{TM4?0s43E|j^Z2f30ZSpi1?ZxMs@b^bo&{;=H?tvFw5%*Kl(8sz{s0Ksk{6_9F7 z#%67oSVLOl}A2$wZUB7L#wBO{&sE zDQEd`bD9#dveBgcnHgLTYdbmVstkj`K+cjk#MV?7X=S790x!3dLeFvUe8kV^JfS5y zIr^ytq0uzB{ajkN?`kNH0y8 zu078cygXj@@GUK3g*531u!F)z)^B<)g@ye01yzp|e|%-tgUq~MjvIiX`)TU!L)V+V74pHT$K}qnpYPjcZM4kZrSP$0}Eq|v+r^31s`Q6)b`@>3s73#J?}02HBc!VI)hBf z$u7|1l-G_VwOtJHZZ4%1k8=69k4!V3Q}2yjlF(G~K3oV(=tfD&v$~_enS~MWpGKtW zdw*+qk1n0laBx#zj(T8q@k9_k(nWyWPmzj(EhYIwOEt~-%ktLG?hfU{h@H|G=%mM? zPDy50hf}03eODY7x!?2ndgd5WbH$>FZ*A|b+Hc+zJ@4mVm%;+OS1cc;jBv*#B4$V= z53ld5yHAP2SDF15h88scI@}z%CG1?Cc3!G4Ci>n5JP-N0m3xhc1;-k++4nuNJb4;l zY1%xpMaF(-k}gJR5y;yQ44&TuC5&ueT!v!mTg^+>i5)w)=XzgA2YB9& zn@9_B$b&33>nPR@vqL!b8!nE^w<%}h(fYyi#p$>i%=te=;!`3G1YZ-5fv^}hn#z)! zPBLFC$I`w-v1sD$?X6oSF$Wz$Vk(&qsW`Afb8@fvEOzWBFAff}U)Ws%yax+Mci(nB zv8D6>ZCU;67TTxH0x+2Ax>G^Y?(iFYccH6g<-(&Q2jZ{|D&Z-H&{TY$^v~6?VH)sj zkz|hhK-}mI8HV`XZEWPxRVl|qI`@*-N64V7tMWOe1L2&^ASyArsJL}1aGEj2Ahi`5 zuG~p)v1CVe+k|LNF}GeQi&R=~-kG*;<)Oa-j$Y=P#tyfX6Bno5$*DTGTz-hWhJBLY zpWz}pg)Gxi?4@%$>V(V(H+sYFqzi}# zw&o3PKAZ&&iQm*@^LwzBpTK7_{>D++%2W`T7$0|ZzJJ;QZr(&IOcn{32HE)CnN5G7G}v5pxcK?Y+$1iV3W`ef z*xo83r?05Hs^`4~%`yf%@1x5nF6)2KT`AdpOLjnzB*$=ia3KG-w!Zl5m-AhgI7>#U z3I?w`3-NyCi@5XjUiYGyfvuy^{H0C;fZJpe!W4(g(tBZ3vQU%{{j#OS1->;8dxrs;-H@Kv>aJ`OTD>v%GG@LEmzm;s zx)UjYmRHQkgRx6$hIX-ISX0;>=jZ38b53Fu0Lkw0%1?Te-L8|_&0opu8y^P@PFHx@ z)z->@PW@5lO16q)d1Z!+hu-1KFq2D2D3yb!k2n#X@&; zYcj0Z)G0ZcV-vptA$0Fcl+qn^J>;kV`calc+^*em$`h`qb~V4ze8^KWjCw>tzS9ga z)7u`}xk_4Q-@cAVi8p*PdLwvuoUI{f@-0#cksZI}2=SS*XJ|p+cP6-UTd1n zzXT>8d5k4@hb(%^SIhUxcWvJM-R^jx4J=ZjuVf5V8k#b388CT!WcjB?A<2r;{>M$n` zOVk&!X2rn3V2k)s%IKRFzd?_vm-nAG7G^u9qKox*-mX>adme0dcWC^#UyXf>=4wTz zR%BEHWQComv^!k(>YvaLewC#g{yg$MwYt^uF{yv?1RIW4 z&}e?M;2NJ5>Uj#g#!rx*cEEoVE02y>AcN#>u;|gOd+HAJ2bQ)i)FsYv=HrKIqkN|7 zQ}JX;HbjUf6=mR?LQ8h1TMXPN)P zoV*m^kHLf!DN(3Q(KW4^^rYFpCvbgfQQVl8PTT`V7O)=P!ko8PcNB;6`7s2vx`;-5A{wR1Z>)@}MpWw8p! zV>U=NB*BrCDVR#%>$VYak{jJCOK@H80ivu)Ye6=AD_Ww9dvCn>J5EX*PJO*$u5avf zsp45lOXapi+XXy!^AXmBf=@>w2$~zGNJ2<-Z|myoX`Jvhu#Htl+b__rzry4b9YyIm zQc_o(0IxR3W$7{=`ef0|w$rdXi3>m6zkodtF++1NYobmf-QQQGJ!3H2pea?y}nMsJ8MZKmT zdG}vi=hBU?IC=wnSI}lP12Z+LAyzy|n#?cSVeCfA!o`M|KJ|^w3Z;#P8etEJtx{7n zvv9Y;SO{G)3{Q5lJdkCMM=oeWTyH{qesQg7|Cq(~1FrfsQYmzPo<@QuCEGXS21(uo zZ}8cnvvB-vPJ$IgjP2valmZx7&yo9LB+~bAqqV zLgMD%<_v^ny;{dGIsdRDeA2I2XA+V+!%%qr^=o{&3017a__~cEg&&ZOIcDDP%QV!3 zB}|QVz-u8Hx1rZ~&bDY0Vk*LC%7B+Cm}Mar8flDEGaw@Q36G?LQ(bFA zTGtRftbLPk!tb8tvv&VvsOMs{90e^7;US9ylv4%syZR)=i%Gu~D#!RAaK1^N#0L;{lWptX+T$I0Dzm{SzT~uh z#_s3c(n1rMtCXfLEm_G4T)HP2qZyn*!2t%-w0}1hB2<#k7J}{S{)lZ|XPrOy^CV_p z*m13ZGoUj>&dw$huH9Qiw<63TEQVC9_wYJ(gRRxzZIko3IhExT9 z12P=K{A}l=eqt;=4o7h5XTqr)(nz;ST*jaCWQCX8mtKgeg{(B8GXzNgTI9*>JUpJ4 zO*#{Te|_~MhV71f0qP4xI&q}APp+=fDMKu&yi%qstdMFS(>P_JV49zh%i%!lleQCJ z#(}S7Nkg%UWri~NAW_R&+nBAasq5E}h)Rq{yM%x@>4G?(3@2Lma$g}auX<_j+PjwJ zdaenvOzQWT4k^bajeB<;Ux{1vesTtvnrfdb7{w`LCc^K!X7P@Uz6H>4b-Z`M*nJeq z9JVq>R3t|2avx2R1TROBDy+86&8qR^16Xu-E$2?injD!XzUvvSk2FX*>{RECyd`t$ zhnd#D3|-wgS#O@1%Vbs09L?*KcTg?=e%iscM_zY;hl7KG0Xa)oxtLrkM%4Wad;OKOzbtvE6;PdE)RoS>gX`Ou zwSAvNfm;Bf0@Pp)Nn>tl@sN-7ucqvcW>y6KsfEMHl3#+oA{jGwVvZ(-rMX1nRWJqTmLeCop16S|NFMC4QWB$qeYG&xWk2~mlQ`4l?s0o{HDK0{R0?eb@`Rr2KMf{qx(b?8Ry7Re9^gxZ``6x zrUl(0$^ZUt7Kn6)^li{WH#a7RoRp9>JA>Mt$NW%`1&wPU_+kKhIcCb?Oiy$J^Nee+ zH|=cN9bN!0YUc_8k!dJ2ami$sfWf0K$-_U^)4I1d*%`qIQ4uEM#?pIqxzA|}`UM@d zfYvZ3cUf5r%=PP|)fsk*JJ!&_zgsj!45&)Sa>%rz+KruSegAr+&E6_MG|LbDkV zqSz$r5NGI7sZPjr*92n4WYu`!)fn$|-Mxk8Y@mPXG zu^V=4Noa(yBycCy^Yi=?)!ZF{MP1>?t^@4tF$GQqo$qhD2t>eCT-8|)t2mstLOmT7 zoUx(7__-b_(eH0>E}&5{tjSEWU?`X-$Hl~?k^spWk$8mY+XoXIuVy6^oXYNo zlc~DC`TfAi|FR45;`Px}o^8T;sg~{;o6nc zHfle$$R?joFiM@azT{WfzYHrdRfYo(iDEQNb-Qx=>&H^1Lv{FBXz0gwRkPYcNykg| z2+n;5usRBKV~<_33^`Bi!QU|= zXd{5lvl%)l!^=~iUBkA!v^8xhfR>8IaTgkFMFWH(M>*|IYfE8HqO-H%w2>+ZLC-ft z=+A-0y3E#ykDRg6OzQz#o=l-tKn*>$`)(~NXiXEW;YXqjyV-z&yt6kYGD z#hRNl69SBJ%s%79wmkbge2h4@OnTUQ%G6LH$$rnn#ZmWq;$h|jS8U~E92s7l03Ugk z%X#mVm;%_^nyUrCZA`6+svR+%VJ)+O8W- znTk-XTHKI`$4(br?tI?H@PhR7j~i&h?!4UmE6)|KJO+*=aeB48cye)|UGMmY|D~=b z9?u8}&(8?a%JUvOw~*G6(d6nO^U`pzXKKI|YoadA8-t3n%MBB3`&{z*e(kSgPEjkk z<8zu6I+=krq2a)JL0NBog{RyRB~znG36A|*+z)+`q2Gdv@H7@U=8fAboIVp}-*{q! zYnqtwJO<6v^eQyL_haV+u!zt+#$$$7Nq^es(Cn(8|8$ow+%eHzR#EC}T^N?PH;I6m&#f+jmsmvMWE1h)JQ91LrtZJEFFA0e2<_9Q}~(9nR_XepWq6Gc&ty7dn_O55@#W zN>M~$@3%zBUe8E-Be6@@*Vn~21eJDqyFL&XXw8?{&J^ONA0=(&jr~}_WV}ldCAF?S zY?er0EJIf1SMv4tBd$f0oR#<`lZKJgqPih}2^~ST z5>59?y@9gqphWmDt3zp2^3{aC=leUZ(bsHnNegwwOn7#7`jK@0u(k~?2jtJRfqbJT zf(^-+XcKiH91ecr`}Ch*{W|WNGVN83qskY0`zSt=BLyz;dB6b ztQt}<*V1X{ap#>Z~lHK^v<{Twb>++?8HE(Pgsffd&&kFpda z_73#E9j}!hclh>kw;R&rlcZudNWQ-w!TByU_l17)uyj@*B zYL3rodt88Wy&;f35Y+^y z?G+)@k)~Kfa$FOt6W4U#T$cZm8Ziqcmsmd9pLc!yDjuC^?n7XDPuTBN{GtQ zanf-Cbzw)V^kt-p?RBj0C_{=H<9No~c%hAW9>aqVi;(exD=Z9wi~T}5HVgSiKna01 zMqsUNEnk?1ROw!9q-SZ`o7+yBCJpy9alF)JzY{l|yLpL-a+x?(CgfjVCt7Ul7%r+G z}mt`UbYVXpEClT_)XTLgJ>Y0_%=*yTe*jjN$)jT`HpZ^<8mx0v@4E`IQO|9%wyLimZp}aXa4||<>SAYMF&EF=?334>D{y;@b#;Ax z&Q7I5pEbs5WaHTT4kQYZOf}Hk_j$PszwJ0Bgc=a(&4~>5^(+qOQ>n zbuygcEgT%5B~XNd}W6)6#=%y zwDDFbPz(0bRcPpY*wh#8Xj#}@T9`fm4}l$$!@>PWU{(eP_mAX3U=RP1f0t3={t*~_ z|3gH;@NjVd5p4|E&_DA3v-I#Yq^z4sZWHxN*^*j4FR}ODH72nn zF?NZ)gN6I=I|B;FeDAl`|E_;pMvzL>N~KDrkYi;xR@TJn^(viS?k{ts5|uzG)(CkTg+eZq%H)!` zrp@Xp8mEdCQn!4fR3g_FTxizd@YrKvtwEElR0g%#*ZOMsK^S z`#KIs-lc<%$rLr2k5Ag3=?FF;!-s_^!o&?`BZ)qQ5~V^qwM9fRJnz2xsxc7^JeNO& zN@Ye7V@XteL?oU>h$h1yL?WJqCy_}cBK%JB5`zgO0>MMXk%-uz1R`M;G0bE%7{Cgz z4zJZ})TTInT%1m;_vk2C(QLDr<4k6)POH;t-I|F;r9x?xON=^$UaJMuZLL~2(lu|X z)X6n^y;2cpp7Kjt>XG#;B&{53b^ZDxS;{;@*U8ALrp*(L>INwWW%>$!r=R+)SH|o6 zba7eL@|KIJjdtcHN4E<9egrjzq-?qXX`F*F*eST49Z3$QJoi9T%Xq4o;W7;4>Wx$$ zi_a1;s5AzP$!9aTOcsm5X0SPIHvGb3Gd-+eCY#B0vx1oH#Vn6A*kQNZJXV6mVm3SN zc89}ewcFfQw`HQ)Ri{pZBR;`uGh3`yv&rI!GniZkoy+F3TP$|FF|mDzmbUbEM!VK% zv*~q?_-Pm0w?4M%C(XddMq|hJGJVs9v_4aDKcx?C>@sxdS=ZQkwY=xr!5hr&&4ar) zXz4VxTf%F(yPzTO8;X0hq?x0q(Kvo zSRqyl`Fx>Rq!0^bBC%K~5lW;Iw>U&7mWbf*V39;5@`!^aVzFd_xO!f{cvbu7JzD$c zU1jZ`Pe1?vdij6qf3;ux)NYkW8Kh8n1}OQld#q7#rAEDA@X7SUp&=}MJC;SVk{8HNW~f?+4uuRW0?m5toJeMgo~ zs*=mZ@S$7=V-L;6;%-wfl}+!b;;b#-avHs$Q7KI}jlwOPs4`nL5SNr1WX@4UWQy6o z2H_;4L+RF(I(nf>Ar+bHIanOJ!X;dLUTibO?%YkSOZ#&^CBexPTG+8vb&$v!#O5e1 zq~&KQI%DjPowRz?YbC*P7CJJwEz*4!Vz3~VM5T?o>MX-xh}pdnp*BJrBSK3o(q%5P zU}6VEZwQMaD{Zl>&e9A9)=!lOe?#Ynl3DTiDBgP7T4AtMA5I}C?XfG*GU8;&vPV-E zw+N*~vRz>`BsV8FgvirIknu_@b@kauYAmvG142NeNs%l|I2Eb?Fg2LOR)ojK$m3&| zoP$Y*TAt6X8krWUI4<-@`gd8Fck0<32y(B1-;1`615)Tt`CZo|~aL0M{**cFlNTYG9u}fY< zP+ZMxh{+Ars;+sp;TnxvZK~Du!=)NcL;cmvZc|Wz1OXDSHU_Sm3_87Dt2Y?*SQWjW zJQ{vA+Uq!-3AQ+c+2M59^llwatI>LN9IaZdg^w)?mO#i58x0B$lfl!+>GTF8EFf$Q zN2^hcKD}wfseH9&%-)^5a?R>EjY6XK=t49SiAv*EaeJ3sE}JGCS<`;oYKMCxi(mof{tW0nm8auYSe3V9lr0$m2tFn6&o(75^U_< zyE%=xe=dq`(T}Bwm+<*ETtd$waT>9&&4@_pC&Dl6f@CZ}(t061 zhUyZyYtHfQcGliaA>0;dT8J%!9o}mJvba0atTREv)lH1&tU1TC+l6c2AHIani)I=J zQ<;j5f^}+q{dOciLl@8f>72l(i(2)lWNBL>FWNYOEG85dIyj#zq*z!M=`wjjb7HixQCBS?{!%R^)YLlQ+Spp3?5a492n(>6p#W3lP-Hq8}d zFV`cB5?Z;aY&tcrLA)!)!eqq7(KxUevN<9pGs#HgF=a9ylg;A95~HJu(JVHV%Fbjl z8B`WAmd9k#Xt10zSzG~+$LF$GT&|B5$>y>ITn04Zcv%S3!wA8uFtb<@Ocnz!!|$0a zFFTmUVzW`!IhN1qc6jVTHk;4tv3Si{&L9Vr-L}k6i(ZQdKCMyNW6rKw*<%iJI=wCr zR6+dhy%x8b?6O;Ju!1|Cutb|-k@ncU)?iq^;WLsmF{N&DN|M8wP`6&)L}-Jvm@FPE z&H{7ZOihRrDpew_%W0H}MRL2tW_Kmny;im>9@c+L+_5KHsBpKzl6zTeN(xfES#`njrpz}Gr2D8|bxXsG-7D~5q(JG-WMY8Uk zJkc7v_Th}>9qCF&gHo!NRy?_Y%W5++R>8H^mu@`AQ7R*LY(S{dayhGBK2;Oj=0O`C ztHrm`RZ9XWX&v%aan3d;ga#hr}t)VK8 zSk6uuP1XgsUrC4~HS9?>YFXo-yeNM@Q$XIbElMvCOL=zBh=d=mG-B$yP3Xvy@_F{A zb?c_ai-dMNUn+8o*;0c`+R(v}i>+3rNFtGP>1;NGBbM-Z60evg;&ViFu3RMM@4$_F(um%UJzv$^2UNv2xA&HOpB2EXjge z^|5lz`Zdc~eV=4ut@=I*qN&}Y_7$v6Ce*3jDpLZx;o8kUxrDXzVzm}RcRmi6SK|Jp z-N!4{L*{`xwOe^4o=;j;UkOqw-KtzrH!#|6iC0ssMl|_gW0(>aAh}YN{Xu&-z#!_W zsvNj)%vMIIG_Xll$dsxq|Lnp>!wu9pH6%<-h(1S+Gn!0U#wdeU0$B}JoIAs|M<%A_ip{NZAvF4L#@TyVsjW{ ziSoB)PeaSm%1LP0TeJb!pnztN)6;wBP_5Ss%moMH_zJFg? z4r^rjy9%@k&)+sgcLRM>nf0DfS^4hu+e-A0raXY~Dm@Ax+~?-Yb7VQvOyG|6cRR20 z6?hAgiSH}kq3GL+%JOzR9R}c5_~1W30Nk->NfD5Ut~MB44chb_ zJMnk){d;uRn33I@C7WfuY;_oB0*b!(zC|kCXw=&`DD>))OQKfzkwD;ldA1CZW{ZO) zemIYYrdG*Bd>Rk81cmB75MC@_Bvom%)f~Wji#|-S!p6{Er^U#v6@Z1lMz^x`GU!-{ zT$NC#jyEx+PLf)x$OW_zNbMyhc1iI?tfc^UE;)b}CY6hAY0X-? zTZFf4-X@8rl7O&Yun0)hYL!x=qpikB`cmS=Dy2%TsU|6tX}nsp-e{0;wgAIxbV;m1 z3LK$wb(5w|n|WGIxrrepQe+hT9i-J}{#(8(v&1U3PeoMA4UART=#>&p617{&P-s9rHCH3U zGS^D5M!==Vkck909!CJB$OzFxiX@UFF}83rq=h31L=GE1A_mBmwZ|$#k4@&Xk7P43 zvPA(hdcZcGPN9$rIrP|AA|VnFP##hklkeWkMQBkZ4^c>wUAs2DzgkPayN2Z;p9Au$Ob9b$Tq zmdipR)l-{Im)5jtD{=Ve*}|)JbgR88Hqdc?Mj^xwqgZ505t~M$Gy%S_Xd>97BT#R? zM;jusQIJcDq#>hGbdSIAFS^v0{~L5Z6+^AKf>ypk+mXZ+3IXO@G)5Lm0ej*|QB-6h zicUpnk-!!ei|j$s(f&d$wn%YW#^&#{~7^{z59+(?2STj&`8pwyytwvEdRx3c)qIsg<-N3h_FyHpV;}vX9))JB% z5KT4GAYa4j!5DMn3{qf9dZ(q%c34mPw2ukVuy?A*qm?ZGoca!YKa8L5{Sg zHi`EW1z``GGPPul=2N5C!1ES;JfMH~j_tb+$=m)2Ta3%mtFiDrDzgTSmq^7FoPsGx z52YieD4K`q=k~`CYvV>PAjX>_`qFc6jR-oJbI_U)TDa2Hllfj)@GAbd4!@DV8l zGX5ea6%$FSL@z^-@IwDdQKppo_Wz>rsYxnGw92@&zcCWP_q@fwsd$4{qFcBjF;OH) zE@MvA3UgW*4NRtd6fH&ghz~_e0#ngXQoo+fPvX;(J{boOaHup|cn(3tQ~WeJX!zqb z4G=uwXJhz{o3vEHxMKMD7+k_T^a?R1_y`I)e=rgY@~RAr3bL4bz=fx|*s}#UF-se*`+(0db7C=3va8XV zcrr1QRD{7MCpDD$rH1VU4f!5@lXVweg7r6mt9ICReq03ah8U5hC4YpCWQ7A)ZZ#;@ znGy^#F|mQP3KCBVHB_LNUZNc_fx!t#c$Lkn0Yo?aPGBiy3<3#Ii62lifSa8EFU&f1 z>PcYIW@Aw-CU_t0VjptgNlX@m1H95~Rs$G3Iw8dB-~lz6;73#$*=w=YIs=>f|3ak1 z$0x(W=tl&@ze69P@MsA0B0yA_OiBz9gym?I3N_4atd9x{$G^q?4@9RkQ3QxNL_C2K zE-$Y@`(j4>0p*4`MWBm#jv8*{fC%$Gcz%Ifj77TtKy*0j1Q4TO;S)SYpGn|hSvJ-~ znO-li0t6AIO7KsQHb$q>#%bs@~burJNAM z_OQa461l(M`9y9w1M$FKq`dsq3s@^);d}84rsf;89%dzmeGTrb{s~}n2o&t0n_jQe zYYpUBWGs580B2!jJaEf_XQ|=-Ck(O{m@0Y12r^6|H+W;fT;>RrdT3 zxCs)+nbyS^fVLeDN`x)%0p#J0d#Z{c7e|46mfAp5(Eu| z%ZO9KLA->O#1N=Yf`_^PXaD(yh?sJWg@&BC zLj59Lkv2;+NsV18f-433#kxZOl^|1%N}suewaZugYt?L+uXfjHR|L1RpI*s=`+uws z)(YzYhMlMOeA4RED_NRcf1R4Ga@F2it+F&Z{wqa>><^~ps54F3wYab=waw4=U#ZzD zTkZR#6?Ua|t1SPOnys?bS)a7RuGDVj^Ixgi%BRl$q!o6hcB@SPm71+G)j6NE!miYA z<@H~wIXYf-ZjCya^0lvEgX;0usoBb-&ika*$16d4y*nXWn3Ty5ZPyd+36x(#rDA;`4pT)eEqm!GoahZNLpGHt!{Z(aojU48y za@Zj>k@#DNm~Ym~Vg8vW1pu$!qs!4w(;?a%O(yV0273MeWpxJgNs`pxTR*WsgZVa) z!R#b8W6j;V90N4hXU8FW3;+R*=ti3=ET-M*a5xiNj@nvYmBr*+HPE>bt+8j{3{T&%ei{88YQ45V7p9Fxu3g2uZp6Sa(N98K?(j%mw@da zeW=D#P%>?*yEts>)JCb2k>)ZhbBOE%^So!`I4wXB1_bHT3#PayhZkfO z4`vutI*%5CvGbY8W{bfkS&x}8fE%wj!^xQs_!6(44En0g2JN3HJfXdziqm=YlsK&= zr>Mv`a`dRtBgQHeabN*W6DMmiVfdI)V@BmpDjCW&Y2e%=oX$~&z>zPx(PtuJ6LTHL z(x2nfnLI!e?w9GF)ZmG88~8@GRW#h6&TNEDF}*%cYtGG^(S$7J2>4u44s67V=+0|TUDxj6{S z!)7pf(E~6#9(GCvipDqw*!UT~Orx(BpA6%hgAM4S=$d>yE9{MxQaGW>V$rZ8rfzl^ zhz9UH4=akn{Xpl2Q#0QbPwfpyZ~iyv6d0X9hdK|VgHh61b8}~;GSoaCn?>bEmfXEJ zDMCnxot}`%rS81`Pj{?TgO9QKTR9UbsN2(%88j5@Y{P5w;>aA8ykNaW?p`@ z19Llr){p~oMsjH^7Kb5>f~43LDt2l}jFH5@L(3J>Z~~|nA*EHxr2NtZ68|%VK4azw zLXW{4$2MrKqV4|NCd~z#b%~HI$Ob~ZkO4O7n0&}>HX-ooY!;g)3LA%_yK!J2s}>)* zRY`u{w0PpDd|dFj+I+saRD|q6B~mC#8fDOCY%!ET#b+T|n56 zqN5P3P>U`)sWdC6SQgFo7(F%hwW=Zz!k4azisc2i4X(_vB=Y7+{g+M(!Wms9#+`Ey!^J2T;^x^vS6938b7JW7!60Y;|!{J&TJG?PG_RvG?$wd z#r{Z{$PXCqg~!L^e0Ne{s=J%m>|=&r_*fH_K~uf2wIVoN43+0*u;b zb2#m0t%MP5`V$t%cds-QfAg9~Vw^B|tv(1VhFqtE$j4kAIQtb%`Uc~~4uf+zjL%T& z%@`%NT*7k36^pnuVt5E%IsP$}U!cXM*%6 z8Tq+`2;d=J7LJJxN2ZZ%GJRYXu(bzcV*?wO^&FDXvwNQrMY|qji+4Hr8XRT!)*|z; zsFKtA|-@I@6q4M9L!p0gKUW)XD_cF`l>XH}2{L=w=S|l;f*nneO*& z7#>Wq$ylaX9R!)ssfffsguv5f{13f|e!YA!Ftx`8_5>t@!DKe71uO=~PnCm4JX#IU zS_I&-eiA`ePDx`th=Y+Zc%%mJ(92W-`8bL;34~=ZCbskUV|!GSNIoTjtqxq0aTyF2 zhkG4Mgl=8uSs%4#&X^Xwpa>C%&dK&$qh_%pq1!hKuycTbDVXRfY=9BK zpnzPVd00a9dla3I&3CV#r2WX@U8+cEHA!@4i%BhD!YdX~FF+v{h=p!Z7`&#yrqS7X zeu8lm^6FO;FnHvoa`Zg12}N6n!Mwl-II(Sqeb)&Hyeto_Fj>afk0hLUgIUGLDB#$s zpQ4NvOQ(8i!E`2@o$tpV`$Kj;0vM3RA~JX}$Iz$N-_e`!{s$aF#lX{te$(C$j&R(d zMV2wz^kH+xcS-o55IegXoXg~}GTDWG+)<-5>teV*773e2ZhvOC@Su6sZ!6zSp4e|pnjSaIE18vc- zUn>A*1E#!3*X|u*;lV)T9Af`gxNj(o^}j&{-wyquPC!`#C=fmhQl#rK`vaiOGcsEG zK{>IGu5Hu1$YZ$}sLmw`Y~Vva3(6lnWK04Um9trR=$QdRLeW1eNp*JZ z(5{Ozn(G5^G{;$p{`;D~{{cE^&`4JRG>XZgsUM?HWw9JMk&GGNq(_gYRhZUJty^^# zW0+)%Q78&uj)mKPp%Oahb3@g?|1c*JmW(VG9@`@fMA2Q?F2s*YYuv3{YCuwkxI^de ztw}6cH)9PZgOnA`5Ai27GZ20Z>@{-#Jz5zV-#RelOcoKg91KC^Mid<$1S()&&7n2w z(xowAyIDduU6mM5BXeQX2%%3S;0U-%%1W%)gNZ6Aa6SPiu$lbcy@uF`{_VS)MZ)$v z47%zO`ci{!*t~G#5XoRu8+7W_2pBvp0h=B}f}I`92qKFakbe!QAPfArkVtd{Ihytv zf}TAG+9?7SmjkOlk;CIMm7%ah+ZN>aXN2wMM6!8|1|2#!1O_kIz~uox%VbipnIe5c zlMcg1T=3^jzx}pNLzkNW(fa~k!UG$+b?a}AU_?`6V_}OFOQF(&b&o61Hen(xWFQPT zH8Pe?sn@ZJf(*NSSczGBEpWGch3OIRExzf0F%jZ7}P!|oKYXr{Uv zOOG3G(Su=7*TW*S8B)8&X0e%@x9fy;-^W4#f=d;L=YU65U@27p*(XS$zNvhR)(eQy4 zyKPweww)XLK?&HL^`Lj2+<)-k{sYfL0{r>l{-d&25GVYBmwVymz2}#)Kv@ENB7W<( znd#)#?b&QnkDE6h-Q4I5@%O?H-Jw;wr%h;DyLx~;3E~}7BoR&)1yRAn!r3x7LM@18 z&w%S3I)jl(C&0ESHbx+#BLvvaX8|~uN%PP{;hqoPEhu75W#qCDx`%rB z;5L)a7DLCTg5r}|Q(-6LWiN+3HUp0Lz*4e|H5DAm%UlI${?`gn*8j>4!#rD~L7|7V4Og4HZG&-uVmSgTZI znNsyxpym|w+!{4&mWnKs&GVeu(9b|ktW@3WLjPygr6Nm_d47$WSgHE6LjPygr6NnA zc|nbuSgHE6LjPygr6Nm#d0~y31!lxmvu^Ejk!2EmUbFrrbC9c6gHJ9LS@N+O3xU2` z`h2syR*R42fB<>$dCmHHW>2m9)#V_&-R;P&QZ3i)brm}iS3cMhX17@^R=Xp+YOHes z0C5(>>m@nxl1a8b!r`ium|(Nm9a;XlQE15p${=TAR^7a0Br(T{B)OA)Nl}UMCbdHA zNVHiUzABm=b40v7Sv&R3?MG$qf4uhz|CE*e^Us5O&)ez~?Jln~B;n%Yd-r|+;LGm( zwtGf~UEy?LjjRwAH)vC>A0Z?G?r*BjX_mjMM6Y$w0gx91g12uF%Tx@?gh2(m z|Mo+g^Kr7y-*JB*YNk1R1Q6UdU%cCe*Z{$v?L-_HhTBDVCfbvmv>Wh!)ltpSBfGb# z?@-IKone?Q5X5RHI#bL}o7Wx+Z}dP$4ST^d$ZVTp#n}vS3>2r(fRR}+Ml`3>YSc@$ z(f+ltXQWoFGgw>++0F<6g)^IVTy@+DZSXV0EH^=qQWX}0BCV{B%Za>O6U;p&-- zXZ~8wjyJ-)#(oY+$(j=6{-dG&_=!e`-Qjd)JHx>SI2x*s_qZtWb&`|KnjKJnjs7T1 zHapz*Foz{+`=R|u+$Y0N9XnrxMD^Y8M^2wOdE)5q)3ewvBfMROm@_Rt7daj#g~p$^ z9U!f5i+AN!QQVcodst+U+MM9DUi0TXbxugv$ABHl`%awPxoqX~mCJrI>l|j=BrDD2 zQ1{>bnlmIC&b4)Js`T&3a^R*zSRP$Yn?^~&m`qq zPU)Fbi%4<-_Rf$~=83pi{~vaEum`x9}E|6cM>4bg4+mD8aZC@XC`Iv};h851(RY z*=r9{O)>>Wwg4kr$gD{wsB5-EQd}jMi$wyA#Up_`JP|<4-D0{#sG!&263;zzb`nSC zAF2;r690sV{9u?f(}9sG=V4@X89)Xv@LB6(DzYqa%vsD+#LT+)PZ32Wka!?1E#>XG zalcozN+7L42ETT^wD0iw1h%}EVV@zBV`OjuwgSy(z>qndPD}hgAR{Pw@P3$3726L* zFT+O0jfo{=*ME<`Rwz^fbBfwTQ*X1s^)9YY6t%>Sg zST6iKZi?A%)GEd5JqLg5OVVK0=tPQJ@6l#7Y-l6`HN^|J72)6n|0X+lq0Rq9=5wSv zZSb@LA`s6ak&58kulv;VA_p$HgO z6)8Sr7}4%Db->b^6*`tgAa+aQYqKe-T_Je{I>PLb@~qF$asyK?tZ5lG8^tpY9T|gH z2>+W+0qcmsi9N3})t4>6lA5PU3hX64*miy}FH@|MT}S;wO2N)=Q1oz=QUG>-9JIjP zk2etD@@Lqp=Dy4ZU;e-cm$kUqDgKP6H$=yi)@E~yC7>n+I|K`AVuTw|bV8^W>IDc- zF2I}(b8HERqo{K1>ZlvgQXPovy5yv~b(7<*S|QPO4SkQkd#PoCN}u6V(AtBZ;7ssU z59%`Xy_4>rG+^M=lSk(U_}~Rb8HCF!=dMl22{@cktCsN@6cWwoh5RDqGN**V9B_;A zHRbd|?30N9fcz3o$y3r`AkPr}y#n(XlaCynh0%G%IB@&V8pj4M$Yc&4F{oePfn%rb zd4j%u3!(T5RVab4r>I5cfk_}xlOcmS6|d!JDDzP?Cj?Uxlaf(zVBd6%EBD_+mg@|4 zIDp5W$AqK2aD>ww17rRfe9)-1Upt{x2xn63Vbw5vIU|4Xt`f@U@w1(g4u>l~0eb*j z>8_Q1SS_u^d-S&$DP}5=FmrcooAMtdJ}1H9jCWae${YSH zruPl;ZQvB=CJq@$M4zyD#W51Tnp^^D%y2UvvYEx0Rxo-PPuAAWMgPI$0Uj{MX;O-X zQlNsjZ62*^gyX8Wa7PWw1C)WH(^^{Ygyxn%QGo3d1NGDOlqRP;K9JwigMgd}4w~#yyXsEy?wt zp?}fgV~pCfeobyQ38OX%CYD7lftPgMVj7UZdj_;9IAMn!^@nmiU)yvw8%fgN6Pcz{Kw@~9)=(5Fhm zhxeay{2b~{TaI?G<`BwRjmpt;!P_92iP=`gF@EK8AI9MkBajQloF(=nlenHe-Y5rG z10||>xI7;}SRj&0@&Xj=HXiH>6G4(C#tY?~6X+Ai74#-o7*LA!{n90#0D3Tdmymx4 z5&aQf1}~695}|t8%IzHk8W12RFb~7-_W_Io%qAMF&m-r} z`5uD=L|bWbNxobp@rU=StxZ1?*z_;R#Y?ud$EJ0bm;mNSkAr09I?VV0kA(HDj zm8$4f{zN88E5K&ahY|8?shT}!b(?_Uc+BvjD7rHYMh7rOGWIu9i--B8ln4y@lS?PY zh{PUOtTW!J6S3vQ6&P$rq>>{NigIh>!lT35{eAivAo5;&{b~#4V4KsRRQjO&Ss)fUnw- zE3v&ze7phHV_QmE_c7o9;?HD`9NDQwU6TUdDy*SBMlof|f@YDBM`JM|vT#{EKGFIF z@|c)+c*JB0pNXBYi0)eu;DAeTr+{sAY%)d6#PUb}gy5rxjTqpTAL0^UR4V2Ic0uvX z!Kv+9wP}^E6$xBT%n5yOK_WBK@4?Y9c`R+3r?qI+baZZk-vDe(Jn-EJ8cG3p6QnX< z22z%&D6AEFc%Kh%qT6LUOZbXj?F~x`VWITVyhQZR?C@_ zis6_|zPE5t42(jqI6?|rT8to&%4}GT>W|w3Kn;VQ=T0t~e)riW9sq{| z@I;@-of+-Tbmz!L%)U3TKf1Be84<7x!<{q%KKF)=&*_Wd=EGi1q*h8N%YsO$+LDWSUVbP~z~M+lh2p6~1l9#a;1&jn zB(uahB0S7=nH;uAS_L0I$q@yKC6mQdK^L!NIegayOad`qAYCpl26ys`RzRo4u(^|< z;{UV%{35RY0=s7~zU)usr{7HQf4Thj({JARzg&g{*BAZy%Kt^>#}b@h^ye%87nT3( z_i<>$FRH-T`1?iW|LXr=R{pR0f7Sns zD)2S_eo^_q`u~@e|EvCA_5Y#@e2u?fRQ|92|7GR>s{dF0zo-IVi=I>{;&Ff)&Gks@HPH^QTf06|Cg2jtNveD|My>*e?V`813}WI zd1);g5u?~q@c*+XHffyF8vak7@M{nf5e9#C8MdM?f`mv1)UTh`q<(#2+OTi?4j7z) zAdcv)w%5MBnodp3`?mEGdXlh1qn!N1>)N*Iyq&{db0nKCZLjYf)l1Rl zP?wi)PCBnS@5bNlb~U9=_W@gGv)blPU%htTS!wCC<@A#I&GRp8y4W=M;_9*%y5f_k zWAyuJug~1S&dZND`LOs=Ws6smz28sz<9wdD<-Tudyz#7ZLaS332W@Ri-5dV4e8A6P ze>~?t`NbB3TaBABes0W|^G6kRT8NS&i_WR<)7C`n3QO2^sc+oRJ-Y`pk4?MY_8ZO) zao^%iYo_)bcJ_MQMbe z)-7(eH2&zip?i;S=#bRra?m?LuT2jOoPM!O*4r=5c@WWbziU4!G-}uo7ft=kc;(CI zyIPJ+r@LCDJ$sitUYXnK%;m@IH>W38X3t*VRP#d8@|@Aq`C+UuJhuNx`-Q~ig9ar% zASIj#+gX0*;hsT*M!fs(dEuXvh8(r6|K`Zn1Lc?2ZP2|N(i#`vqDJ8AMaiuyY$1l?mc7w%#5tj^QSGpwfo6~$XBNc?|HkKBce79Y`*0O-O~`Jg)9r3 z7xw#+^uxZ@Bj_EkE||8gwe8rEOD`nLM|GKddwTvD*Zh1%pFCwwb#A+9-#1+Cn>fTWK4;ZTEpmKT7vxii_^m{p;jjUV+M0Hu?UikG)bwOJ|^hl`0#CA+mF2S{qB3#k;kX^ zxjbDnJ^m5zs(~4Mb;_+t^;w*3pW(T&Pd4F@Am~~2)Ki3M&AbPb6OSEY_ER3QJ-XDx zda}V0-qm3TV>ZfmzkV^h+q&oIpatU}k9|F_^V#ip=fB?k^N4E$cK-DK@s{7Z?QB19 z%$x1w#jR!La!%i*kR>U*10g|kZ+_Zh#U^}O!e>!l)-q^pzFDa6o; zJL(NMySmTHw7E?UxJc!K^$D##+EZyk%rm3j&Fk@~p{Udo-#^qby1#_7rtI-iQ_!xq zq(x8ro&PhZzA#7|qYuUlM^sSv;Shxx-(pc8@znKqO&yvXzGKi%J~S`ua@4++w|bq7 zZ-@4rrOEB^J0YUp?Q>)8or6;5Jq}Tp42x)f(ZDe|or8)*X+qEMZ3HAZc>{ z=YMxTf3{TrN9ywKt)7sJ51m|daG1tjKcvr$(-z!X)|4YR(zZ=%A0*wkc<7cpi}w9? z{6z1mWA)uar~EW5&o?`j@y*g-CWjmv*043i?75qN_-=+7U*Ycr(=e(@Ic4Z+M8L$q zv+c#@vfUu+ib1DW+?>RIRzGpiuy%_=y`1TdPLyVq(~>=I=eJoB%Jl6~Ess}p=^sH| zhAdvY<;S9RzSiH>o5r#HPB>P0wq8Z2nYa$h?ISB3Bchcvh+RV#_teZA)@RYs&?)Xt zJ0pJT{hGaX=)ssSWiJk1czmFJnCAd3`Qi&%@*>Bg<6T#PIh+MqPqqw;>LFTq_nBcY zMVUkFD#ZcDicM*AagCGLbd~JNhP5)X&kb1EPfgj8ph~vpBmfttc)?yHR+(Wj3yZ`XUkfC$dS! zrvah?J+(bR5@f{Jc0zBOeVDO^`_C#2*Xr*GN02k{eg$dX1ma%I`yqR8fsN2Cy=OT}%uk6@( ze&`fRGLN-AI-=`@AmfAKegTr zOgWm;kOp(4@2U%BIZO9GxZbpQ{>Iq0l_9O8gdSjt`G7`FQtRQx6_|Ji7 zjYS=gtwQR}838l0*m|H5Z~AtxGUBwkZt;%M84ZN1amqofmZm_YX-!(B3XNjG7fOb# zZ*1rpIU#-`HQ8HNTWVRJmfAqSY-rY{a~X1(cJi&0^;(2dt}Gd@-hS#qwEoTdQ?!!r z`_GTezqnh&!8vKkms{(sHv(N;Idt35;n9teNvCA${omf1fop7-vUKVlYU;{khpGAn zL|!nf=U8cb`oQPsyX$^6wXse++xgYw^y4CLzsX}>&6qXonKXv}?sEE_3F`LzVM|ZE zYcNkgC&>IA_4~C2+rJGJO=%z0ta;1hFHVi9Tb%Kdx@Bcr!Y?21~rXKjmBqArUpt`OUWtsS#*f8RWGNIG!i zlzjD%jaR0#Ic(EkvyTpl8uIsy1Kr+iN)|1cKbzim>o32U3Kv8rmed<*9c(z8J^aK% z!(hql2Jc!mEFIBPw`Fk0V=IxF_x?V&zM!Zmd-~svpPp3WFI?WZqT}MtIOg3;mu7PB zl@SxW;aMkyKPoF5tH^(>m{R}T{rmTq?paH(SYaI?E_|97Icx6Ri`!=HU0*;+>C^GX zPeaY_@@&-t;avKSoynp5W-r^iwITf6KJ`nB(l#v;n>1V)GH^g-iTe1`?2}#>e#Yjs zF%26Xy|t*3?c|duLsxW~)uiJ2p6e@K4!d4)S3^1^F+c8^j?AIoycuhQPACib&G zYa@F&WX%P)JW@AJb*oNEy)(#<+*75+hu%$)o^8}6?=Z1(8n_;k)QYh1PExmxuX>)Y zKYa6rsN_Kt&Y41=Z`-i4Np^Nv#^b9ymyExBec>A2)M1PB=e%$s9ox(>KW>}Wi+bnw z$r)vjXA&D7zx{Z7hrYsFZ(of(@k%l3Se@5(lvf24TYvxk+l=EkNGo$DPA8V7u3G(~ zKXUS%HF((YMlC{|3R4 z`QIHa9^J|Erg!s9!G><*FR3feZE1gUyGS^db^F3RBWd4+GzP6`& z9yF8jSI$f4-_@J(V`<2&sb?nMt~0R@6OD`Dps%~UuG_OhZ!Sn0vh{h{m^EHXpS~@U zvfuQMnrk_iaUtgRCfV?khowc9rKK}Ny^ohtCnz~-o z)rIRWw6_JT%hYqemksaM;mTOrKA%10@T)u0D}Ve{cu8RJ{9xioQF6|FXI_W74}lci%keC+a6auI?`^EMy0- z+hS-wXyDx<+?2Y14@bW8p@2j&HT$?rj{gKzFPoKUQ zyf30bs5SXgy`J-bdVVw`>g2`VzmawG-@IY3d4JY%GkyEZ?t5gvPkfiuBZNh zFYleWch~NIlShmmef-g%JD2X=+j4fN8Ks9_EWI%JV6;ZPuiiY`z$ng!WmBKychi#5 z_#;CWRLtvj@J!22eL42|(rXoW?6)NLcN;G129^#WWS$wrTatAleM(Z>)&nN3TWENa z^4;-Ob5GXo7uHk$zFlYLhG+cJaa*1~~Q9@37hG*R? zdzKm_mv5U~=jJ3s$nTq1G`Vv1YDU>q*@gV?{`qZsgA3>X5^381R3d9S<5*7OyPX@y z9geb|KmGvZkH7Zq|B~&bV@$zMAzkbVK4I`6!c?qr^q!%yl^t1T$3`Ztn}tA+^Oy>ic(;uLVtypJI3U&&nH z`qA^Y9(ta7q+jz_rRyd%;E(My&9Y^)=-sx9c3V#-=}wYw=Y|a(*;l7Gxo;x8{&i9P zf_k|9%Ww3!E4X>9lUw!MxKnML@mjVUySw5DXXEqI8EyYw;h42)IXO zcW2uELkz>&HM#|t|4LIeE2@A0@Aff!>e}4V%ess?y=>8imdf@|-d{Y_BagYHOfiEU zKGt1t1MkYKAzgl-8|6+(Tkm*&${?D=7cR`sSk#Jg|DVoFXmrHfBP6Ea!0gC+e_s71 zr*FMEce1t&TiC`!v)I`gPoMp|@#*GGJs!Po5B2bIxgwQeNXM7L9=GD>;(@a z6Moq5TqGy;3%#ITH?iWc*S7|BM_v89`If~jleE7}clD|}X;BdFuivhS?-zB@G~$gc z=`vz}=&-}3?N7XU+2|jf_DIWSWxp?*H7iMzFmmJ(Tt!pmh0|Bp9-{U(f492B^|J+n z$knCr|Fh6enp~%IC;MEb}NDTKDt~9hUAsJH3fBvnXmI`QbBF|7Nb(QTmFlY0RUPJBP^0<(KDw%N%m9 zeAc5s1cN60nD!#S@!&VZ+bHjH>hGS7_PF=U**%THDM)Kd{?Nn{+jV(=bR4?%`NCb# z?%1~9|0`$7&2?z}Z-Tj#%6^|HWpo?2;m)M@_^tAvD_-5rAG^GP#bm-|Z0z<;`MsCV z3ManXI@ob1g@sHXsl=oG3zG&v`k`d|(Db0`N2uB@vO!B&~Tn%2ywr zAKGMD-_GO4j9KsA`g2g`$#H{3+nUbMPAk>4UpeydqSMVM*OBb~V_0UF_m!I4n(jNA z{Pt7l<;`VRmnn`+=(iw`^`|27X_M`@-~PKre$n!+I^whWXI(foHia$~XJ>T8$)?mm3g)E%8Qu+fUvf~#3+xXPskEvfnL)YW z#KX)o8LQXEo^-rVg3r1r^iLPhEG!EGnkwkaA#`W`yz!VY-0Am=_B;AdcjqrtYI2dHz)tNiDhOPI|flvF(0?2FpSaW~e_F@F{W9*sfl;I5PN8 zbtm7hzLpIWi9sCxwgd<2xtxlL%D+X48u>i!NcDQGj=5Nv34@C>NMVk`{zE7H^!emNq>!3L<#&T` ziG?ebFk7D4V>fXs{Fsv8$5g25N6yc*THNS68wSic!+qXOX6*0jJ;-uR63@d3#(Fde zV9BA>RbF8rO-#JhW!I#SQqVR^Z-Sq?GCTo{z5lnZsRL@EH|>^#`_+Fe49L0jM$qd6 zHn@J|u%Kt>2|*Oq;OJPvm-}IO4rVD9-yR(lF8NM+ZQJihFg5(I(>AL8G1MAt3~7K+ zEosbssu*g2S#OveI=e0R+hKWyh$F{GJ$jntPMi256^#2fV(AyA7f$HeHT()k4vM_n zbd{=m+DF-o9FT}(eaOA8A#OZkU<1igVbLXX4-4^ul-E(2p|tZBu}eIqDg+B_a30y# zA%wz7-Q=&P_S-k&5#x|56^LS!aB6dmFcQGO;H3%aa4|@y?Cgeit@7GWW z(uRB-aWcco&#n{v&zgQ@omMdOT#ZJQbPSoFCqT)6p6JBo9~geZto&8&=ur*UAoam| zciqs>Y+s@4>BoU@;iit_amqA~cjx{I<4tUs$eM?!pCqMK`H^-Wit#>q(!0>(CG%eA z3$fVCJN!Cbgy4|I;oEZkLbtl6KIP`~#Lw}<%Is0YN1u=7i<>!e0>bV!@X9{&@#difY+R_b_t z$j(A4RsobDXvBS{*M9`%8=FV&3}~;evwK^WZFYNcR?a=}d);7T?eOqB>U>dyjTKfi z;~J`s8Kr;682--qakKx8K}_(OL2Na<<7AZ&WtTGAquSiuV;_CvXd{Xh)>f|?q4 zMaXwW7PnMly~Q3Sqf??Yr;-gP&T_AkY6NEgiEKjjQ_y9_&W2!Db)AF%9e%6i1cjja zredYdzKcs4AcWh-)$3nC%Z~Z#Uh>E3mOjEraR^j-kAs|6dJwj8YneH#0Jw?h;?lX0 zB*mx>JRAkxV^J}nO7)fjU zIkX)@oP$_W|CB65?misNez=s@M-Y6q4e<(tpbGe^5Q0TMFq##nEem&~m6J-p)wnQ# z*&`5i-->1j&zTu3JmJ`|+EkaP9;6qPVQfDpHFOuoW11;_$Fb%qNm~K3)N!57 zk99Yr&AYW7z}S#9foQf6dGsH`48XKuBTMLJpA@XxP$l%^g|d38HD40`Yj;94_N(O^ z*X9q2EO`0Cf+L*(51`&y-zLMh+!F_Pus12sFN~-Z%K~w}_WF3L`dP-e+rg|#Yd?T$ zHgCUP5dNgp)LR1&G=9DIHEPYk1jiI^=z`$4nWWTQg(MU_sJ(vL$ru~M0ue(lF{DD@ zN2yuaF1qW9!t?MnTqWCx?ng2eKnm;2*P&O?q%+IFRsLCl*nV1nGO4PiS33GypyW4) z_NT<}Sgkhd_v(pUEu6`qJ|wk6hVUhaAU*9w>(~*jp73Q17J93vYeR}Uwn*=L?E(Rpm?kN`!W&b zB88LNM%I^sP?9^ImO+CLbhnH$H3Fu)O=2>2dbrp=h22w)SeA^o7utDsg^P_mC4Pp! z0$vF=R96s8sxjPV&@)m$rhz#%0s5I}~L#0gzhG z4RD(^squRbDLvA5vJj6OL7n5dc4C9NYEX2nl0l(s>?y2qe`OUV5KvNj5;9Z;n7f-9 z@Vd)JuuR_p86}u>nruD<_ZaSp zf~KqF_CnUHqEUw@f}{dn%AE(>@`yltgWR6zI=+G6eEYp$yx0DlNs{ynko@T>enGn4 zZ3Z!$b}uy%N5zPXMN2tDE)y2C;A#yKzLh6m>4DPpW~kjFK5$m|CZraheyFWP7KDC{ zzw*~L=Qo_craJeQ(E1AYKv~hjAVNpb{g=7s)79iHI)2V|1yAqfC)3sC#=o35>`Q(& zu}nDy=+%l9p|^S7`ZEnpP1xdbxc>h2&0z@A>SVHo6e}}+@@ZKXA5i;x4BDRU>F*(i zy%gnKzyZJKu*2?jW z@gt}v2ULvEyeLX}fDsg?(U=DA1E#}gKsC9o6aDGh#JEt|lcF1?5*tBahRYA;FnXqz zuP^*|#IV?+H6Obv2L|!_7wzOo$FZOIC#TQ1?(6^f z*RnW_@Y7c{HK`(?0erM*#ioolD_II)7^kv%QCs8uhGlMM97-E?E3#>(Oz!2ECFhf} z+&GSf)}$Feh-MX`mW@T+?^iU-GCxRN?JWQmdS>IcL_3)yucb0pizoo3ol1We2u+Cb zy$brEE6Q@Kz5jVhn8aHL(|OlOJR&XZmRDb?TNPe#O7x}RUn~d9I85JWh)@E%lAz>y zuRlE(7el97ySBzs5sK%8EGO35ow6DW53DC(aKJ zLET#wI|M@m*t5KW_36i{I_4(LhKWR;$Xr)%QRnS_>!szF?C-p@VW$lFTYc-RzsbAl zuqtuu&f%Rpmdp~EhF(XpGYefu;w=dtxd)Hv*@1uUhaYz1cfX&C&4p*g29wmUeTypf zJNu>sy>>8dXuJA|%RK(8GLT>}_I9&l4>lF_z?V;a?>VLKIMHVQG^1hH&X$i~we;{@ z6DTYn=b~b)@4msyA+83&s_^|%Y}@ywqUqmz);g1Gq-!gwy(B+mSkti%4G``nx4^c3 z0am0ia?%3BY7sN(azsHdHHm=f?us8>n_!4~GQr64QK_@@ z^a}a@u@Rh6c+`AFYrA{5#DDebJdv0Kx&AF$L0xY7Y$!`00j~lBl|j=K1Cvh&O6}VM z{M33WEVAsXiG1mfP$W-9*i%U}BvK^f7GweRZFN`QpZ=f9jcX$n@Z*r*&AB3DffaCG z_0pAqxpssAc@atss@7~-dNnUfsQX2CN+>00V*xV(_{EU~`t}EHzzxoJMpKO=v|?{z zb1zhbSji?t{CQ7Av$n447e~`+zrUosEK|&$tPe)04VCIJHb`0)?9)ev71<(r!rwO! z%A2?hPxlIIt_l0 znN{SK@t$ojB3Ez`ex8oLwXspsA=75jG`xB*Dg7&z>ydcFhRrz^7X=(EWUfZ(j)WP5 zq5Yy{CdJ0M>dqmjO+I73Zoj-cz23E6@m~D&CN|ux)jN$pZUo=UW7Fi6d|JNO%o7A0 z^ggjU#;dnj2pxG3Idf1BYJ5^UZ`a*$J_?#MNTpkSaltnH5ysG~jj_fVcJY<^Mz!3O zx`2zf8vSC8U1`vyOk>^GFC!+R?u+iu&!4Wt_tH%=ocDm_%V6qog`)KLmVCa3UvOVa zn6h`See@Q)NsR;ec9JY)cR7q%o-i zv=&@4jEqF1t1;adzPA^3qvSveK?HhoPwbHi}mFZ z6atMuHFz~zv07br1&)GOCXwN<@FQO!raj2=#^RbWX9x7ao5!Yn_?M7ZL6o7m?{^_d zQ+|C|+KnFOf4P@?`LoAYu%aWfV0fxorN^lsKY3_G47JA5<&sXkC$+6PM~SE+J!BQ z*sa!8SJWLXt^9a6-y9)Jo;wY*yznAcM3ns^zz6qIeYQj+?>+GM3uif6WOtb!j?{=1 z-%@>UCm!YCXW-&BD zxmmuy4V+Z<0<2=zU+!g5Y-SByEDE5A8X%!JCPFORvYeLOy;KH$%GMxn?(W;pGZGr@ zvuxRoo=z>g8KQZK)N*=qx1wZwmBE%7KB?vUp3V0jjt!JIlcds_SJmdD7Kn+vh>%|~ zb*U15{)1$|9}t3XKt1$p`nmIvI+va2;03h+cr=Ac`#X{S;OkW_ZNtjh{E{%}g400M z>;I3qf+9w`wH%&AUaCS$5z4@r4c$o#x-*bxI4040S=^g;wcl}hCl8ptyIrzoU09ei zoDPD*NTn)2TW{=9{HqipZXiP}4T(2BSz~>Y_aplSeDArW!#|J6Q*>(qa4vt$QQGs? zG$>qd`WPSq@S)1_5f5^Vf{cB zVN|>wXfQtF!(F@i)9xQ2y%Zg1fSa5+R!al^S}ik+BjfVrxS5eoI8YRqxM5yYK6>4K zrtROYs^WsqNa|C{Z}9sOk=G?e$HHGPNkB)FSQW~bS8+OZh-{<{{{V~4zL^8YRRwl% zM!buLa#crTy#=6G6)lRib0LcI2PxyJ0u3^d;SZ`dL!f_ffg3AYUXo11qsjYk?FG(Or3Yq?jhgpadP(4>}e$7x^3|-3MS`r zcKNZK%m{_AtK)V??s~~IT84dMeb>cEAH9_H&qs(yjfMyY9}BnrD$~pT`Jx3NjoXa_ zd_a=vTWJpiVx=7lC;rBqr0?Pf6iYu^Y9}dF61bq?T(9XG->2uVeFvV}FdY#7eBm&#`O-Ccg)_MhucAwrAW zR=*}XST^Mr0Xhp*5U7*ZZOZp{-K%UeCr}Da$-?=O;yHY?C<#Fm&k|4qt|=KlEqVsf zs6HGdn%B@?2oUlRHG}6t5wr5- zY<->L+CMrjrty9k((P8ukIFB3at5(td5toD*jx|v6Ax6fOx~O^Lqm0J{9JR+`u2VK zFBc>aUUhn$|5Tbo8pLw#*9a@oDKWm#>6l3BOqwDSi6E_7=Y$C^NT2tctlh8y7X!3u zM?YTy6ZJ>!^TV|1aXGc~vyP)GV;voNKeRpH;r1h^y-xSX^z%oAC~}E&e{%U(-BD3A zbokSGYtm{GHXkn9&Z6!`CpP4Pc&#)fM5Nrpi|LZa48aa}A`|EwPQj+vjjjX2rylGN z`Oe3u$x`1&r6ZgqSB;!0FZ0)jHRmRQkDhQA!$l*D)#lDRAG_pyLmB1@fZHphjeRU* zv=CF*dWUoxgkC9s8E$t21RpJpFFW{Z!HDUDV&(B5!<&iveGXVZ z7ntsg?0>@XWK~>F*Aov^6WBgAJ^UQWe0w2%?Z7GRt?Y1QWcj%|wZG>w@!hLR^6ag{ zw^RH5nc3mncF|6?6LhQ%|Hu0xcV|wPZ5qoJxp^l{(ARtZRYa?S_%&~>*-N-!s3SY} zL6e+32uTje`u1!Q--FTzYcGw*)5Br!hqb&5e3szv7P#N!WfuW+^Q{DU=6-N0!RtUTV1bLpUcHE-t%gp{!E^m~v34;ue5E%lN zUES(7B^54}R}zVXS2okpv_#*@!g2^$HAJPyy#@szZ1ox=ZPOr<^maHQjTH85V3fO` zyx~T@q6Ln>^1l6x#LMD*(SDf~yada@+FD+LVjXSTHp{C>2w$}kL@+9*veJ9On7P&) zl(u|(g|2Cp#`UX%EC~sPDJYtt6fltBiYC<-gB23h7pn zDy$EXMa~mE`iYE&sXDKDJmh2H%= zKlD5rEeJI)MUgOEM8v{**{!5pgOyaPyW{yEYgg1m13xoJ)(^XPnRv`}8gGW&PfvS& z&GY$Amsb4m&d;*423m0vqqAk^7v|8{ZToNM{JQdz5*}VuFugtDkmP!2B1T ztE#oUKT4ok$%)-JG3x}T=R!P4P=sGuq>P&vT3-4hS~5LumzU!pxADq#&U zCICmLto;9wArTfEL8I~&RHI2y)Ef^QxwBCcqBP{c#C<$w{ficUqjq=Ds4bZiXQ`-@ zA34zBK(ljySvOd2;Y2oGuz*UAjWP~+)!ja*U_&^kfYbAh@5m(=u+X~ zI)Cz_T;Vf7mOHBSBo?_jG#$#Kg z_&K>QJX^NR9sR-tqm-?p^f@Pk0PaybnN$@!MTx-$#mlsYF6G{&?#~?Vq!Y7B!tpUe zd~fc~Fu|+#WbjP1Rd!w?4(h}T;kX=;1!rjKEtCms!Jm2;dW@_TqHPZsn=O%SAMn$^ zk{>GPUplPUN($YiD9MRq+{1O}qAGFiOY{EAnSp0wwdw!$cBXV1lfiEoa9yEvHg359 zQ!ZU4L=8*86EJhnm$`f*Feo=N!dXN zCw58{|JpH%yv#s7p)!{~{sfi7=8g8aPXvKu?{DfXcd^ROXB)dk=iFlcr%h2}d@XNu|T9{0B>J$7K zcSwHF$bQotNRqpJihS3;;m#fJI*L{J@r0>)xStjo&bo&|sBu#!f*>6utFbz2g}3hg z5r8)p(V2aO93+cfFR^5z5wMT@f}T2+;(jD~Q0BWDF$MctQ}^L=!VG5>-`IlYqXWpC zQbkjKfTAexgkHo6b$Nqr-Fg)xtO}#`_L-y77E)AJ=7XYD{D5P4lz$ zGOc&(bI+fWWx--?JpS?E`|$I>2CtDMezHywu|f>nw9QfJT!NPJ(sIp+eOspcG49h{ zmEi)ZU{rVY6K8Ov;7|Bg5~DDd8q>ORVqM>?)+_ziEPs3S!y&-J`^83w9MSrF@m!OO z6>PaWlgi#QoDc}ijnZvkjjIJi51X}@_YtE3Fk|4u;u;q}H{IN|2QP;&d#tgQDO*Bw zohBS<=Nu#;D*inXOoMOpxk=RX9Ot}l5q?v(OPl{pMS7JRO^ruE9E6}!3g0o|CRW?x zUJe7q-SwB75Y9{&_HGH!^^nT6I#txsz=k)(_&rIjH|eysO4{lZx<>nTD(@wh&sJ;6 z@)LGPaiXv+84r2PK>tdnQ4KpP_DxyfQc)Pa4uo1eF-d-g8FW12=dHZ0}tH=d;7Mh*+o}mdQ!@N(TafKts$o{ z`b~`p#{x>*sRnJ7&!e*5)rf7gjpW_x_)9uun7f zFwMz=t*e!S7f{n6_%nSJGy7SMi%jSp&Pj)czX=Fht)oc~d1#S&9dvZX?42x_PAdtg z%4;#B1UdFN4Vs)du)jnTR!79?`koEOpW3fB8czzGzJ@Q3Ux|xvNRBh(}LyyuFyt3j4gXrb-lL=yiSQ5AdxU@N$iN%z1^m7-WUzMdV2x#88e*FOZgv$5EjD_j#>?wa69|8%~&)!jHK2rigq^J)d?gHM}! zXh+Xx-GC-+fJ-(cRPVtcQB0Q`RR}YPG5CDeo0>KR8`;JS4=F-hqpc6(8lr)cJ{XKmh_2vzl* z+NVAlQ30V-yRqB0i|vXPM4ZEmq+ZtX=Lprvr^%yv7mg2)a{%?X?JZ$Dbg}Sio>ce; z1)sdVzJa3Wi>RshQoAN9X-bBj-!}$D=w61_@ z8YMSikGjz zSRFw696MYqYz^!i$v&aHh;{663lW%pr8_otaw%xjB1{v7$6RY_oPKq|%%*OFkm!<$ zN!m6POCQPR64tloOGsw2H)={}hKk2uXzWz-@#1uq3PZ2I9mGY^y!I4Y>7DAFKpf@v+1Wh@KhI`2tH<_*6s;=_|gWOgoy zQ`AhxLmn%7DkL^MTOTg$`o%24k4J5o#-|9?>g!phoFbq|MSmy2t@A47K|}6eG(|kh zj#z}2Zc`5K&jv{4)u?>m8 z4D6*!oJ!RA;7kmZlL?$Jg6}MXS}Iha4g5yNAc%OC>&gus_g=JdBx=DyBG~kyXNSqf zIYmirbRnGiE+-BB*8@wfo8L`(i5ZeLs%eCsC) zTE$O@m5Wi-lyUf%Ke)W`Yb0fNjrbpo8e=0)0fy!Na(j-TE z72o(r1VHt9jev%pFlYbVNvi|z@o;4Pn9&Byd7NS8GJ%&YEZxamgwX>yqDt>R5pT7T zlgL6`4R2>JYs)T%xY_;6%l$Y*) z8cPN1uCy{Ny!Q0KYxmJlJ5PX?J+HjLfJzPDMzwR7CSp~@i$X$~SCY14B$nRl_l3bM z6U4z8CTUv#W2z}?)c56W!)=Nym^L za@1%!H+MvK#8R5k8F4MJBAqSx$Gl_2N=xcr0F*oV3HJ;L*?~|rufpxJx5{*SOrT0Q0YRdMoHc5*LWZaO+Y{|57GhPUV+{I7p9k&qnL2p7TrzX zN~XP*>Ipr@4X!Nd`L*#ckQG1PxM1t8LZab7AQt!8cuQ z&x6e#P4AV%I@pI4f;M!(^WjJj^y zTeYR8(R9XD1JrlN6lq;Bz_-EHFd`H4DxQ&I0T%%!leD#`X9uj>BX%_l^ua_AKbe4Z z|1=<~_phNg+p|uDE4fF+tp2=0-FzIy6J7i|3lWNV`e1y{?D$XvPVP=c6Y@N_K_BcN z{Ut6IEg2g*VsLZYfRZqLfs`LVRq}2GTNH%#M92AR-85ASX=r3Vy?k5sFW4@=YKX(w z_uailsy!at?B#Ohu?0R_b%{tRlB)o;!x)|+8~7IYJ>v|2BVPdHF(DRS4fqqK$`@?h zi{vx@YMB@GN+Gux_y3&+2k%o65Y!Tempr@N6GKNSK%G@xzOKH6_`IW94cLt(YSbrr zBog%j-beRIX7fYb(WpNAL(eyU<3;EM^wKn2Hd=gygLR10hkGZi;8bF zbWVZhZN9&LsNrD~N8ORj)sGvh_jVvIm4r6eJQ%y$L&o>8F!<#)M4RG;1ZnizZ2deT zQw12OLL}n+RGO26ce-=*?PI2NN0BOZS8M zC6N3dxdFVT8NN6B8@-A_aSs9rvYXnnHv?NYTS20at^55f0iVfL#zy)Yx=4e~&hLyz z4&+p@KRmNb7@iiTL1s|9(T0en1rWQIAR}?Qo`%$uH9D-h5|J6LR$I$~d;QDDWsUz` z0$B8QAoL{WL-Q86K8v&&8Tu=T*~60#E^gP8`wD5*U+wf#Yx?+FKY<+d!WCG$npQUtW_Qs(-W)x2&GMVk_moXFS?(&~d#@Cta9v zM5Yd~h?pIlN|VCRM`&ABUd21$5TSa!IZ5$1Nr|wa@^z;Y4>8*L$_fzV5WaX!v4)8; z;5(z}L*LSO=%8F}a!3kZ=*JOCpF=+QIy;G$LZ^f&>rR%DX_WfF3$%DMyXIma7o?0Z z&)M7F<0TxU;mIK2IKVgKJgd3oABUQm?#Cr5M8R+$F#hG3Vk=n|JX7~i42Gn8#UO}K z%uwNPQ9Z3{onUy@b^|zO&sWlEN>OOabs?q5)}PL@d6pA0nV=4{i0Z*~`EG_&dK8WU zW?f_a7aez)hA}!dG(5=jqK86|m+K!i_2X~<3taQS)GnJJ@>C(u4R6A$DAZy}hj!Yk zkK@VS4Fm++6q!s%1IP@j?uJ3Ei?XS~losRAqrrg3aBskf1c-o*B?Vc`5{F*5`?|A9 zU?{_12b(!@l)2+8Mt!)y-LcyhO2|Y#IfGQB)*7>w}pOAq?bn%A~*8hMta8soiry20z-8W%{P+(n}?sfYh4&h zJc=O@Ew@Q;Dr?WS#EMuO_cU(r_BQhwz74*m`2GCFH~LmXEKPk-02{?L+1Cn}628Bn>2mL3s(H_g^Ql z_1No)uWQ^`1aY4ixIkxA?u|?jKflsDL7vE6pD)W3kOvrNK|S>^s;{LjMgecw!|){h z>Ao|0DfJ=B^=lMrD1n}{N@B}9%B_L}>e#AWT0>k$cvgf7SZE-JWiiZ1yzjCYsoLU$ zx+!G?3E$b%>91AWZkV|~(*OR$Nv950Vx?oWy(d=~Q<{S}#6-3+qaoNJ8do6z(yg!RS*KD+L_EOyHM{vu6 zbRD9TwIqKBscBF-{A1MhntJg`6+)o(Ol7&_z+St3<@9y*H~sg{Tn1cYO;F@{UmMM# zG9~!6XJ6V23{Y@p%C|M!i||xLP)vv>i+_((hltVQd=RxE4!(Jw`rG4%x%!j}tuQRn zCqLCCvu0Dw~T zpBBJMFcoh9_iuYVkG)w2Q-ap>g>k?=_dY^GTa}^qbppz?v8fZg z{7e5pHUQ@#OT7)Zh9;8fiOodH{);snHQ~kCBp1q9gDhS)jeFo7POs={sqb6b8_I#T zCMSoSoHIMkAO+IcT&{<7zmZ>^SZ3?5=~%R3xQTu+c(9uWRBEaIJhJxO_vi8hK8M%D&VZbVb&0ry~h` z*98ewyRe1NaLcOhb*2Jx5HVljXF#40FE9DToW6{Fa(pYRB%#*MLDS2|B+q*i20swyw71EliiWy^GoiebC zGvZPU8>!I~EDyf1B?ieI`on$-onNnBHSd+_%ctszm)SU47ijibU^}s9mU)zaD0cBN z(!bMv82#zh_dVhldDhf&!$*_p=0|3yki+#P&m#@+#xPAZRUX3ktFXc)PdXz8bA=kN zxsom>0O5B}eLKr;9o%*WXF7D=aBQCWWi1p9 zFt(?E`2~RCOj?0R>H?Z9Lry#?3t2i~+=#L3O7T~Ptt#&>54rbuUth?!_bnr(i#g(J zcE%Co%dw`9Cw{y)#D_tQLP;A$ebJ+R-w+$vCx*3})Lh_Dkl1#OaaAqp;8 z&vHg0G0I+3J_WSrehMP|!Go=eG9~VMf6KUTnfxg6x@XUt=_HSWnX1X%dh2>y?J|D4 zC_8-BEo#qu)5IN-fCRn5LUr$Cq_Plh2SL}t17u0UIaRd;_O75KSYwUczuM|R6M|>G z$Syhht6HAvp02S!!hu$kYE3<9GUyGQX^^eQ!!KGP+c-8iUQyO;?ep>J1KJ_%Ye|fT zrNX}MoQxfK{)waf4qfDy>Aq-OsQtWGH14TEjTqC!6YC+8-E{yOiAQT*5so63wYg^Z zigLbfy^{W?Q1}vUmTPJ)ZkOMAvtzpS2A_L%RPUHJHl5zl@M}f(na#E;C?@ zG9A}gKMT-Lt!_Emrs2uQh+0=0Ni<@T_cZu@W5ZcF~=C!}vK!81@bw!WBxm^-hV2=E;Z^ zlG{@zxT2z+XOM{qVEV3ALuU(4f+E7uta93~H$XUfX_?wb%UKCir*?9Vs;s zxW8VAl{*hzg8PRp4#?syxh)dk|GF*?X?}lh|7<~5 z6DJh9?M46$-;cWg2_hMr)r!gU8BYH4qhSp_#Xo~i3)SlP7^;ne%S3|(elu$>h$=;bZ(dC{#|DZVAwOgHSXEh1^{{%O6Aa{sN)Sd+ z202&L-yqln&ET_y75wE6x-8&b_v?hcDx2Tl*)HC;UmtDax#oeyn zzG?3BzNO2&^>{RvD{VlZ(g9A7s(PX|$(M$hp%KrXT*fE;$&f)d21f$WU~Khz07*K{ zSMu8d@#89_+_wANnQb*glZl7+8I$_oe(l|b)SGp)&!2TPis#zkg57HJ=_d2wcRTF@ zbegMRkn-hOG?tR6;#P)9eq`Z89v~p-7IzH1{ zLQM(Ywf@cE5LMYGt^pa!RmUDjSG4=ND-Mh1x4Cu~4Gdj{GJ*#78c!$T}^EB$BPoC`hdI=`_mlSNx3)N z^XxWiC3TW21COE|rc^GmN=#kYan4APbzUF?#BiA75b40yMm!Z6w3(Q(N3`EY0?0?p z0IBt=k!Po;sXRQ#*BuR50EA2tuAISSXLJji5VOK+kza_`2TW!QVqD(*r*m_5QF(NR zQS_K~N^G<;1P6mcH|Yw4S3a4xMXx8Zmi_#ZzB&;3Z={Ni!^^N>A%aYZoYUw-w2G1^ z(m6<+Kl|mgg@sa>m)VLY3-48(&!ub6Z@T~X(;Nm+ufUmi-1@8e9a7U@y3A>cndO5H zGJ$-Pem4;CpHT|RQ3o`fcJ0K_-fM@J14qBoFPdfpjhKZ)plpqN1fS++ug4vH@&S zEeGjE7Q=;!OMqY3A3OgnPhUmo+fX}ZOWK>#n~Fp#$Ww!@%ho(T0VItDtpG zJ&7atX1m>Y3xGIe5-;?@m^pLllCMHXsUK;0Q?l>ePC}|w43jKIR7*Oe2cmv%Ogm3 zeiW8hQj(Yrf5_OK9@&Xioj_pw<>J}NKl39U8r%LgL^&}fB<5(2{lxyUkvBLI<1mUd zIpKdQ(@E-3$iE@R#KK|9Dy~@irhhqwynHeC1x(^AwT9P<*cmJncSj9~>G94mQ><&f z6=$0aakh>y7Y&#FPB?hjb5ujFF+~9^`QfI7E2n_uR7KYa`Mdk~b0gkS_S#{4;bTWN zC}Ck~o+@I)lhNrDN8sV@Yx4K6i3^w}6QW-BQ61qZP$7x{=vp*U6d@vda6Hhc*fUIo zAtFFDM|cvypq;Nj;QE5VssJa_vl*xVJ^Vj5{udknKW0icuvnHv|MP`laS|9Po7e#g zp9%C(2)m>}aT05|SKq=BFUff(=de%JPk@Z1qC};bk^iSgC@%mIr1AgO2nBvV1^mA? zLT}yYp8uy2`ag}(|7nE&Pb2jIyGH0~#}_bxc?$RYt;?ifiaZ-{3(y!6LKH3ut~^){ zI$B*(Q}n?Rd)nc{(|fbD?EJWLvvTqMqph;7Or}{BSyTiKQyCSFw;%9@0s=@nOu_#7 z+hR)Q(Z_{HSy^jqQBhH8Tj@zf>4AbxY3s3I=D`Ee=%@xQE&dSyI19@Y3(S-sW^IjMDYG%ej1D`KI ze-SmbugX9=@PY|T>D1(;CK;)0_bbiQIl1DpGAsvsC;71?uo!73Ob20QoeLGpug_zrx6Xa9@R~ zfhmXV2u@SIJw<@8<997fa<}tjB=E`&aI)^ABB;gCzyeGFT5UtO!3-)CP*Nlq0vOcg zwc~W?lPE3Xjii$j^@}TB13+LF;r@llFPmPP7wVHug7s@gq5rH4c`&9YN*R5J7CBhS zVYe@EN^D{k7Xf7_n>Sa}!v&)HwP1o#*~lpnfc{{9C^MXHLIch_Lf4l%ah3p$!n|~( zTmTP4VCyf0)*tb`l9nqY(~O%t0bm@A-MGb`BRi-O`p+Ho=l7&V*0qO`0&@ZVEVDu8 zq9hV<@tOd!zR(ytI5=Pe=_eTp+Zu7oDviQz02V8AzS3n9cyPE_aoOU3koEo_$f2yP z|3StgW9b5BJD*LZG>WC~Y09IaLemuDGTR{lNkxo&ph=+Q;lljEB+7(9HbiAYpU&W@ z(zj(wD^dDcl`$9_x) zC<%d1FA{-Z{Z$J^P9OeD`agLHI0SC7A`+5M>tqG&fh4+ zK9gb!2?7^picvZ+(*#N)g-NRK$w38>Zb~U6C?!HyIS7_@$t2HiU}ZhMx14mQPloGF zN1FfS^1nDOGv>u4)fKPSr=s-OMQ6EU`gC$8nQ{hjie91%nc8oXb`ttvC%@57+OHJOOlbq&{@HUYV z4Z;n*xA}&FWSb*r-XQh>wwgG4mr>s%gbXVixnwg?S0hN3(8U@*=MKe{UzO(6jG&hg zw*+q%18j3pCA0oBoqy)(0PfHReEDpA08hCDhh)*>+?YeNkd7I8IDhA_oNiCKOw2Xb zy$@?fgAOZIwt6Fm{Uf29_~EYRpVeOfHAEyIp~;DDeX{Op^OK(pQnqG~Emzhkuf z?_K^`C?PfCOEuh=c<*q2(NcA;3lp`8{tP4$KL}FMI~*4!J}y}L#Q9zdP5`KOs2P9T zOB6Vf)+ZY)OhirPs|k*V|1&mIoKv}fZ?0%9{{?cMGt#yMFF5VDNl=#ZB_uHBP6vu5fIjTU;F=-nQA@%pUgxEnIWJM8Y&&A_{QfS zuc-cUO#>lJ3>hZTA5DxEj5a9kU7#t9tJgbcz*9@Y1tE)|oTYvwZE}8FsCqaz?68;MK{Eu+V zIcO!jsW>?h$iT@V-Qzpa^q_Ak9ja66IfC*`2t`mEo$gBnJtlt8I#4ncXxlan!1)-Y z5^yf4kQ0j-mrr3^Ah{zNL@?+`SPBk-;g%_90x$^iOo5KQ76F}92LGYXT}Aez09Cnk<`@zOnmB^$r^ta7Em<}n zKgwAsrAl&Af&}-?o3#IDL|)UF^V4>SK6cL~Kg%Fl5-@EK9Fjq+W{6C+V}||^Do&1r z5IMnJzwFos%86X9bdZdoMz9{lQ(16tNF9qf*N#=LIUo)jWT6zVY7&(@z4*UqhVCzq ze=i~-PC%t;wV~#6Pyy`YsAO{G$}#?`XdNsX7xl6fvnfNuH(3Xf;#- zaBmS{kP}LvDZQ%oOG<7y6HFS(v%F z(C|IBqj6^l>nfXkDxj38Gzb}*q^a}}TzjpE05E+?y4Oy)kow(q6oQv1u3_o7n4pjr zFON`dKAhl8qyg4Nu$Df4gOM$TMdt=;d9d}4bue_=_QAkWzpaa#2RWs z>AzLtB6yd!51_qUONAbt>X!HTdlHk|*lvc$+Wh$4KJ27xxltgKKIH1VcZh7HRk@d-k{ z>z7o3kvQnwV~&A*p07F{c9S^b$^_M-@5_aznpUg5>)RBFeiHDCQ*e+ByC=0A91=~- zsR)GRnBvxl*o5FvL2eVE9z1Z_me|{$Xaz8IgUlKk-n}w_mbx>2ITZ{7Hg=;Y28Y}s zaA7O}GI(P^rKa(3(lIVI+zI(<-VdjKf{Mwnf^&e$9aK1YUWtGr4ZSU7GTpvKuV1liBUb=ab2I25tz*9E=f!I&+emOh~kk{ zS}4G3?VC3q!;Jrns)z^BE;J}apZQCu_#a#x#o~Vb!{$eQ%ekX3$WF=^++>&9fJ1?T ztp+A07TwSq^6l8jvBtFGr79P<-8EM7$9TCcT(QZtmR+fWuOOTjFZL$OE_lkx|3?+# zGLTel086Yo2o*$1P1R|Z@Wv8L19W0LBJsHc1r)THF9mj;IEps?%~=bgN^4MJCPa?_ zF(P1tA30 zF_MSY{8!1|u_!W<>)nb(+s_BHE zpb&2!iYQ{G62@eF^vDOO>s#TOdZ>dn4M>@DAY?3 z0J_~}Hs>iqIPH%Y!&tz6v4{XvBtnyBn0h@1F*Cj@|Be0jD+#guvunNt zv>SZ?sw7$4YEW3(=f>CC8pSuif~lA4Vz8Y2&N?+XJ5=lw=cV~o;&~8@#hdUDk|?SR zhVYN5gQ4Q(xaA6q?@P<}UpvfCRrX;~6G0646Vjk;qt(bW61Rr|mc*TnmM>DFUx?Jk zWWc*un~4#Z-!)aJ*^$gY>|fHAFixo%*w}gm#543W+S25f^00TQeqm%nD)F-SL+hPb z|60Q?;pyqAppJv@aoRfSt5(B~tXimsh1G&uv1a> zQZuW0ae}0FXv52Q{UwU&Q_l}B&&@yPUAsv4$O^hbfPYU8%8Xr(OZdD`3Pt>{Cu&yw zE85Gl?_Z##^_m%oEEp80hLRYd^=9@>7G^nVx_i@uc2Y)dN_WUPncY-Y?Rd3H0IoFn zTl@T5hs-ArH^)V*kL?u|-$De_ze+FPXBB$tsId&DCjNZ&gSc8WM@7_X+^do5GMa1U&t>F+2YHgeeqL4}gfKw|P zv$+&f=giu4N#jG}7@;u#D-D$*x$D2Q*o)n(Xi$NAA_M2xNNJ~*RG6$5Dsu_Wo?b@=d&g;j=h=;^ z$Tj$JuPc87UsY7f_(hwYwO=G64FfD4!-{M=d$K8t4JA}U#Q$w1ccc;%b3BZFfFi)H z0hsQ*h3fRdCRZf@QH*@@<^*1-f#M^{sLG}!fm@FLi3Z1`kMQ#w+5j|=1TEDA0Gx}I z9P|ap*3PalDfqC@WA_!`L~y``>0Z31s&;MB?fI z3vKd<-v%_UtE~t7rDR=FYfsI!lQ9FY%H|eqN?DhL3e!Cl4K~EZ4}2M@>wO|iD7Nbv2*bLqC8XvJ4x7Dw7t=k6v+z!?+5TXaY4dckrg ze!Y-@8G=RcCx`d)gj|Zy$Aok-Unq@-JK)p1OnzJdhxq&pos7rO5dN(2P=RX&Do8P% ztRLCR3j5$@qGji9wYeaw2yfD^?cCh zM1xKPLwc&cJjI-$uu~QYI0TB=i78;WLj#Ggmp3`=MR^A&jqz`5DX1!=F%Z(=c(aN} z)Xg&J2|TzvF-_2<6{PLA{==r%u~9g=5>biRtGN)@+9J;`O3XBHkuG2Hg?4k1cxxusA((qv1Vpv zlNCoRQVGB1<9m@@Ls$6%G;bV?nHz9;GP(EbqoAD{c4e=G%yJa4@jGb5Di}*{@;rVB zA(6&!wOJil0BA8O_@3%0;8EG$$?l7zb-W zqPT^ft84W2$(r1X&+6KWa$x6+^7i&9KWy@XUDE*SkwerY3M$uuTA-1q3a`}mbmTyR7s=Hq=i9ff_gf;sX`Qa0H-ILfpnbf>!@>>WwBuU{=VH}vo{Ck z<;~XDThYb7-F~Tp8}W>ble|169_YpPi>SytF*s8~g6hQW5B@wvLye{0#H1wrfgZiH zLJBWTQEq1ZUXL+`7 z$A}q)l4P{@_eBX-ouZ1 zO}vf^-1_C)i%zW1P-f2zgu!Ec)P>ywP+b6K%D)Uc#}zDtPNHU|i}6!sSg zDJLF{16k`;_a_c6U!-)Z2bm|hkfj#9!lA!S1kTy=z(A_?Oc2agMXKfV z2R15A9500oN#t(~hZ!2LC{v3Hc%+3h(WJa0>+8swsz3x_9lViUjFG*VHZZuPd8r~X zF`i{3KXgCsHLikd*!6of5l@JRj>pKVpK8AMJeq#B#c z;)pnmL(avvs9BDSJ}kL!yrGD9PpQFa?UVQu}RzI%D)Me7H#M?F^szDybBXPL8(d41I#hZT&W@-Q-l* zM-?KQ)?L3HdT`tC31%H7;5aCk42B2SmN$7H_PpEuEc7@$-<{}7izy0AFJZuFohdYW zD^+3nvnEg?J1gqLUSZT^)>{YLl{U}I^sS__>j?Cw-rID;E;+`ncN^c4U;R+1m?CH@ zs^j7MN-!@WaYN0m$Y|?-(74EqUNZ0sLiX|;0&aO!p=(vy{qWOn=N6hry{U-*vD#d~ zwMxk!6FKf%PWky9XdSswM`DnWB+b}5FVkBEGS034>^H*3hKB>!|H7q-j+w4lmMg{q z!%!!eqNU{lqeDYsS}h%4*4WNusIu#t&Bg{TMz{t36olEX#2oCcocLmQo*+@G=}>YE zx{}Q=S|*jSik(L_?(Z1x?^&uq38`8nHybxBs+MCd#|pj|uK^uQ?5YY3$vdv|%d5(I zh=XNCmhvO%KMCRXZ2YBnvG%=wGZwog*{;8~tP<6^%hAaELWldKWo*R8_;Y1p_ro?_Y z8vN%e-cG5wo>d*@$&6N3-eApD_e;%>OA^{=ee=fBT)iucRJUE=7A zpPA?@N@H}BN&JH2t!RcZtAg0MQi?tyxlD{XjcfW3&=|Nas2A|H2oT*<|G|`5-k5G9 zFBlt-$DBG4GSO0W)}?66`kQUg)6v~2RyN1u^1!@yVASKl5qSUP|L>5uoJMg@w!o#8u0-LFM`^BoabqMNpVUy_%(1RZqS z9!<(kcf;L}(xBsr0#+V4*8_V;s|j4QS-OT1=+7}4C((?A4O@W%MSs4$bj!{zzp-^- zn8qhLzS2EyFBx%p?rEY6a%VV02c=OJEP^y8I8#IYG9bhphVoJ3xEa6Zrn{fVWd*k` zo2UE4f)OPcSgw-Dbe+|j16Nc&GOyH!cYuKYLq)^u2m`zeP*CRIDt7vHQ z93r81S+)A1?u=i);tVN#ESckVbn4vXTwLOl%)k9(IzcS<9MOv82j9MUK9zBdZTfhR z?Xk_k=9>eRW<6Ygt-`YP)B*PCD_Hn=54j)(U6T01u$PVwE3y^o5gr#eCqLXdefo2@3>yieDMb-{U*Y^bHszBpN}2m`dQrqT`xX0d(^i zm_SJ)7v#nteh++;PkY{q%70j1W0jP>$1V@VM60MAtu63pZ`#n%zy-tQsP@_jqCx9o zUz0!(}T9Ofm3*2C7-~?CS z&!Dmo|7~1PGL=^2wre=AwnfymoL7G65x%>ALSKv9zDnWY68wR_AQCg}ME4Wkj>+-# zC?}qU`^<&qkJi&jA+8(=>^1QSf3g7Uq269Ks7{L^%HIFX7k&(!oz<<-9+E;5#-JMQ zC|g%}A1a=J3(?5LQUaE9^(W_0tqXukSez{bMOM7#jV~vpl6>;=UT$O+&rSWEl~Y>_ zac;8vbZ2rLD$WHeq9CHB={|z|Qh|E${LvQz>-{+W8Ye%%_LRbLHdKSZkyO#rljJs*#_(SBoDQxY2ZTpI*PlAtYwE?Td6r#6< z*pp7)%M!(XNHdFFB<(Nnla+qI3sfI_gP)p9D%Ez^U&)3`7^FmZ;Qr99i)g9l9xu)- z@^viy*Vt|A7R|{PwpDxKPcGx8OIx(%)*(+f<9ctu!^iy0mr|2_-fWEo!N1Tn)3eO) z@|Kphjy!CGY`X456xXyuk?sxW?PD6g5K4e!S))|g#$*hU{GM*$w*!}hRZr1aB9~_4 z@S!z`^H?b(T3f+3_uL{kHXfoa-?QPHb z7;Zc2IoHBgA(vkDH?zBf^6yya=fHB8TXW&v$1$du(KSq>)NUhTc>j~hBX7qU@l`6i zb!QWWbs(n+*dA!M`2)?&YVt4&W`FFc@h3qD++w6E4hwk9UMqTrC)Kv1AHuwayuiY? z+h~hjTZCCze4+WeKHO-%LedCC^;uB}oD%=0-G;-d><+AqO&jbw%q-8!_-I zh7Q{2>kU1aa$*uwp_r&(DAM=HKy^U<-b;>tpou=l5nW|njn8yJ4iN zk*dshKU;peNWf?jfraMfuUd*?gzMYrv5%KzF)G)vb2B%A#RRb9`HC55__Z(oTvYNl z+=RB-t|Ah}!1K?y%H6$}#LFz7J%q>UNOe+^50T+h!uGy*)N-N8t>-Z2PZ2bUglb;; z@gYqdVjxc#L4?W{>m?tLpaRdQK~y&#QzgEnQ#gt%?U4Z@jc?H#+Q z?l0>m+6|CleSl3cFc+7TwJninOoq%5D9hNtpXK0k7IDa}B4*sgy0zSQP9I@LtGuZt z%TX)%L-((Og{b&UF4i_}jAd8ujt$G~J7x@|vlU36`2l7Gjsi`U!!oO?%^RM?X>vKn zQd>uh&`J>|cT$_6_pWc4Zs6!YY0yvJe69?MuRq#^pwUj&WZ0Pl*CVHD9PFYrK7!qR zr#f(uQIn4C=KDI}DK99#j0f#-h%jEobB}AeA>soR1L+p?_wMC4SP0~Jbuq=09&{kW z=N9)(ZJ!BlWoF)ZKa`5qGfXqj)2-S7*zso4{cC(YMvajoH1IKn^cTzya)d&@Yv}17 z1Hn*GoFwZcpOFMcQ+)0HL}f;$7PYFNdlTdrbP;zsho5*skdBDtUq<0IO^`$aO1U*j zxK;f~gJ)<`5+l6@445d;gWXut3v{-&g-e|w7j|8&J)%g3nA9#oHpm)}&~;j8c8iq7>)H_yRaN5geE3p8FZ9~ z_4oHPai^6=mg+QSPUTmN@)f^CLVs6QQmmFi+WVH0cOHEl)rEa+Id0eFmSltMjv0s0xrxAudix~|iE43rlk zG#)>`hPmOqmklXiWPD1Ad)XX73J)g|eeT6hryE1VnUDpRL%k5^N8z9l!Nbt+WmR#J zbsg26ohyin=NzW89FD(>(m@uD)E_ZJgspz<{@R?K;hI}^ z7++t)IA+^x-5vAZq8uW8-%f~5@zv()J=zW2Fuy^)=mru3LPliM2uo@gonZoV{j;`h z$p-QO6PPTRC z4)KvrC*Fd;XTtryw}tZI%iU`=Km0AA!3EXuz9^+ zjwmVbjMVj<8L0r#5-aP<9HT9-<{2U|sj)YlRm%HBxN}1a_!#ChPg)1nSb5Z*ZsU>Z zrxKXXWFA@kh`l<(gZLn}C4d%cBRCq!ToRge6u7^Al$X-+x2{hsM^g{In$&MxGukBF z&x;3RV+3iNEnR>EbHnL!MjLyT;M`tGRE)iL?&`*yE>K7G^tCoS*3}M@9^#l{{A4TFOaE^^+7cx8Dk4G;u z+Or&^xP0DHjC22W56x4)j*z6-NO*490!FoFxcSLeN)w=it(gH5<4Ef)7JFUaU~8{Z zmYo*}0=+|uxBS_utGJ_#YF==mPB_d@e$$f~Old9vikHZxeZN8JRB_F_?WKu^JKFF& zZ;9#Z^|>XPp!)t%k7QhCmT(a!v-Y>#&nYDMbAK$$6Aj&x_$u&|n%IhcGt~543dc19 z(S8-CZF|OsaIF$?*8BZE0*tDE?~eL+d_aV48lfS`BRu_3-zr15CJAv=Ke`eEjjkftAZ)wlf6-bEZ^Nf-hvE#)N#fWX0^%vP8lk*l?qV@%CHBCvfNj18Z{+4dR$;5V4Agio7u4Bn!W``?p3#amp zFqTW!G52>0k&^%$$i2~bnhe}z%T3C^wPn8SpJebuUP63CPxqp?#tOnz+CFBb*Oq`2 zzp5-G z#(!ttYZ5n!hA@NJ;Ms=66K5ySJWa2BQLMN-BHrj+D61Baz6nZVV(b>3ndoxk< zqD#3}^uZnDQ6iPtpAAFj{9mIv45ZW_iYB0tArIw~LRR|sovJ^VNTTEhIua&`43V$a zhy;6+tT}|e`BYN4{Vp~6r3Viut0+WCEsn3;%i_-78}~Dv!1+S7iE#Vn_0YjU9nk|a z()};P-Qt+6b1a3Xi60$#rFbIHS%a{;PitKZG$Ks`cXm_5-%eCtxu_s^0)S1o{eDev zs%L4w;n^X=-3{4y1`l|xrO#Cx8|G`#T2g?npA^Z_`oCDIo!4`GhSfe{$qR>${d5@YiaP8q8KrtOeOs_bIGM zYibrJB$+6-BlRrDg2?vU2UzmP4^wSrW%F8wKbgI&-!W?zMUn!mIO7STc!I{G$fAr} zN$~4A84eoN&3e|B)>QEqN+#8~b`)juPnPctCYF`rh}grYwi=D-qxrrpV&~oYn7Ccg z!WP(#I^xswyefn?Tx3R5)EXME;YpJmyg?yEUxh)YIhLk6K!_g+l+^}NK@r{Z6(xU? zjDUn?;+xI-&qbDAXv!B<&;VYrx5>hVqyO=!s`8nS$oP-lyiW68zW%@J68t%_S$*@Z zwxsC$nNS+H9XpregPI4Ite(0M{DGm~eABD>#{J{=a?F(W-aoR8Wqad@8-4f9EWeR&pg@p~JI!W(4EmI`xt7~~W3JzFZ9Zu?1#`t1| zcXH{RbTINzhA3CiJ^rm=WQt)*8A9VUg={^PiQdV13>$l!MKT027J|d+;z*;Xd8o2h8s-@G~*(!&I)`UX73qJwa z`05t<$sUk~4V1urL zyvUmqtc26uZ_i<$UzaqK2gkFT zY1oq@9=Iobe^hy?T9#YOlcft>H-}Q?UiJvGmFg{=J25}+l6e~@?}w!KMj&(rUw`4EUx;nlf%;P!!S7w<(X& z#Q`*2wp^siUa$bv$HRQ@@TrA3q&ItBf&ysF9I~5cb$CI2x9tPaq9E1qa4R<7AKlrzLyHuGubqAO)1%HOe;5koQkD zce%=EIE%|?+`csen4%27`T+ijYj1h}$KGi}gJpRNa^zjH{U|TURmVQ0L8J0~^{jm5 zUgUbO`sse_f=}rzo()y8D4{tlHpmO4^rAwqs!3|SHzz~#9V;V9voO#tiSXa&@+0yL zFp&5|-cX74c*lb*IyirGLUQPoE?Kb+Oy2pVbzggX>T{J-Ls_ix4RHkm%trM0*Zbrb z&hl=z@bNiUu%~}5yrX*!>)1bU;#>ZD>v=Iij`B`R;5VWiZQ8A}CE-uQBsae6@qMEP z^WrokOKz-oyo>IL0V8a-TTM*mfY2EuljTl1kw2Ibsqe&%J(6D}5&*olq$ipozaiH4 zPWqcHs}pLfil6=7pAUcPc9_p5q77hx$|=VXmR-R*{T0{A6ge2b?fCmRrrvX57rsc3 ze#|KM28<&ue0+~~fww@4^L9RZ+i6_5`}bQzUE{!}q3n?_t9^i%86_O;dto(q4}(b9 zdgjTPY5@E4Xam%!vmT_Jmaz*fC(Y6B-=K9WXLUfYo^ANfDK&IxVQ%y2RxIpvC%c`E z?eAYPjE`lS8U%hV+Sf#kzqfIP8K0-G-^BRp*wx?ylnwc4D zczzW}sJkyc$~~XHKZqLIZL#0?Q&ZOI5W?umvZKqUoCfBv7~%I7cR1D8-*O?T%0Qrzou$NrnhAT zY!?vg0=QTT=zO2`?AyXLyGNIC3j_)KdO4m# zLuAxX@{l`yU(R_;iPWJ71f?{i;aH(~P4n}PTiB?KXp0TO-AVvIf=I-7dDRe!F9hPX zV*7#^FsH4-gVn#x?E$9>V*OjczaazOtbQ2cNs^wO0EnK-d)Y?@sjQzw$>%d3Vixth zqs{A0@ZzU2e6REM+>GWU=sVwvU;Ewknen_i;QQ%UgVs=;SBb{^MlED6EuZ=ec;`MREx`79b53x3OV+9z+jto)~b|+Jl{be6#C)LxdLK zEbOyvQkLKqdpCW@hm9oM?UWtSt!aQB3FOhJ@23u*%lAyzNivt?JR?ALlLxlK0mlm^ zqpH`g5nmt!nWFj=9r1?Lf`hSWbto82+Vbz)ZYs0|FqQXgf8jt?>EDHaRfWm&8R)!Q z_1|b0ws9SvtCr1SO5rX)HR4IozlYNy&$`3nXub~A4_DWANFsH1%9sv4H%0<|G^sGp znG;O*Dj4(h^7imdUAnf3uF|b^G*EN#^8RS+gMIw>H@ch!Pe*RP1xq&k-S|v+TZ*`& zf{pEZmnr|n_CadCYE`Ve%Eey$WSAl6VQ&!x+xUUD4mLQ$rvtU=0b9JA!u@s2YA(nV z`MkHH^;_;`51(HZrT|1<3^haWXOc>wWVH`@RRlAfu*&7%fXd%qgv;*ZY_g&s?&xc_ zR^adp77RlG-qpgC4l3RJ&}_lyp$urxj|{b#!#NGajuhZL^eCiQdW2%Awy!uX|W$t$vtM*D^Id ziG3n-?vS|KJ^!q+6U+>)0kEALMSbAm;#JB%dGucNT>tR-9FhWV$D>5oolk;GH}-9U9X=(O58$MxilHYdQ0k$s54O8F z`X*mH-o0(wG>ZJ5STZv)r6Qk0${&Nz%P4zq+v44wbvm%0(bUyiovVRP)UMKIfeb?= zOQ9n&-R%Ybz7(tE2!HIfd86NUKmN4P;4>QCk2vlhsH&~ZM>RQ#dkfnPl|roWaqCHt zE*e17|M>Ur#8~b;X&-vOz9*M!AVgX zWn4O*P`suLxB358i3PrO>bN!_hj7Qrc3PQi4C+5*~X! z`~Qt$w4KjxC(LJVf@=lS*3%zm+Cvmq9iupi;QAy>QXAq`8hE4aa?(*IK%AF{>hd3L z6==**11P4Wk}ltqJ{(|A2SEZ>O}kxeGx`}AT#ahJU99pbc|>`zmmbtUo+O`XKYZBo z?v{FN#RvG#)y8-0#Fg`Hr0kU(Ew@LREZ)~wK@ine>}ScUuj~P$teYRL6!#GsQAU&P z%r;NEUd_0>hI`f#+kyr<>q~#i>&;ll;f#4Th%C=rbEuDXj_VOQu(=Q5RXDzMd(Q0l zxVPeMx#G?jenRzqY5VcYmoWa@1%)mx6J%m6g@5C~(Da%3uhH^GjySPs?az#F`xVweZr4^0W19a{zu0V*4*AcEq^E1Lm5T^%b7R7HxpvcRrfJC^`{F*IlyH>_eah1c z%}biH8YUZW+R$&~L?Nl6T5I4*qz>UQUw#gw45;N;?u@Sv&JR5HwkHWi&m|4E>iuCC zB94CT8N5!6-CnxA+%Vp64?U(Z;rmmYE1ETF_r%Ma>${!;(UO6_8YHq z-}j`^2WuidY-HueH_zE7uJc}4&;;3TimLB`TbT^RjSWO9{p@tq`~3QZ-IFN0Zf{q} zi^Dp*U_r)9{mbm+?vHPd72|tpPRodmLrctpb#Ev8OrKAGa+EK$^w>N9jHIlG4@r4c zB~@b0<94ANO2t!~PO*$k-{&!lc=BPmi$$CfbU!KSayc&7{ln>b z*iP_V^jr6@*x8-_M9&JyFvUL7kKKkBfK->!jB;v$JSKo|LRDm{qQ)4`L~WvA@sg$K z4kwiPQs92DLY_2IAm8SwVM2H7Zehj>1(WW<@)Pz8@nb4}yiOZCx` z44;IppOlFz?QLzjx2n7PC$IARJz{b`1YK+DKCr-FR*gTc*vu>jm#V+IdHJiK>+NWh z8pB+CLT1p@Laots(DgkcXSs-AZru@(SB3BfC_QAhYUWMLoR+*vV!2#IOYH6}bHn`~ z*cQ@4Lxtv@wuZ#?rWG1w%3BD&ng zTjs|Px)6O6CFTPk*7ozeF7HWt!i=Ptg+x!UzNB9T%mAsna7IG+A}>ZEc@yBF||=pMUhO;@t}8 zM{&gY3&()W3f0fTFp#t`a-V@)7KL@_flBL^h28l!$5MOPrz3&!7Y&+{!4%U$6-wq8 zH0Vz|ktp}Skcp>Kl7!cn!o~dWgYUYZh_A3QnA%b>Gw9}^XY(X{240RH0eMj9-I%wF ztIXp6>@EcHS15-#ZVqbGVF|06e;#V8N(v_&T$$?=YdaBTz5cT3#mgaCjZG>{rzWR} z>R*E8n%kqzPYET)>YtB6hE;V$o#GM$K(LiJCsKPiQhO%{A_eIOzSNhQv?j=~&~D(a zSNB2V^xha*ZDF>{J-g>^?&r!0Tf8 zUAe1vuhi?lXpov>BmHX^oI2D;d5AU9ePx-L+1JVZ5!jy>x^}9R)uGgvT&89qx7Wrk zAK67ugxen5FfXScPI?db8#*@nB-rwAf8Ba$mk z;hXBZ!iIf-ef98*GP!RB-#&@ne^NA>^xV3dpI%tVm=el1;Jlk*Tr|Rc8)Y-wKENln z%zEd{3@(K=e|-B#%w%95ZGB%9fJlUp1COh}+4l5=)J+Wh^z_6_Ibo=ib|DuDBDxl4 zA6xUuq~Pm1Cg(+xY2D6zcBHU7O!)!;hy(uB2+fr>>Zo?G@fWJrZ;D-Yf4cKPCLIaG z68L4@NO9YRwN=yY2j^QKU3g#a224zNYsibe`I!kW1s$F&b#N|nAM=gclAbdsF}vE} zry+?#du@C66m4cQ)wVOyx3?a)lD2)a%ciz$u5!K~EGRT%sRJ6(fpuhG^=IJO+EAU$ zKk>4U=dl3XfKDo+t&RJO;s;7(ef=64C*>V*Ra8&7^~S(S>cjwE=UEJovPCh4D4$_W zK!9!&EvCB^gPG6!pJD7oIpLVFW^ zSTYM{J}f3QJ;wCMGSX3f5^&71?4ibXv$(9e<1!ho&r{vzLTui>YsVg&0Kavtt5Rm!QoD2Rc8+H4uD=5+ zbqJZt_^t~7&A9iKd%Q@HN5d&&FI`+JMK&p4`O(u>2_NTn8Pe+Z^&Okug6x%E^KzFf z@U`jp<*P#*zJ1^A8&=c%H;?d*sMiN_OPkwuokf-XttIDZ%cKJhXKmR=%m75nTl z^gUsE2R)nUa+z-T;r2KpKkv!0d&&%SX29p;0(nyJ@{{sZVDQ>+mOV9o&p2>}TdDO6 zmxIld7M}`wgf_!>E(nz{~J=) zmlGOIYzCjm+^gvclhZ##%+_OT+V}lyiiDB~R^D4lxp zEf?%r<7o&#tTmRkZQ$F)~ob72=N#gOg z0$HYu8St$cG(&Skm++3tb?o=S{uyJQR?3r)ucd<=BYl=nUmE|7GR>zZGa88%DJhQw zr+$4bmDc)1$c}PI<)N>QS}FU}#6vDaHT?1N>A~*#>5*l>pXl<*7tfxFJo`E!s}KK~ z?Ly3?5-C(G*Fx+&D?z}W)E5^tsMw!KCLJ9CPekF6QdVoxNzZGcHF<2Yb47Z1tGd0N zskG-Pdh7N%vrNqQIml`9Y<8D-cGdf8b7)}*%dliRkrdR_Z<4Y_;Th2r;w`+GWbWcP zh1#{UzuYP?5>dhA)ZNv(>3OzPz?thY_Y(jmGNYy%c zEFN&l5wP!_n%i|NMRKX!>d#G>1qcTjk8+Bmv>QIHnn$&YHgBFW<~P1m=Gk+3YL5OX zC2_KvdXf&~0|$pJ6C=a0@`ces?zFJEcb-(gmQDT)3qyo&mTdNTlrH_w_iY?|yTg*5 zaxcPD$2X*@Bt-Z_@6!#BJ!GC{^Y2sN=&9;*VQ_}@1+&8hh@6*GlAg1?PFAajtm|=m zyH$cOy3J?);0C7OTAzpp^C5Rtki+n)xEjMqhJ(*%K{yY-0Kx3Vm5F{y%H;frXM)6; zqk#--Y%C$%U5XH8GTw>yHFs*Kr7mOh%8@5@;^N(;?Vx3bm^eC6!XVwshk+a8v(iYQ zE5%Pe!ajf#=9S0KwBz(=r-i!70{rA}-}Em!pO2zHJoY#jM%FbaoUx+j{(&@BdKB0HXtl+TU}|FYPMi z_p7%DN`*CIXNQo(A{i_fKIg0YYcU>2d{K8D?BrNI={^zl8~!$6Mxz%b;$vJNLc}KW zE90ovkEx69RpmQ(Ig#*K>wzDVzb-f4tz^5jt+?S_-|lzcHYRIN^OK3&C9q3gY=|Mc zM7PD^NOL%@Dk0h$Pjf!=@f6k1M~%EeE{H=GMZaCP3hYIiypSfOLz5NQ(+cH&R2W2#A1m z#|R^cbl1=wD%~K`>JZZ19RkwKNOuk~z{G$2y^H%kzK>@1aqM}p_w2pawXSuZpS9aS zFZlQ*Gk+O~DB677y*Z{Pi2MnV=2S)zgab^>YNeolw;7o~{cgil#1mma*$a7o$?n;uD)6=-;~6y1^b`4A^Y=F^;iIuSuncZNNWZ93(1by-PjeQ}zp(Y*pkB|JU2~XX zb~JI`|CUBi&guPYWNjv~c#)-{n~y!5QQ_*Dj2&)p#2@E?Ft6i<51$vO+CMF(u}~xf zFZHMmvmH+VUWRNZx_~}Nw4#_9Ez0AT2-k-tW>Bz?4-3!o3-EHBnoecb!{tlAS)$9A zg%z{t)xZ~`31IDNQ6{>2h% z1fUX6$GerglR5~ga&tR@Nd+1Fo1$tG*n9VUaeU4`q$lv9OE0B)&`=ahX&0N+$Hizl zv9p5e2=A{m-&Wm538$%)CNQVchQ3dEY)73F!2?6j2a9+BcZWy6d@qokvEE|KCQzMT z7nhOzIeLp~p@JKo#JMMRVtxuXuU{_hj>{f@V{C9LZpUCkUuC8KRprWZu=%vUFxdG^ z#*k}tYtA^*&?%bSWE=k#*C|&-VLmIgL&;fLNAA2zg%#0TiRX3HI=gze%h+VGK3L(r z@Jc2zUmkX~ev2EujE2mM-m#5ZsA3wdPKqgkE*~LE1(C_H5O?!DsTlN4Hk<2ul==duyN~FWCrzCqfAG_5tkUpkHf{AdBVJM3iu=r4$ueTsQ@zv);F(5vZ6{{dO#ln zx)Yv1o?%91uYd3BgZDzK-kww`VKg3>M{-h7-$Ctg1982poPfP@4{1q4KXiimuL4^g zV@YmT2ZD={q}of~ zj-^u7ln!(4f*BXY?`iJc&My!eh5Fyja|#&4U&Rn*Abo#`i+0g@73;>qP46WcQ}RE_ z%KBNbt2z3BPPpyG-gplHdbFS^>(#3MVU}e#qrp4JlcDXD=n2gmPz2TGXP#YcZAM9n zsm=5zW^4z77^wZb8dJ<~#HrugIJywgUT#(4X2<6^%LNQinfr2md}gaj55O@pGG!4y zQUk}vpAxKyfY~>t1q4-9YtHd+tLi?+0 zS9z$wOkp+RiEys@%G_L5(b~_iBqVv8Y0Lda6C>@#Nkft(W``RVd@{W0<4~(_=%soW zm?&hsGL0BGl6yu`cE?Th$hf~rIbB%koK}zF*;eK z9;dmu0*#@i2Al9*W@Trmhr_78wwd2W-g?M@0Y#%Y-KuL@oyq5P*U~G_~t<7`)2V~$7BF2JhI!eUr;uh zcWZegA&&P&o8J;X{le5@UfuZ_#%RDJ-)~CoT*Xl!w^KOSq|{RHk?&OpwWZ(Zb>#f| zl~ar6HMlE7^a>*sJEtFx=eOmi-&(B|(m6pdEa)xwd^nkC{lMXW>AYpFzk4`mY@#ht z(o(Byv~+_ZJVg|t`kjK?hoKEhtiK2VaWwtTNEN7skDfgg8h&W?bvU8MeA1oc@xjN! z1?Q0K*-L?nr1kml+Ym{MB>6|}M;U#5(AFgnGbe5e z8Q04V4AxmSv=OuW_RA1|m;iJ*WuB#3$^n6cf z1Oz1JRsK4B4mHurKq@P?FYtc?n;gEl8l{Rr*6}#qL?;AT!h)4HoIt3^y@@7Ta zuc4(QDe^aB`zzn=+5Q(D<$(Ya9$o%)lV88KfOQCJ0tM=!intEf{W!iZ#)jdF!aSkN z_W|1%m(E_^pz?pwxFRYBn^C7aO);KbuuPyK=0Y@rg+aPn#_|)7{(;xe1}00htb9R* z_ume@h`P37ppYE>64hc{pTaF@*Dt#+(Gg!t{v0p5wqL&{W0L@QJO&h(QNE>ODY#=4 zYR57Na{A4@mSz0K-j~UfzzAouY!fBS=w`bzGo=8wngm0Qa5@F_y`4Jed7rk*uP5!~ z39OhJU2Xi7mAo+UpR*1ivY_PxJ7LBAVft~mBStFouV{M986iLSiSf=hrrI0S#BnQi zXW*DE8lMK35hp!9|8Ok)QYuY7qef)hP}t)T?%#h=dz^j$unNX3@)e+!Z+ z>YwN{7=7%GGZ~0FW4V7{TlIu0G2UjNoym5~Q1()vp)Q=3;9L=qQ0ZW)Q_|#}|2L+x z@wK({<w93$x8-G(_8h-3D?9J$n%@hCq+&Y1IthdH^qJz9SyOzebhzbx(}{d zZ7(%m|F^JTk1HJL>_txsKEE9M(x(h-J=mNKFfai>LjH^=#etxDKEkxsPY_$8lfu3> za7>=XUYA=oX%0cZX3@a}P$+zjvzLTtb-a!56?c#z@4@M3Zn6j2)frbbV&nP{MaNiuvga^K0#OhE>xtqwE%`Hdp&&YQJ>INWp^ zn5)qxatF$;i(x|G`cA5^NU}E7d2>q&23Y;RJawP#)suK8F&sxJo zv(3po&g5!n5tv#cW}ktbaA&!U7|Y(R%Y{}_snKp*mi7F2_>egDB&q<+Il*6TeFrE| z3Okji%dtg7lN>W73$o$Y0m@#JJVOQuQzxAw-nPTK@XnF`W$f};`_b`D^ro>04L3>e zT|B2y;}WoMNpluWMh8Onf)X;yW?ElRp2%q9$g~{C+3kPa1{YaBMxkp{K7HsB8Q#vl zq8eD0begw95?&^>UQ;ht4N4zvsvv78CzK}<@*yo~8;c*JrB5g#%}7L4=$kv~gUNQO zg2a6h|+zcgtCK}q<<*?j}+LbW{Wow3a2@*e>sQjWG5eb z3yg!&-$b7aIqCjv!q^SS<+;PIhn>NyvI3@yyVA>H)big@qEl)Tx4;J(%w`)AZ8kOU z@5k!ndsatuKERJA!X}ajj}=ki&3C$-4W_0<`1^@!_7s7{?Usu2{ZTmcl2Y(p#Ue7> z41W{%<~8TOj%|wjW7L`#yndJ0+pJ>V-OZjev$N`|-%U29NBNc-rbim**E&@#D(?}p zM$N*D7HS)KB0g(I_VI%J4HAKeV_!ArSor2%U^}J zn{a7sml{{4w<^-l1tMzw$|QTrSuyPt0aemeE-WWLhA`Jj4ywI&lV6=U{LU$8)8+|NwaW%p3=#R#yalo+AVLV9!xYG|+acrc*;fcc823u?Za8O3?cPcj3*(-$z>L4@;3 zX3_t-w+>#__-W|s&1-bmxpCLv<|InUji67RA1izDOPA%^R_n_8)^hqWb2ZvIoJ9yL z7J>Ty5X@(aO2~acrj1}XQkm?j{tIrJnypUBVq|?z`B9_%XN;D8@0YXDN4EXMJn~gZ z{WmQ<@(L7uRBeJQ>+cREtI|T`fb9m zi(=_l{6SL1U(T0)n9fM9Qc_+Z&RQ>bitJaKleaDg*e*Rie@kXy7ykUQhGXdr0M7?q zhgL-g-dr60xrY^zA{MpSXia&VW)RK6W;a>uY}^Uek#6D$3q^+}D zx3O(u#bv|~vP^zgj#gUinbTohpcX%*MYwNIbIDVmf+}{(MN8;(<#;PY&S?0r#EeAS zU9O*+VCwnGt#?g~L`73_y9JXnU2|^a3I)5J5fzor#j_II(@NZJmSdY`DSjX6g4LN$ z_?8Ff?^E)13GE}%-9~E(g81s6_+s+zU0S6^wAGOPZSz#+aun}>sihiLFMaab{?+X7 zu?E;tbYdzo``#eCfAj58i$I5(0!lSTd0+n#o8EObxqndoaK?3b%O|}2jaIa8xKVuLBMcD*>A`*Je#l)q4%=wFuiFh7F{2~2qUxOCH>SXg z#=(_BhVNDp$djWVh7>&zeg5MJ#Y$b$RC`9(!(M||i^zx9C*Z^~@*unSE}!ZjzVTYF z*9i;*yYAC{=Hx*<9^v=I4M!p~&9kXJ*n|_D5ImGg@^4U=u6%-YH5Yb>8;Vg&?Mk|4 z^dvS2=^gg`Rp!pCiPJ=xmZsttEC~mj3ioy3U|Ab9+W5KILOq$3na$hnu3Q6ef$(`k zIJ4L;w*LqsEQ_1JMEbJ6>%drbs(owwVvJrZ|Vr>SJfLr1v_fIQw zc?(7C<*?rLN8`)^ zWITsQMz>1Ld8@X$cINrB=R(u1@y7=O()>Q_jh8*bG06j{I7~Uccv=;4LhIK^Dap53 zADf~sU3~TDB^OpEUV~2`Fz>jgR^qr_p&Gay;?UrG1bWF?_s&}-N9fM%jB1&5y~R71 zNh&24N}@90`y$j<`+QJs>Usv~tfr>sZ*tRyiuW^Rc7eKeI(tko9uK0A-*NZBzqS8r z4OXjz2?cRS6lTnP)h~OPO!zA^)Z%XLz3VM8_=1DAiC_wT*v)kN8BdlPNDz=lF5|h# z3lOFFE56^G&ru+YU-4pG!m^@VKNR-9N>Nt9eLF7jv=7a65qezhO}aOr(=q2SOyRP9 z*q{rP6auZn=i?W!tpvhf-=uOgJVZ`(!|0GNnZ$;z+IurOPUZkCDJlJ1Uh3bf*j0Xl zou~R!vL*tgBII?4E(U^5TY5+7ie(^4?DjGVg=|rXxnH^fI^r``oc~QZDR|*k=EqF) z`O2*^J5Fr_d>@K3-dWoHClq&#%~eF z`t~3!-m{LuB}$Uj{Ed z5-t;z9ALnSEs+%~Hjq7K_t8B4=vQ3p8BKI_!H3Y}Z*47CGE}<5>&}oX*?mveY%FEL z5AWZ;I3aKt-?}D7s6(F!-+_=iV*yD5iLmjrw89q4_hV(nS5v!zYBI&2Hz6+|3^%}X7b6HUjj8=4B!)`4Mx9}uzFt= z?}@%9Vub2tk9bSEKPY)q)U+OHnu6_?+x`)9+$7WifvnD5L(E%tO*Ugre;Q_EN7EBx{P<=N{Zwfype`x0DQ%;W+4%z1_I z`|jWrMiw3DIFX{b5!2syY{6*^!E!B|`R_i!&X9wKN*p`{@sY92)FN*~B; zlR_S%z}p67_b$B-{E}fl=!6A!)>hxOOfbJ?4AH^E2_Mx3-b)HjdotbjCBpWnZcT3X zyhM0b-JYS-hAOm;V!K|TwFjR2m?s{SS}djJ#haDUt|Y(nHD{xinPep z{n#(usl^sBDG`$``SGo_5s$dI3f>@PV`C!EJ3PJW^{?qIWMtMq6;0qXD#8?JtrQA7 zQ6p`<2P`4lj8E5^` zvt20Xt%&5R!i%C|<93Qv!8g~(T~A+pvbRqf_Ycnb-m|KhEZv!Si|#+|^it5+E}JC- zB%2X?*%jbXfY|qyNHFEEiNMC7nmdB7I0j(>H-5#g4*m)as*kd|&0drn^w_66xY3y8 zHU2=7PX8yG=Og*nY;9v7ik?hc)NOBj5f+c`ze-s zIRp$Q&%4?QJnkp97yW2Nr#F$IN#XlaqofG;PZ$~!FV>33u2d1>goIVOk4FN6oEw8h ze>{pmdy5N32P9Q~PW%lu9h;am9p~$o-S4g%k{2<2${ZRaRrR-18rXuJ!0UWwsQ^P? zs~qO+s%x#Z{I5w+oisayeR|l=Taz%(1^$g8$K%beiyc1GI_?3Sy+}AIA>DhNqRn2X ze}HU)8?{jDMFt4#X4E=izRy-t{Y#{TQw;N?HI?`u!aV~Y{%D@=a?2Uh~xsM!WDo zu@xQMzqEgEeDKO@BH}j%KVbKWb+6WjH2c*vS3B>;7)uB`c<)j4_-h0~N6?%ptDr9jvF(=jU{kP}`t> zJk$~X2B*{N=E!tV?1|-jk{CzB$aAz=^x=o#MXcraFjuGkN7QvT$1!XV5ty;RH0S}DXrlknw z;XfkNJGz!9O6$t!P@_So7CEdT`~prN3rB?9O976HjlW~RRYzQ5z^QyxRGR~IM`me` z6D6Hsx`X2Q&pMU*_@Ue(fow!A^(uy$6&az9v@O`fpf4{uftmR)6^^?eJQZU9SU{$T z%a{QPe@{XM9Ss+N;^Cg?Nm$hklp}o@!D0CiV=6|__<1vqu+4m)F9b?=M@7l%aaRrs z?3^J1;-+ycDFN?f{84@De~WLp3&$qs8)1?YT2Vp@gKiKQzki<@B7F+W--z$iDcsq6 zKjAol;?CJolD(aA=3xAEyFiCHl4#nAD!|Q-`{X`@#5i>qFyu54_o)l46zrcOOuCo6 z^AEgBL(munt;c`9*B7Y$N1E{hIc7eA&uP%}eEL3B+s>V1_ZP-ig85lpqNe~?e~L0 zn*+%CF7tbz0_wAStyRjCfMRHw(-^(x7(GDp3L%Z{oD`-^N-WRpw%N<)^WSLWps^vC zTxnRGT_cJyHUBj`dqq>b%ec!rHs;YspWYOUx!HFrP&;55{8>(4Vr8qDKs_8;4*#1@ z7?g*w@eJ-*nnuNjv95!WM=sb)wce<|G87cqmd2wH+vS{Wx zJLSjrxMqu`SjV5bvxxdW4YN((F*<;|F?@0-dheo^w(~hc2J$bk;3(C4Dx=EzLM>I> zA^J2xeuY#bP_O<%G+Yq@{d@_J)`<8+PK7m-I5n&9Q91-`Den6RNZ3(<`?PJSRvYe~fCS%pz%nxkq#lU;PnzY=OB7As51l|Na@4T0dr!6-Daq zyQ}sz$39-pYeJsPOf7^e81`#FF@93+HuSw_!Hn^7%-9u2K%+B|^3b34!+B|Sl#19J z*Kjp?DdUnsR51cj^j>Ot0$R9k|N&1PZ;sZFfVxBzcDzWE( zo@MI0#?erBikJFKfMF}Gpn-Gf_^hmeZVNIWKzL;om5Mhr6PYTaD=r%Q#(j>BN8I<} zb&SBCr}oK%su9o^DL-|kg-XTGr!Vk?N6}*9(Fp-W+8m_|%g|rUwR^?omc^xn$n*Z!7=$ znCO7l&Ok{n++}NP>#0$YNUIs(@)G_F#X56?JGOFkX#N7Ni(W@cudaa%l+|h7uOA5* z)C6{rejr=Y@z*F;Q$QG7+ZoN7Hrz_xZcJP=oJFZt|EgNuAv?f4V zU7z6^kyw=pL7#0|b7zb@;s;#!R5X&;6RCyz^edfx3&s*8x}77c_~hxOH(6r_rrZcm zdn1WrK#d9cwpimHws5y@ke?4II|cGkg2qqi%CXY-%g|rb&Ed+J z00HtUy7;BFFT=Aa*N7F>R*g@$%kIU1jAYcy{(%{su9eP+?N+PoF8x)E2FX7jvoL-I z*mC|+c6VNrWJd-%2-LxW_!#b*8CFM>6M6Foidtu}+zvu>-NLX&3Jiv;Kq=)jTR{RA zKEPI1kU|ysosC)FKpLQuVInm&|2XhHpG}4IZKejTH^tq*e&6V&a z-jtnv%&{CJROTvpK&yc}7TJlj5p{P-r)3l-2(>HL0?tn+%a zjkPR#qM>6qYafe(I^$>rxmoCA86r{|FaZu3pHiSg4b08^roey5++%(y-^p$!{qv+m zQ7XUm)FzAj!^WBj==;D_DiHXEzN|4nb4I)9Obi&as;%vv}CV_W8Tdy zC~4q!hPN0Lj;3UF)ky;wE)Nc5t9T)HgrW)q8_sFSnGOi%cH(y| z{fPM~DlUrc>$c_cR~gRlfJYCixpJhHItlR~<1*f1t$|GN0y?ZUnVrnA+yWR^!^;p_ zMOFrqbED7j?`s_wjq&j@t1MI?EzJ9Rb3<3B_^DRdIpXhDCCHlCQ_$qOMw-Xe+6$i} zv)3c(LPhkAGBS&<0^cGU9X2snUHv3-v#tQX3Kq^5b^+0E22>0S?vbpJNPl;X4>MPCj31u7T`zQ&@aqQm$ zKI!}kN(Q*T=zI%koC78l2i`GSl#-SicDQK`eNRV>Ms3=rPa9%(-Cg^j{BX+q-Bz`E zy3;W1^(b(v!`z>>Zk26cKDHo=4|16UqB z4JzXojw;bE#J%=~FFQY_NV0bJk2&&Y^|{ytF1eZb_Uaf}m}!ZPNyC?`@r7j-Ol=;s z-4lN%`D*t!=PZGGfDqb&Xq^ev6w@s?!QH1$fDH@RZ6?NK$dKsvw$>J>M5+1mq!MD6 zk`xjZu-*_AMhl;y-RE1rx06~B^$yIKvtHJBz)Zt0F4hLrL~^uh{xkL^8S2Y?1*_#o zE8b2?x>reqNde-#f;nikia5nRaYoJtjoX^r8lLts=wBHYlE{oc}()gj=yuNx2m@E{~=sTn|+Twj!C@N=8g20 z(=fFkh6^h990ZjM8*1(=RL5>z%R0+qq-Cyq@7W{bgx*p|o)f7?+Eb{MOw*h&1%Um0 z5~(Zi@EYmsmOrW!m->Cyr?GTws#XJ>9<)z^b9BPvfd>yEPn6t`zz;lx=V`(^3cmAJ{0|in>KQ; z)aj^Z#M6}}QRP_bsX4Ry2SMqJb+Vibl4tFIAG*~3hA2bc6o?h(_+jk#YNC20Hp>5T7d)Z%inaf|OKrqceB z&LpHzHmMS0$q)9GNLu+}6!T1>F;Ny{bo;?FkNNytp0SSBkalTBw`3^Hd1h@C7|+cmzXB*}88jGM9B%aN~Uv4r#s!{!GI|5>Agt z!qY;l9Z9KcwbWKs08VFg@7KjhLBxU8wR>Co}T77Aipg;MmWLRh7($> zHB-#P1{r1E#8%`ke>4-1bzVlk4qSb`cym}{j zxwQLJq>a@LXx09}vb+7<<6rF$&c&&(etk6UY6SiPH9g$HRSG`;(C!umJg)y}Wv5N382Rtt^8>_IVEN3FL`S-rd=a$C?* zOkCRAuh&@TV<*3LnGsyr9#lzskG{v0ijp9EVtZtCU~gfTOVq)TY!V_bKq z&f?}QEiosvrX!oDLD)TU;EA`x0V*9Nv~Ug8&QT?#@^xl|d=X`6a2Y0H0m49;3O?%l zw7)ZlfDnDj0eBfaJBksGnmy~-G(LiRPC&Oz2`zKlo2za&x$+CyACY_?#^fV%Pp`Mb z*zhip(yhlW$5`L%-HD*~R+p4%>0@8z@3EdA3YH>`G z7;6AB^Hs2}iKo8{ylT6m(&kBxu`45f_S$b=8ok0kx|!VWN|UiKJV9S2*&nLh0BkzjlntDCXPTGIoO_JUy&1n6 zxI8$vJ~4Jg21M4&+X310kIXvgKCYgdk-92;aM`2JAnzPi4Xaj${a{X?^OCg-pI_WI z0r*SV1X);vAw=ZkN(%!N&-~4GX?5L}~Y;BdXG`9|FlNtL9@n{XL@3}M=8J|T%eS>!`)3YMN`(TPmpLsmisz4m)>*L*!r7|* zh_1p0k*B%R7iWxD$UjoK>}FO+=sBN(j>Uqe$lidL;#%3@{t&gTw>eSrhfcRVH8Ma) zc_8+HU~2@6m>o#|yD|_VG49Tc=-Ll1y>>(oBCTLU*Q>3y>v$)y`Jpk^6^g!f6byL- zYi!N_WZ1#H4)%h3Wk|073Atv&9>LF(8W@h2c7dw0*rDd?mcS9Wv(YANQ3hR;$KUQ` z0T(KhN+NIjeO{YJgmC-&@9Ur^p@8oLb~|gCWTUK??w17@ujN;e)AZ4B$Tr)NYs+WX z+?7iCBR{S5wHTPm@^y^Y?L#^siVq+Z`sHIld~hxn6dd6HgK+H%jy{+f@Vs=dtBaJi za(CUn18c7YKC0>$8kL`^#BwMG1Mu((l=1NuN!~Ky6OhnwOg`cOh-+#<|9w~Fz#W8h zq;mf6G)>%D)4$Hu|NF^*ckI6h=D+vlzi{ziwEQnw{C|}z3BMWs1^@tK|5yP353B)% z?{pfJrHTG;sS>Oh)j7L-4Zn{~^f<57_+M~RJ^yp!VX;^PkFA Qq4ppr1Kc5n3K; -1); + if (debug) { opts.configuration = 'Debug'; } + + opts.stage = (args.indexOf('--stage') > -1); + if (opts.stage) { + opts.force = true; + } else { + var from_source = args.indexOf('--build-from-source'); + if ( from_source > -1) { + // no specific module name passed + next_arg = args[from_source+1]; + if (!next_arg || next_arg.indexOf('--') <= 0) { + opts.force = true; + } else if (next_arg === 'sqlite3'){ + opts.force = true; + } + } + } + var target_arch = args.indexOf('--target_arch'); + if (target_arch > -1) { + next_arg = args[target_arch+1]; + if (next_arg && next_arg.indexOf('--') < 0) { + opts.target_arch = next_arg; + } + } + opts.args = args; + return opts; +} + +module.exports.parse_args = parse_args; +module.exports.download = download; diff --git a/app.nw/node_modules/sleep/build.js b/app.nw/node_modules/sleep/build.js new file mode 100644 index 0000000..b81b116 --- /dev/null +++ b/app.nw/node_modules/sleep/build.js @@ -0,0 +1,113 @@ +// we borrow some build system tooling from node-sqlite3 +var package_json = require('./package.json'); +var Binary = require('./lib/binary_name.js').Binary; +var util = require('./build-util/tools.js'); + +var cp = require('child_process'); +var fs = require('fs'); +var mkdirp = require('mkdirp'); +var path = require('path'); + +var opts = { + name: 'node_sleep', + force: false, + stage: false, + configuration: 'Release', + target_arch: process.arch, + platform: process.platform, + uri: 'http://node-sleep.s3.amazonaws.com/', + tool: 'node-gyp', + paths: {} +}; + +function log(msg) { + console.log('['+package_json.name+']: ' + msg); +} + +// only for dev +function log_debug(msg) { + log(msg); +} + +function done(err) { + if (err) { + log(err); + process.exit(1); + } + process.exit(0); +} + +function build(opts,callback) { + var shell_cmd = opts.tool; + if (opts.tool === 'node-gyp' && process.platform === 'win32') { + shell_cmd = 'node-gyp.cmd'; + } + var shell_args = ['rebuild'].concat(opts.args); + var cmd = cp.spawn(shell_cmd,shell_args, {cwd: undefined, env: process.env, customFds: [ 0, 1, 2]}); + cmd.on('error', function (err) { + if (err) { + return callback(new Error("Failed to execute '" + shell_cmd + ' ' + shell_args.join(' ') + "' (" + err + ")")); + } + }); + // exit not close to support node v0.6.x + cmd.on('exit', function (code) { + if (code !== 0) { + return callback(new Error("Failed to execute '" + shell_cmd + ' ' + shell_args.join(' ') + "' (" + code + ")")); + } + move(opts,callback); + }); +} + +function move(opts,callback) { + try { + fs.statSync(opts.paths.build_module_path); + } catch (ex) { + return callback(new Error('Build succeeded but target not found at ' + opts.paths.build_module_path)); + } + try { + mkdirp.sync(path.dirname(opts.paths.runtime_module_path)); + log('Created: ' + path.dirname(opts.paths.runtime_module_path)); + } catch (err) { + log_debug(err); + } + fs.renameSync(opts.paths.build_module_path,opts.paths.runtime_module_path); + if (opts.stage) { + try { + mkdirp.sync(path.dirname(opts.paths.staged_module_file_name)); + log('Created: ' + path.dirname(opts.paths.staged_module_file_name)); + } catch (err) { + log_debug(err); + } + fs.writeFileSync(opts.paths.staged_module_file_name,fs.readFileSync(opts.paths.runtime_module_path)); + // drop build metadata into build folder + var metapath = path.join(path.dirname(opts.paths.staged_module_file_name),'build-info.json'); + // more build info + opts.date = new Date(); + opts.node_features = process.features; + opts.versions = process.versions; + opts.config = process.config; + opts.execPath = process.execPath; + fs.writeFileSync(metapath,JSON.stringify(opts,null,2)); + //tarball(opts,callback); + return callback(); + } else { + log('Installed in ' + opts.paths.runtime_module_path + ''); + return callback(); + } +} + +function rel(p) { + return path.relative(process.cwd(),p); +} + +// build it! +opts = util.parse_args(process.argv.slice(2), opts); +opts.binary = new Binary(opts); +var versioned = opts.binary.getRequirePath(); +opts.paths.runtime_module_path = rel(path.join(__dirname, 'lib', versioned)); +opts.paths.runtime_folder = rel(path.join(__dirname, 'lib', 'binding',opts.binary.configuration)); +var staged_module_path = path.join(__dirname, 'stage', opts.binary.getModuleAbi(), opts.binary.getBasePath()); +opts.paths.staged_module_file_name = rel(path.join(staged_module_path,opts.binary.filename())); +opts.paths.build_module_path = rel(path.join(__dirname, 'build', opts.binary.configuration, opts.binary.filename())); + +build(opts, done); diff --git a/app.nw/node_modules/sleep/lib/binary_name.js b/app.nw/node_modules/sleep/lib/binary_name.js new file mode 100644 index 0000000..34f1173 --- /dev/null +++ b/app.nw/node_modules/sleep/lib/binary_name.js @@ -0,0 +1,58 @@ + +var path = require('path'); + +var Binary = function(options) { + options = options || {}; + var package_json = options.package_json || require('../package.json'); + this.name = options.name || 'binding'; + this.configuration = options.configuration || 'Release'; + this.uri = options.uri || 'http://'+this.name+'.s3.amazonaws.com/'; + this.module_maj_min = package_json.version.split('.').slice(0,2).join('.'); + this.module_abi = package_json.abi; + this.platform = options.platform || process.platform; + this.target_arch = options.target_arch || process.arch; + if (process.versions.modules) { + // added in >= v0.10.4 and v0.11.7 + // https://github.com/joyent/node/commit/ccabd4a6fa8a6eb79d29bc3bbe9fe2b6531c2d8e + this.node_abi = 'node-v' + (+process.versions.modules); + } else { + this.node_abi = 'v8-' + process.versions.v8.split('.').slice(0,2).join('.'); + } +}; + +Binary.prototype.filename = function() { + return this.name + '.node'; +}; + +Binary.prototype.compression = function() { + return '.tar.gz'; +}; + +Binary.prototype.getBasePath = function() { + return this.node_abi + + '-' + this.platform + + '-' + this.target_arch; +}; + +Binary.prototype.getRequirePath = function(configuration) { + return '../' + path.join('Build', + configuration || this.configuration, + this.filename()); +}; + +Binary.prototype.getModuleAbi = function() { + return this.name + '-v' + this.module_maj_min + '.' + this.module_abi; +}; + +Binary.prototype.getArchivePath = function() { + return this.getModuleAbi() + + '-' + + this.getBasePath() + + this.compression(); +}; + +Binary.prototype.getRemotePath = function() { + return this.uri+this.configuration+'/'+this.getArchivePath(); +}; + +module.exports.Binary = Binary; diff --git a/app.nw/node_modules/sleep/lib/index.js b/app.nw/node_modules/sleep/lib/index.js new file mode 100644 index 0000000..80e7572 --- /dev/null +++ b/app.nw/node_modules/sleep/lib/index.js @@ -0,0 +1,35 @@ +var Binary = require('./binary_name.js').Binary; +var binary = new Binary({name:'node_sleep'}); +var binding; +try { + binding = require(binary.getRequirePath('Debug')); +} catch (err) { /* ignore */ } +if (!binding) { + try { + binding = require(binary.getRequirePath('Release')); + } catch (err) { /* ignore */ } +} +if (!binding) { + console.error("Using busy loop implementation of sleep."); + binding = { + sleep: function(s) { + var e = new Date().getTime() + (s * 1000); + + while (new Date().getTime() <= e) { + /* do nothing, but burn a lot of CPU while doing so */ + /* jshint noempty: false */ + } + }, + + usleep: function(s) { + var e = new Date().getTime() + (s / 1000); + + while (new Date().getTime() <= e) { + /* do nothing, but burn a lot of CPU while doing so */ + /* jshint noempty: false */ + } + } + }; +} + +module.exports = binding; diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/.npmignore b/app.nw/node_modules/sleep/node_modules/mkdirp/.npmignore new file mode 100644 index 0000000..9303c34 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/.npmignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/.travis.yml b/app.nw/node_modules/sleep/node_modules/mkdirp/.travis.yml new file mode 100644 index 0000000..84fd7ca --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.6 + - 0.8 + - 0.9 diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/LICENSE b/app.nw/node_modules/sleep/node_modules/mkdirp/LICENSE new file mode 100644 index 0000000..432d1ae --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/LICENSE @@ -0,0 +1,21 @@ +Copyright 2010 James Halliday (mail@substack.net) + +This project is free software released under the MIT/X11 license: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/examples/pow.js b/app.nw/node_modules/sleep/node_modules/mkdirp/examples/pow.js new file mode 100644 index 0000000..e692421 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/examples/pow.js @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/index.js b/app.nw/node_modules/sleep/node_modules/mkdirp/index.js new file mode 100644 index 0000000..fda6de8 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/index.js @@ -0,0 +1,82 @@ +var path = require('path'); +var fs = require('fs'); + +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + +function mkdirP (p, mode, f, made) { + if (typeof mode === 'function' || mode === undefined) { + f = mode; + mode = 0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + if (typeof mode === 'string') mode = parseInt(mode, 8); + p = path.resolve(p); + + fs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), mode, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, mode, cb, made); + }); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + fs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); +} + +mkdirP.sync = function sync (p, mode, made) { + if (mode === undefined) { + mode = 0777 & (~process.umask()); + } + if (!made) made = null; + + if (typeof mode === 'string') mode = parseInt(mode, 8); + p = path.resolve(p); + + try { + fs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), mode, made); + sync(p, mode, made); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = fs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } + + return made; +}; diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/package.json b/app.nw/node_modules/sleep/node_modules/mkdirp/package.json new file mode 100644 index 0000000..59d66e1 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/package.json @@ -0,0 +1,38 @@ +{ + "name": "mkdirp", + "description": "Recursively mkdir, like `mkdir -p`", + "version": "0.3.5", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "main": "./index", + "keywords": [ + "mkdir", + "directory" + ], + "repository": { + "type": "git", + "url": "http://github.com/substack/node-mkdirp.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "devDependencies": { + "tap": "~0.4.0" + }, + "license": "MIT", + "readme": "# mkdirp\n\nLike `mkdir -p`, but in node.js!\n\n[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)\n\n# example\n\n## pow.js\n\n```js\nvar mkdirp = require('mkdirp');\n \nmkdirp('/tmp/foo/bar/baz', function (err) {\n if (err) console.error(err)\n else console.log('pow!')\n});\n```\n\nOutput\n\n```\npow!\n```\n\nAnd now /tmp/foo/bar/baz exists, huzzah!\n\n# methods\n\n```js\nvar mkdirp = require('mkdirp');\n```\n\n## mkdirp(dir, mode, cb)\n\nCreate a new directory and any necessary subdirectories at `dir` with octal\npermission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\n`cb(err, made)` fires with the error or the first directory `made`\nthat had to be created, if any.\n\n## mkdirp.sync(dir, mode)\n\nSynchronously create a new directory and any necessary subdirectories at `dir`\nwith octal permission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\nReturns the first directory that had to be created, if any.\n\n# install\n\nWith [npm](http://npmjs.org) do:\n\n```\nnpm install mkdirp\n```\n\n# license\n\nMIT\n", + "readmeFilename": "readme.markdown", + "bugs": { + "url": "https://github.com/substack/node-mkdirp/issues" + }, + "homepage": "https://github.com/substack/node-mkdirp", + "_id": "mkdirp@0.3.5", + "dist": { + "shasum": "d7def7349d674800fac371eef2ecaff11c41ccde" + }, + "_from": "mkdirp@~0.3.5", + "_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" +} diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/readme.markdown b/app.nw/node_modules/sleep/node_modules/mkdirp/readme.markdown new file mode 100644 index 0000000..83b0216 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/readme.markdown @@ -0,0 +1,63 @@ +# mkdirp + +Like `mkdir -p`, but in node.js! + +[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp) + +# example + +## pow.js + +```js +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); +``` + +Output + +``` +pow! +``` + +And now /tmp/foo/bar/baz exists, huzzah! + +# methods + +```js +var mkdirp = require('mkdirp'); +``` + +## mkdirp(dir, mode, cb) + +Create a new directory and any necessary subdirectories at `dir` with octal +permission string `mode`. + +If `mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +`cb(err, made)` fires with the error or the first directory `made` +that had to be created, if any. + +## mkdirp.sync(dir, mode) + +Synchronously create a new directory and any necessary subdirectories at `dir` +with octal permission string `mode`. + +If `mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +Returns the first directory that had to be created, if any. + +# install + +With [npm](http://npmjs.org) do: + +``` +npm install mkdirp +``` + +# license + +MIT diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/chmod.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/chmod.js new file mode 100644 index 0000000..520dcb8 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/chmod.js @@ -0,0 +1,38 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +test('chmod-pre', function (t) { + var mode = 0744 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.equal(stat && stat.mode & 0777, mode, 'should be 0744'); + t.end(); + }); + }); +}); + +test('chmod', function (t) { + var mode = 0755 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.end(); + }); + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/clobber.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/clobber.js new file mode 100644 index 0000000..0eb7099 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/clobber.js @@ -0,0 +1,37 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +// a file in the way +var itw = ps.slice(0, 3).join('/'); + + +test('clobber-pre', function (t) { + console.error("about to write to "+itw) + fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.'); + + fs.stat(itw, function (er, stat) { + t.ifError(er) + t.ok(stat && stat.isFile(), 'should be file') + t.end() + }) +}) + +test('clobber', function (t) { + t.plan(2); + mkdirp(file, 0755, function (err) { + t.ok(err); + t.equal(err.code, 'ENOTDIR'); + t.end(); + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/mkdirp.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/mkdirp.js new file mode 100644 index 0000000..b07cd70 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/mkdirp.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('woo', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm.js new file mode 100644 index 0000000..23a7abb --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('async perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); + +test('async root perm', function (t) { + mkdirp('/tmp', 0755, function (err) { + if (err) t.fail(err); + t.end(); + }); + t.end(); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm_sync.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm_sync.js new file mode 100644 index 0000000..f685f60 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm_sync.js @@ -0,0 +1,39 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json'; + + mkdirp.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); + +test('sync root perm', function (t) { + t.plan(1); + + var file = '/tmp'; + mkdirp.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/race.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/race.js new file mode 100644 index 0000000..96a0447 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/race.js @@ -0,0 +1,41 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('race', function (t) { + t.plan(4); + var ps = [ '', 'tmp' ]; + + for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); + } + var file = ps.join('/'); + + var res = 2; + mk(file, function () { + if (--res === 0) t.end(); + }); + + mk(file, function () { + if (--res === 0) t.end(); + }); + + function mk (file, cb) { + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + if (cb) cb(); + } + }) + }) + }); + } +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/rel.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/rel.js new file mode 100644 index 0000000..7985824 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/rel.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('rel', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var cwd = process.cwd(); + process.chdir('/tmp'); + + var file = [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + process.chdir(cwd); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/return.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/return.js new file mode 100644 index 0000000..bce68e5 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/return.js @@ -0,0 +1,25 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(4); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, '/tmp/' + x); + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, null); + }); + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/return_sync.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/return_sync.js new file mode 100644 index 0000000..7c222d3 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/return_sync.js @@ -0,0 +1,24 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + // Note that this will throw on failure, which will fail the test. + var made = mkdirp.sync(file); + t.equal(made, '/tmp/' + x); + + // making the same file again should have no effect. + made = mkdirp.sync(file); + t.equal(made, null); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/root.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/root.js new file mode 100644 index 0000000..97ad7a2 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/root.js @@ -0,0 +1,18 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('root', function (t) { + // '/' on unix, 'c:/' on windows. + var file = path.resolve('/'); + + mkdirp(file, 0755, function (err) { + if (err) throw err + fs.stat(file, function (er, stat) { + if (er) throw er + t.ok(stat.isDirectory(), 'target is a directory'); + t.end(); + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/sync.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/sync.js new file mode 100644 index 0000000..7530cad --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/sync.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file, 0755); + } catch (err) { + t.fail(err); + return t.end(); + } + + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }); + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask.js new file mode 100644 index 0000000..64ccafe --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('implicit mode from umask', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0777 & (~process.umask())); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask_sync.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask_sync.js new file mode 100644 index 0000000..35bd5cb --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask_sync.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('umask sync modes', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file); + } catch (err) { + t.fail(err); + return t.end(); + } + + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, (0777 & (~process.umask()))); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }); + }); +}); diff --git a/app.nw/node_modules/sleep/package.json b/app.nw/node_modules/sleep/package.json new file mode 100644 index 0000000..644c149 --- /dev/null +++ b/app.nw/node_modules/sleep/package.json @@ -0,0 +1,46 @@ +{ + "name": "sleep", + "version": "1.1.4", + "main": "./lib/index.js", + "description": "Add sleep() and usleep() to nodejs", + "homepage": "http://github.com/ErikDubbelboer/node-sleep", + "author": { + "name": "Erik Dubbelboer", + "email": "erik@dubbelboer.com" + }, + "engines": { + "node": ">=0.4.0" + }, + "keywords": [ + "sleep", + "usleep" + ], + "repository": { + "type": "git", + "url": "https://github.com/ErikDubbelboer/node-sleep.git" + }, + "repositories": [ + { + "type": "git", + "url": "https://github.com/ErikDubbelboer/node-sleep.git" + } + ], + "dependencies": { + "mkdirp": "~0.3.5" + }, + "scripts": { + "install": "node build.js || nodejs build.js" + }, + "gypfile": true, + "readme": "sleep\n=====\n\nAdd `sleep()` and `usleep()` to nodejs.\n\nThis is mainly useful for debugging.\n\n**Sleep will block execution of all javascript!**\n===================================================\n\nOn windows the module will fall back to a while loop which will use 100% CPU!\n\nUsage\n-----\n\n`var sleep = require('sleep');`\n\n* `sleep.sleep(n)`: sleep for n seconds\n* `sleep.usleep(n)`: sleep for n microseconds (1 second is 1000000 microseconds)\n\nUpdate\n------\n\nNow bulids properly using node-gyp :)\n\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/ErikDubbelboer/node-sleep/issues" + }, + "_id": "sleep@1.1.4", + "dist": { + "shasum": "514d79e04ea79ed6e81761f4ca5c4c9aa866f169" + }, + "_from": "sleep@", + "_resolved": "https://registry.npmjs.org/sleep/-/sleep-1.1.4.tgz" +} diff --git a/app.nw/node_modules/sleep/sleep.cc b/app.nw/node_modules/sleep/sleep.cc new file mode 100644 index 0000000..4faaa12 --- /dev/null +++ b/app.nw/node_modules/sleep/sleep.cc @@ -0,0 +1,70 @@ +#ifndef BUILDING_NODE_EXTENSION +#define BUILDING_NODE_EXTENSION +#endif // BUILDING_NODE_EXTENSION + +#include +#include + +#ifdef _WIN32 || _WIN64 +unsigned int sleep(unsigned int seconds) +{ + Sleep(seconds * 1000); + return 0; +} +int usleep(unsigned __int64 usec) +{ + LARGE_INTEGER li; + li.QuadPart = -10 * usec; // negative values for relative time + + HANDLE timer = CreateWaitableTimer(NULL, TRUE, NULL); + if(!timer) return -1; + + SetWaitableTimer(timer, &li, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); + return 0; +} +#else +# include +#endif + + +using namespace v8; +using namespace node; + + +Handle Sleep(const Arguments& args) { + HandleScope scope; + + if (args.Length() < 1 || !args[0]->IsUint32()) { + return ThrowException(Exception::TypeError(String::New("Expected number of seconds"))); + } + + sleep(args[0]->Uint32Value()); + + return scope.Close(Undefined()); +} + +Handle USleep(const Arguments& args) { + HandleScope scope; + + if (args.Length() < 1 || !args[0]->IsUint32()) { + return ThrowException(Exception::TypeError(String::New("Expected number of micro"))); + } + + usleep(args[0]->Uint32Value()); + + return scope.Close(Undefined()); +} + + +extern "C" void init(Handle target) { + NODE_SET_METHOD(target, "sleep", Sleep); + NODE_SET_METHOD(target, "usleep", USleep); +} + + +#ifdef NODE_MODULE +NODE_MODULE(node_sleep, init) +#endif + diff --git a/app.nw/node_modules/sleep/test.js b/app.nw/node_modules/sleep/test.js new file mode 100644 index 0000000..e0735ad --- /dev/null +++ b/app.nw/node_modules/sleep/test.js @@ -0,0 +1,12 @@ + +var sleep = require('./'); + +console.log('sleeping for 1 seconds...'); +sleep.sleep(1); +console.log('done'); + + +console.log('sleeping for 2000000 microseconds (2 seconds)'); +sleep.usleep(2000000); +console.log('done'); + diff --git a/app.nw/package.json b/app.nw/package.json new file mode 100755 index 0000000..e767526 --- /dev/null +++ b/app.nw/package.json @@ -0,0 +1,14 @@ +{ + "name": "ipynb", + "main": "app://whatever/start.html", + "dependencies": + { + "sleep": "" + }, + "window": { + "width": 473, + "height": 340, + "toolbar": false, + "fullscreen": false + } +} diff --git a/app.nw/start.html b/app.nw/start.html new file mode 100755 index 0000000..a78726c --- /dev/null +++ b/app.nw/start.html @@ -0,0 +1,167 @@ + + + + Start + + + + +
+ status: status +
+ + + + diff --git a/app.nw/test.js b/app.nw/test.js new file mode 100644 index 0000000..6667538 --- /dev/null +++ b/app.nw/test.js @@ -0,0 +1,63 @@ +var nbexec = 'nb.app/Contents/MacOS/nb'; +var basedir = '.'; //working dir +var startpage = 'http://127.0.0.1:8888/'; +var pagecheck = 'http://127.0.0.1:8888/tree'; //no side-effect page to check if webserver is running +//************************************************************ +var ipynb_process = null; +var spawn = require("child_process").spawn; +var sleep = require("sleep"); + +function Startipynb() +{ + console.log('start_nb'); + + var child; + child = spawn(nbexec, ['',],{cwd:basedir}); + child.stdout.on("data", function(data) { + return console.log("stdout:" + data); + }); + child.stderr.on("data", function(data) { + return console.log("ERROR: " + data); + }); + + child.on("exit", function(code) { + return console.log("Encoding process exited with code: " + code); + }); + + console.log("start_nb_End"); + + ipynb_process = child; + + function transferComplete(evt) { + console.log("transferComplete"); + } + + function transferFailed(evt) { + console.log("transferFailed"); + console.log("Waiting..."); + sleep.sleep(5); + checkServer(); + } + + function reqListener () { + console.log("Launching..."); + } + + function checkServer() + { + console.log("checking server"); + var oReq = new XMLHttpRequest(); + oReq.addEventListener("load", transferComplete, false); + oReq.addEventListener("error", transferFailed, false); + + oReq.onload = reqListener; + oReq.open("GET", pagecheck, true); + oReq.send(); + } + + console.log("starting..."); + checkServer(); + +} + +Startipynb(); diff --git a/py2app/nb.py b/py2app/nb.py new file mode 100644 index 0000000..bd5e625 --- /dev/null +++ b/py2app/nb.py @@ -0,0 +1,17 @@ +import os + +from IPython.html import notebookapp + +from zmq.eventloop import ioloop +ioloop.install() + +class QuickShutdownNotebookApp(notebookapp.NotebookApp): + def _confirm_exit(self): + self.log.critical("Shutting down") + ioloop.IOLoop.instance().stop() + +NOTEBOOK_STORAGE = os.path.expanduser('~/Library/ipyapp-notebooks/') +if __name__ == '__main__': + if not os.path.exists(NOTEBOOK_STORAGE): + os.makedirs(NOTEBOOK_STORAGE) + QuickShutdownNotebookApp.launch_instance(argv=['--no-browser', '--notebook-dir=%s' % NOTEBOOK_STORAGE]) diff --git a/py2app/setup.py b/py2app/setup.py new file mode 100644 index 0000000..5be1d7d --- /dev/null +++ b/py2app/setup.py @@ -0,0 +1,19 @@ +""" +This is a setup.py script generated by py2applet + +Usage: + python setup.py py2app +""" + +from setuptools import setup + +APP = ['nb.py'] +DATA_FILES = [] +OPTIONS = {'argv_emulation': True} + +setup( + app=APP, + data_files=DATA_FILES, + options={'py2app': OPTIONS}, + setup_requires=['py2app'], +)