From a88a42fbbfeaa75162b1529248270dd9adbd801d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sat, 4 Jan 2025 15:34:37 +0100 Subject: [PATCH] [4.x] Add DisallowSqliteAttach feature (#1283) * queue.yml: remove TENANCY_VERSION env var from test.sh * add DisallowSqliteAttach feature * Fix code style (php-cs-fixer) * ci: add cd to each step * ci: simpler solution to race conditions, proper os/arch matrix * ci: fix runs-on matrix * ci: fix workflow on windows, fix makefile * Auto-build: Update extensions [skip ci] * Auto-build: Update extensions [skip ci] * ci: try fixing retry logic, make makefile use cl on Windows * ci: use the current branch for rebase * ci: try calling vcvars64 * ci: misc minor fixes * ci: try fixing c compiler on windows * ci: misc minor fixes * ci: add debug steps * ci: try to fix windows build * ci: try using clang on windows * ci: windows fixes, makefile fix * Auto-build: Update extensions [skip ci] * ci: dont produce .exp .lib on Windows * ci: try forcing shell: bash on commit step * ci: try to get linux cross-compilation working * ci: reformulate condition * ci: fix syntax error * ci: correct debian image name * Auto-build: Update extensions [skip ci] * ci: try to set up macOS cross-compilation * ci: add ARCH variable to makefile, override it during cross-compilation * Auto-build: Update extensions [skip ci] * ci: X64 -> x64 * ci: only trigger extensions.yml on pushes to extensions/ * fix tests on x64 * ci: try using bash for pushing on windows; ignore phpstan error * fix test failing in ci but passing locally * bump php version in composer.json, trigger extensions.yml build * remove comment * noattach: more explicit return values, avoid potential non-bool return values * makefile: use -Os on Windows * ci: use make -B * ci: try triggering extensions build on extensions.yml file changes * Auto-build: Update extensions [skip ci] * Auto-build: Update extensions [skip ci] * ci: remove windows linker flag, use a whitelist for git add * Auto-build: Update extensions [skip ci] * Auto-build: Update extensions [skip ci] * Auto-build: Update extensions [skip ci] * fix path in feature class, minor refactor * Fix code style (php-cs-fixer) --------- Co-authored-by: PHP CS Fixer Co-authored-by: github-actions[bot] --- .github/workflows/extensions.yml | 102 +++++++++++++++++++++++++ .github/workflows/queue.yml | 2 +- .github/workflows/validate.yml | 2 + INTERNAL.md | 4 + assets/config.php | 1 + composer.json | 4 +- extensions/.gitignore | 3 + extensions/Makefile | 41 ++++++++++ extensions/lib/.gitkeep | 0 extensions/lib/arm/.gitkeep | 0 extensions/lib/arm/noattach.dylib | Bin 0 -> 16912 bytes extensions/lib/arm/noattach.so | Bin 0 -> 69440 bytes extensions/lib/noattach.dll | Bin 0 -> 102912 bytes extensions/lib/noattach.dylib | Bin 0 -> 16912 bytes extensions/lib/noattach.so | Bin 0 -> 15304 bytes extensions/noattach.c | 22 ++++++ src/Features/DisallowSqliteAttach.php | 72 +++++++++++++++++ tests/Features/NoAttachTest.php | 106 ++++++++++++++++++++++++++ 18 files changed, 356 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/extensions.yml create mode 100644 extensions/.gitignore create mode 100644 extensions/Makefile create mode 100644 extensions/lib/.gitkeep create mode 100644 extensions/lib/arm/.gitkeep create mode 100755 extensions/lib/arm/noattach.dylib create mode 100755 extensions/lib/arm/noattach.so create mode 100644 extensions/lib/noattach.dll create mode 100755 extensions/lib/noattach.dylib create mode 100755 extensions/lib/noattach.so create mode 100644 extensions/noattach.c create mode 100644 src/Features/DisallowSqliteAttach.php create mode 100644 tests/Features/NoAttachTest.php diff --git a/.github/workflows/extensions.yml b/.github/workflows/extensions.yml new file mode 100644 index 00000000..9cc1eaf2 --- /dev/null +++ b/.github/workflows/extensions.yml @@ -0,0 +1,102 @@ +name: Build extensions + +on: + push: + paths: + - 'extensions/**' + - '.github/workflows/extensions.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + strategy: + matrix: + include: + - os: ubuntu-latest + arch: x64 + - os: ubuntu-latest + arch: ARM64 + - os: windows-latest + arch: x64 + - os: macos-latest + arch: x64 + - os: macos-latest + arch: ARM64 + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Download SQLite headers (Unix) + if: runner.os != 'Windows' + run: cd extensions && make headers + + - name: Download SQLite headers (Windows) + if: runner.os == 'Windows' + run: | + cd extensions + curl.exe -L https://www.sqlite.org/2024/sqlite-amalgamation-3470200.zip -o sqlite-src.zip + Expand-Archive -Path sqlite-src.zip -DestinationPath . + Copy-Item sqlite-amalgamation-3470200\sqlite3.h . + Copy-Item sqlite-amalgamation-3470200\sqlite3ext.h . + + - name: Set up QEMU (Linux cross-compilation) + if: runner.os == 'Linux' && matrix.arch == 'ARM64' + uses: docker/setup-qemu-action@v3 + + - name: Build C files (Native Windows) + if: runner.os == 'Windows' + run: cd extensions && make -B + + - name: Build C files (Native Linux) + if: runner.os == 'Linux' && matrix.arch == 'x64' + run: cd extensions && make -B + + - name: Build C files (Linux cross-compilation) + if: runner.os == 'Linux' && matrix.arch == 'ARM64' + run: | + cd extensions + docker run --platform linux/arm64 \ + -v .:/extensions \ + debian:bookworm-slim \ + bash -c "apt-get update && apt-get install -y make gcc && cd /extensions && make" + + - name: Build C files (Native macOS ARM64) + if: matrix.os == 'macos-latest' && matrix.arch == 'ARM64' + run: cd extensions && make -B + + - name: Build C files (macOS cross-compilation) + if: matrix.os == 'macos-latest' && matrix.arch == 'x64' + run: | + cd extensions + brew install llvm + export CC=/opt/homebrew/opt/llvm/bin/clang + export CFLAGS="-target x86_64-apple-darwin" + export LDFLAGS="-target x86_64-apple-darwin" + make -B ARCH=x86_64 + + - name: Commit output files + shell: bash + run: | + cd extensions + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add lib/*.{so,dylib,dll} lib/arm/*.{so,dylib} + git commit -m "Auto-build: Update extensions [skip ci]" || echo "No changes to commit" + + - name: Push files + shell: bash + run: | + CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + for attempt in {1..3}; do + git pull --rebase origin $CURRENT_BRANCH && git push origin $CURRENT_BRANCH && exit 0 || { + echo "Attempt $attempt failed. Retrying in 5 seconds..." + sleep 5 + } + done + + echo "Failed to push changes after 3 attempts." + exit 1 diff --git a/.github/workflows/queue.yml b/.github/workflows/queue.yml index 07994bbb..0f3ec82e 100644 --- a/.github/workflows/queue.yml +++ b/.github/workflows/queue.yml @@ -24,4 +24,4 @@ jobs: run: | cd tenancy-queue-tester TENANCY_VERSION=${VERSION_PREFIX}#${GITHUB_SHA} ./setup.sh - TENANCY_VERSION=${VERSION_PREFIX}#${GITHUB_SHA} ./test.sh + ./test.sh diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 3931ca36..73f6355b 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,3 +1,5 @@ +name: Validate code + on: [push, pull_request] jobs: diff --git a/INTERNAL.md b/INTERNAL.md index 34484836..b3335fed 100644 --- a/INTERNAL.md +++ b/INTERNAL.md @@ -16,3 +16,7 @@ The `ci.yml` workflow includes support for [act](https://github.com/nektos/act). To run all tests using act, run `composer act`. To run only certain tests using act, use `composer act-input "FILTER='some test name'"` or `composer act -- --input "FILTER='some test name'"`. + +Helpful note: GHA doesn't mount the project at /var/www/html like the docker compose setup does. This can be observed in act where the inner container's filesystem structure will match the host. + +Also, for debugging act you can just add a job that does `sleep 1h` and then `docker ps` + `docker exec -it bash`. diff --git a/assets/config.php b/assets/config.php index a16a4201..3a521a6c 100644 --- a/assets/config.php +++ b/assets/config.php @@ -389,6 +389,7 @@ return [ // Stancl\Tenancy\Features\TenantConfig::class, // Stancl\Tenancy\Features\CrossDomainRedirect::class, // Stancl\Tenancy\Features\ViteBundler::class, + // Stancl\Tenancy\Features\DisallowSqliteAttach::class, ], /** diff --git a/composer.json b/composer.json index 905ffba3..851f4ca1 100644 --- a/composer.json +++ b/composer.json @@ -67,10 +67,10 @@ "docker-up": "docker compose up -d", "docker-down": "docker compose down", "docker-restart": "docker compose down && docker compose up -d", - "docker-rebuild": "PHP_VERSION=8.3 docker compose up -d --no-deps --build", + "docker-rebuild": "PHP_VERSION=8.4 docker compose up -d --no-deps --build", "docker-m1": "ln -s docker-compose-m1.override.yml docker-compose.override.yml", "testbench-unlink": "rm ./vendor/orchestra/testbench-core/laravel/vendor", - "testbench-link": "ln -s vendor ./vendor/orchestra/testbench-core/laravel/vendor", + "testbench-link": "ln -s /var/www/html/vendor ./vendor/orchestra/testbench-core/laravel/vendor", "testbench-repair": "mkdir -p ./vendor/orchestra/testbench-core/laravel/storage/framework/sessions && mkdir -p ./vendor/orchestra/testbench-core/laravel/storage/framework/views && mkdir -p ./vendor/orchestra/testbench-core/laravel/storage/framework/cache", "coverage": "open coverage/phpunit/html/index.html", "phpstan": "vendor/bin/phpstan --memory-limit=256M", diff --git a/extensions/.gitignore b/extensions/.gitignore new file mode 100644 index 00000000..d2ff3048 --- /dev/null +++ b/extensions/.gitignore @@ -0,0 +1,3 @@ +*.h +*.zip +sqlite-amalgamation-3470200/ diff --git a/extensions/Makefile b/extensions/Makefile new file mode 100644 index 00000000..1f61398a --- /dev/null +++ b/extensions/Makefile @@ -0,0 +1,41 @@ +.PHONY: all headers + +OUTPUT := + +CCFLAGS += -shared -Os + +ifeq ($(OS),Windows_NT) + OUTPUT = lib/noattach.dll + CC = clang +else + UNAME := $(shell uname) + CCFLAGS += -fPIC + ARCH := $(if $(ARCH),$(ARCH),$(shell uname -m)) + ifeq ($(UNAME),Darwin) + ifeq ($(ARCH),arm64) + OUTPUT = lib/arm/noattach.dylib + else + OUTPUT = lib/noattach.dylib + endif + else + ifeq ($(ARCH),aarch64) + OUTPUT = lib/arm/noattach.so + else + OUTPUT = lib/noattach.so + endif + endif +endif + +$(info OUTPUT=$(OUTPUT)) + +all: $(OUTPUT) + +headers: + # To simplify compilation across platforms, we include sqlite3ext.h in this directory. + curl -L https://www.sqlite.org/2024/sqlite-amalgamation-3470200.zip -o sqlite-src.zip + unzip sqlite-src.zip + cp sqlite-amalgamation-3470200/*.h . + +$(OUTPUT): noattach.c + # We don't link against libsqlite3 since PHP statically links its own libsqlite3. + $(CC) $(CCFLAGS) -o $@ $< diff --git a/extensions/lib/.gitkeep b/extensions/lib/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/extensions/lib/arm/.gitkeep b/extensions/lib/arm/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/extensions/lib/arm/noattach.dylib b/extensions/lib/arm/noattach.dylib new file mode 100755 index 0000000000000000000000000000000000000000..a9a8ec98a4d369dcc2ac2f3a95ec47734c35ee1b GIT binary patch literal 16912 zcmX^A>+L@t1_nk31_lN;1_lOx1_p)(W(I~<1_6)|gCqk3g9Rf4LwtOQYeWcG2$gU^ zZuq$0rw;6lLb6 z!}+N0tAU!Q1eJ&JpMD z*c=zf5J#{Ogn)(*ESw;M2oe-tAPkNWu>R!y+}!*;n2Pv#?B;R66fiI_fb_$-Fmqsh zkh?s<=K6U0dAquJ!r~Mbx@hhbfO-;S4hX}{;bmZ8FkoO{kYIo&9;if4W|DqlQLcVo zequ>UVseIFN@Y%F5(9$?149EiML94qSTHa!7(@9MP(H{SkXaQD5cjWeU;qaZHv*y`-P8zft3%ODZuvd z$g*fLFhFwz#2Ow@zJQtqat~95BP%E*^h=A2^g)4;lbIA;SzMButLFp@1CUNNs5u1= z3=E(+(}eOt{szg*LiryY7#I{lo&^bx;?WQo4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R z7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z z5Eu=C(GVC7fzc2c;UVzFf8WZ#)r>3uIx|fC%*?n-gn?m06BENvj~vIJj0_AD6c5-= zWMXKz#K35Oje(KDq=U)fCx@uxPX-2t2@D@>CxXNim>7O4Ff;`Ht#(}b#sAQX1I+Q) z>=PIYABfMF0WWpuOB64AO+W z?HHsVB!+<*Z0v?~4ms!Ff4l!Xy zT?Ci`+6T?Y$iPql-B%Ct4?oCNP!E94A>e0Z0G|T@(xAWqw-01EoP%mfd`fCwWjti( zc|1xug3JKnU-x(pFfcHJwt>UEDe~(c4-*3eBRc~V3n)}TP5~V&0C6bz7z2k73QP>3 zE#Dv`2w~U}1`IH_LHB<*s2G0wczkMFVeG%dX10AP>o0TOdDQ*euw-`QSILi|Rcq_l zY>LP~_A>1N%k_&Fvzh!OSpU~-si|tcwYS@&Q)f9L`HefI1w0oCNBXQ471?{~{@J(O zs{SW@CDbnd&FxzME6np?yVeTp<%>W4Yujkem6h~wO6clO40{(Ic9)svK5I93AlP33 D!vzeE literal 0 HcmV?d00001 diff --git a/extensions/lib/arm/noattach.so b/extensions/lib/arm/noattach.so new file mode 100755 index 0000000000000000000000000000000000000000..ba61056d54e4c54619c4af73ddf6d95d2f89db8d GIT binary patch literal 69440 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 literal 0 HcmV?d00001 diff --git a/extensions/lib/noattach.dll b/extensions/lib/noattach.dll new file mode 100644 index 0000000000000000000000000000000000000000..6767a4cec16aa385d1c35284def220127015a8a1 GIT binary patch literal 102912 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

n(?L%mguy&@V7KIRfE%zr(!uan64HA7}!L zgTsUQsE791(y!fqER8RhFf%Ze=rzA&DN$&C$y*|1eYS+vqx&`rmm%{)5|F@L26lY}MZv~&ga^gQIR2V#v z{WU8X)MP&9+v}qu;L~fH&CST*xDQmu`Si*-cpiMr;>v-_f>g=C4HMHFL+r3?Qy zCQ#+)Vtt@o#kDtp(XsItD1?f|9lO|Fn2$PgxEM*eFkgkLDSH5_EG(o-4|z5p!ba(bX{j1OJ^QO<9o1YHJjhFlt?$f=Plv2{#&Z#(Jkv*3-PC{35X%!(JiYCVz7I3 z%L;+kqiWxSMyW?{7!Noiy?bqx`M0}>|48d(^5_j>0)^*$&@!`g-~a!A%>iQRdvj-M1V;%SI0UR7N|u7Jvt21%jv%8 zxDyoc#wT5k54@}bue$@yEBzPMO9RC%>vU1jRE#EsGf5P>q7!rs=9wL9?lCY}pD6b) zaoJ&f1k98#vFtwB{6ee5NSEmd14D^6=gb>7W+|552OW62#ePVyj z1UhHPMa9Fl<&sag4`@35fDgaxaUXuy^Ch4K69d#a_vn6|W@%6&3thOMW?ACOQ2NcIH^-I1 zqxmRPnq?_N>0{8`s)dL4YY=S!685+ff5x3Tc9QDt(Qt?45!J;2P{XH=c>)*wK9@_UkdU-5-x(^#)dU4qg?nndB4j$xc5#hWu zFF|)Qf#$X#bJ@^63#@4g%NbjvoGivRnRskpI%*^#{d7j?L52Z{AHNP z$S?s^q4RlI-{5ZrEn0pFx)i~)d(Gbq-@*N(?z6D-RPQE&TnB1f^0zX84y+f=P6X|I z3orHTjo9GPeHPT>?-g|`W?*=scoh^MB?b_oI1ra=k|WkqQ~y@FUoHJ|KFUVlEC26YZ_<3$gmgW9#Eqy zq5G;!ulqL-&t-h=8^u9Y6RBG@aIbL?QZRvJV5p4pkbd3ZC7EUg&!>FuXPbtqM5%0=#D8 z1d6#JJs@LSAd6~1D^&iAUXBMvWDIE03eubqXlpj4tN@n~p!2o$K;s0UnMzRb8-s!$ z6st$7!G7FY4G#Qm)u31vd0_|Y(X}2Z;QVqgGO@uy#au9pGTs|KK01&yJA z;uYNe1|?X7U7)n?(aW2r3)&wCS`zSIR4X2oa$(o6fz*3+v&Mp!ih?ErKsC4$$T12& zy}axY$NZ=QJLYE<$T7?>HiG635jz`TdsJIamg;--%Kiq8M|5+8hN=WSKnuv&{)_Gh z4N^BNGk_;Ods!!dMo+A7l->ZhuffYn;3bwvH)|muBLisL30Mr|zW<_aap2_~9-XWq zeBe88K<#h18n8kr;nA#W06IAjv>yd3ghF|AvkHRD$6lW`z5%5PP>Jo);nM4r@gmm~ zeG2ns!G#ASfl_dTa$jmutuoBdU?*X-*lO;TQ3t09ufaa)}?^#;#`&e|J ze{oEMfx+5#i6A2bzrXEVP+#hQNrGedJCA1T|0V7o&DQ@)9KW$Kme_n_<0$3z=;r<} zx;z#XMI~Au-A8?TSu?>Qde-CMPqyX<_MY85Cp>yZ4uHlBJ6$enbg^}~T(t1`f7Iju zF>v@czh^964C>>7yn_7qgaFbJWRNlzy!+&Z&s9*T%=qLBVRevON_oKR$zNRj_y7N9 zMu?KytN;IZK{v!8)n=(J_w z1CNwUg&L0GYL9N-$R7+0FQ^!49#I)fi+U_>6>Z+2f!b z40d-n{|hS&qkX#XfQmWL;z|bJUT*>4US|%_K#yl{umtFMQqNv*ju-tP3!(LGCvPgq z#7^Ec2$c?@GI${cCnyY{XO$o=ZE)zm2|6)Mu|}oBaT_COTDqY7V)HAe5_J#}1R`WX zgh%r$<`U=TS1cub&9B%>IGcYl^0$HxrD%T1#NV<7bac~87XFqAU&*VY@v5b)@=4FWOPJ$h{oc|dE~--1TRxEyx(4SK%UBpS0Au=GP8Sh^Zo$y zz#a!RJv2P54}v;Q383R=4hXz{?a|Hp^ed=C%>J4U;sTJ1xgh)EUS9yM%=yO%?s?7p z_y0f04v`lv=l=ii4iEtK zyxsz`fTP!s`9;r#|NkKt$?g09e*$P-GbcA_eIrKN_XOQa!v(%~dV)uHFbAkag50VV z)9ooTq5I&$7rZMNOZ>YJsxaFym9l<2c%YPvf7e6qB9{M5uPr>fodp^!7)k{o`nnxO zCR}{6f)R8;47W!&=Zo*4S)d>PK@&~R9RC?!vwL(qOEh!*_vq$-VGp|R5|LFw=^wJ^ zEi4>-z)%8sYVboh*Ne>a;3$`k1&zxlv-)u{GWhhGfJayipdO7!H#ewRsNm5p z1}e*ykex4z?0i13^Ev)AfhykDyF9wX1U$O^K>K<@W3=Go)4=Bocz}!x0G*f=0U9t- zfW$Iva90DQ*a0+_Yv9q_18%gwnEMZuy1V&b@SF#ga`0u_367vkkI$Sr)8V7S0bN$^ z(3}cBm_(yFRROdm3bZBd1!%__WW_yrhu9P7fh9jcJEC@g7ScdAbG^9m@BjaXS^!Kh zDHmuf5~8LCR~X><1ohnopgv9jFQf-u^JKdlwAB9?wzc%Heu9o{c>!MJcLQ{99q3Si zqoC!fKVBPo^oAaI0XjSfw4n%eet`nSE!-;@K?BXFU#tOLr*z`QK}ApvR(jX?e*^wy z_bErQEW7sy3#x!>&H~Ubp&IZpO$nd?-pKgU5_D<`_I7CV8-;GxjqHpJ#<%x_HvF|7 zC}juFcfDq_K3>bweY}%(GCL!KNAd~qdgmA0EAfGIUWn=b9}Enhy?zF+#s?rb zdf9yfrAAhHc2Krqy}$$-3%}}d@E4m;rwOx1_fb&&+RJmmvzz6DN4L)j4ba%H2k78I zw&QG|cA3Zjqn^#jB0$;215CeXES-lL>lp2`7iU5DnYrjPFn~6}@XlugS0gwO2Je9+*(sA3?f{d1VZqxrW)=|zuj-U2p8h8MyhuQsbDvw;S`K|Ny7`t*Ya z9{*Jz27vmm&0zLj5F6BvfMG~`1eEfde?BO;@n}7{1Kjh4tVPe`1|<*B73Qa3d;%Xe z2RgrlcReF$M&U4Mk(CU{F|7wmuDs@b@#X@k_5v-YLo7sxna{eL738N|9+pfcVvw~o zt*q`p7#K=9UTA=}K6WyLx_IDuYN(!G)^>;-9QX)cx~9<_-s-Ci7y%|99Iv>mNq)~GplAMj|I`DH z-KRkPe^9Zc@FMReXb7uR7*r>DBztgpSidadcd;mA1kIB z5zE-S1dR{0T&iFJ-3!}wNacaefl@Z`ArXhW4yk;wc~Hs*Ze|{CKJmZd(T|2-A9_7l z`CSekb_j+nriL830h+)nddmP=gbBJyt9y$I=rmuCURh^mP%G+*N3U&g1OtO_>q(F9 zLq6TVJo#O3dbD10?9EYO^yGJa;lc0v%j5eEU+Hf?${#&i-$sJv`@KqodB;U zxcun-SdwqwIjM*gNv zp!r*?6a399K@9$FH+`({x^`do;dj3JT8@7kc%{Zcl>;^n{H>sNZ1tyB1=?EnA&dz%DVOZ_Q88%z`TsuyLmBJNzo0zbdb@-m@jwf{u0d=)MWgz?(r^pSt&e2gF<~^h-G)E7D)fx>)2h zf_O}z&8Ylc?o6Pyv7$Zx@CBF0|8r@M+y~M+nRonWW?)ED zKH<@Pm}v*Y9R`Lp?h_!tGXDaJcr?FbovS`a#2apkY7o1xwu?z21x- z%s)Juf3SG)yPo#wjbwbikuv%<=kKH~)*IBcNg#v|G8mM8(6S`G^5% zJQ7@VwX=%;XJ9xC>*s>z{BZVjLGu+5r=I!n-%-G$yAgCdA1L~n!RrDV!3XKL9w>ow zLHFAu$$|$wVY0oB7LGeWv)&%PqOU>zu?+YCT6_#TNC>2#$)maA1$aGJzz@(FD9j%~ zP5A=~;I%2IJ-RzVcR#$WWCXPjK>Zzz_HZNUgg{W^p!GmWrAIICybqw|=?6=4J-VA= z&Q1iKVi@Dm-3@X0$r7<1#+RV^_7@UhHQk_l6!wEkArI~IFIXUA;Oh;v&%gM3 z0_+%&F)v<1*dV`y&pq_$-3+=5V=p8it1UcwS?9fDVDPYX{{T87lpoYb5(4>&_r*G} zR=yX@Ky-8c3kFbQ+W!Yg1s6yK>x&++%rOp+=Hm(;&2Je?H-gS61NYrfTm3JSPW=CW z<_t)yj7Kl)mlROQo+uFjC#Vnn2ODER(@F;pgHEQa2cK_LVhG;H=h4f09HhAWCg}cP ziEgmM39Sc8d0!}l1M&0=cCaHr$6$cXmja!a3({hJqJ$5!S_Q1>{|T7s@chN!G7VHG zHJ|+d!G+NiId!spaA5=;r2>iN10^s%Bu){0P!NOCD?}bSg?fT2Tu=(-@cT%-qXV2qPeRk^3sczW5IBE>=NMiz?gJgHxdSv%16f_v&HC*v14HWx zP#;+O=)phnyp&`3qK07L0rk6za2 zuRxJ|qvRq;W)kSGo#T*34%9MOWBkmSGu^D`elajifRFuy2F^f($f7U$j>5~m+lL|L z9!ERxf?uGD0a~D(IdcX+AlCTC15|)@vvxg!wsTrk1Xw`3O&)@`{`>+TUwyJv3gju# z7X}E^YY+eb|5Aq;)cE;U^31pONy$UdS@Gvoz;mFWE&h%>K7bbd8W=)EdQ?D*RG@;= zh71gz&HtJBn_e<8FnIny@6kC&#Q|h7|N4I(ooiGqKy2o}pwsycz(>$|bna2n0J#-Z zV1w?RJnpG|)bsl{kKPDIkLKST{OzDIDqrirWvSl1CVHOTcRjlQd0KxjSKyat0JSK( z&pZCV(t5z7`@9Fg-)T?ge;(a8J+1$jJ@)NB2D+il`hJO=r}lk*c^3u-@LCrh;SLtz z4la-0AVzR9d*!SB&)52I`4Z4t5(SUumyDnR4F&!VHqg?g?wm6QKHYoHfIRs!29yvl zzV_@s>&d_Vo>#Apwnz7Mu=REN;A_l|`&hp(QGwq-?#RE50d$zP_GSKUTpdh~9UPwj z4}h0XKLt6h`z%DS0mP}k*6&MHeY?;4YMp55QmCU{u?E|d0TzUN_mzgQS_ghTgfh>Kpo zmgJXrVDMzV=V^VvoEJsPqx+qw_BRjf?`072b6_p?FFdS27g_j%&Ud+1BInb6+DH2w zF8e*K|9NyD_TYB~Z3TZ>1`1W{zr_+0Jhk6>Sidjh2ipe;oRZhCMLo6Od0M}PS_cyb z-CWvz)Ix1CPtI_tcep@W+)0uO|z@u{wIMP6;NP^Oqr}cgQW>8bnr~CEG z$$$U<_q4uWEb7r2bH>1@6B55Lr9Reg`I|q3Ctm-)%m6pkwy1!Tt4B8^1%r+n0Htcs zy$ayO+uZ}sUZ90YGe8?k8;^kUA8dvkJOYPw)`cr5o!{{3zUA9`veXc?C)yB{4@F+A zIQaknZcyW$rem^}U;YB^A{5uD=Rz1Hhu5%%c*4ilaQ5-wr$0L`vF z^=$=RnDgI*-vzVLyrH??xCTMGe@tGG!piTqm zKm^b31Fv7gicoO<0BVX#goDnF?=|&~2OUxRh~K08mZ$bD(DvC|KHUfT!*6@`I{p95 zpU>^l{DZH&xVxoo4(LQW=41aKr12NuWPF_fqL^Msf+*(KK_H6dwKs@jeeD9G*k0R$ zDE8N8Ad2I)K8WIctpTFAUMqqq?$=Tvis!X3h~jRL1r_)1kGcBxJ)1}6L_O8h|3J(GQR{>@*pk?h|BU4)FT9O z!R}&xT@7Nhfuz`8=Y!bnAU6B!WDuJJ#O8P%4q|hH*qq=%`N;)hbG^0)iF1S4+^>y6 zY_OMkUaN!HydZJj*U}(1ABfHOnjgdl5jXi?GxLX^Z2iyQ`jCNv;WK}Jus|Ar{-HGf zlEaX|DK+)%zU&D)sWL`I0JKO}A^zpmzyJS(!s>#9MKvRT3+R$$PN5_rEDU#F(=7yn{<9S5SA!M^;( z@;U&-V}0!jqS#(LfhhLZ)*y=GwF!vge60(jxL&J)DDKztAd2U;1c>5&EeN9cUV}pD z7uc7V_`^03)gcdU}NG@hzP*}{spuU)aL2oewgXv-h2AjnU49<%|D-RBU zCZND~n1T1GIDjTHyTQjrh`gAz2j2F%4?3;q!0QB1o9#Jh+1Mvg_1X*CPxIn9sF4pE zM(7Rx-(1PTP@>}T|CERIuW~N_ZA{->I3!t0-+`Lr+NV6aFE>AA^w7TO@&6RorJUf? zMFK#B2Jwd-LgB5d<~IqTd*lr~I%5+&I!iM=I%^9&x>?n3gNnJM9-XclF5RzO!Anbh zyB~P;`f|JoI{yEE_g>Iao!0-Q>>k~&0^Jon-{*pwt*+hYeY=lzpO?PWoT8$^0NKyo z{D|ZKp%;Iyf`*Mi2T-sZ|9=U(Sk<%pn+NkZ&_!k*)*n2iPkJby;BNt4Tj^_GjiXyN4|8IQBCmFoRy%^Nk?LO|oe82;AJFfLX z59tFQ$_M#dY(Wx;_^^dVl?T6v^@(z3POn{}Id-3WvFeD=(~Xg0z6oK!MyD=ePspbl27gC4t?p1t7C> zK(`xx;O~#cXQqpahGX{?k8alt(5#@si^n%W=7Np_=Wo?!WMFs++WrPw5z2hhqt{Wu z!}&p{S>bc5#S5utTl z0IU*p<1WanSc9Pi;$+ZB-3t@2b6XFT#C5wCxPW%LhNwWczlNw7ID!}Kih+*$02!w6 z;@YME|3O|Wm3plQ9zBP9dk<8mMB1a*AC?jHUc~PB|NphRNB1ue(1qVfQmikWcKrWu z{0(%;%dPHDpe%`+g_L*v{|{&TATup?oXbeW3VndcK`6`1?_-eedz!HZs_G{y*?@tpoJMe;8lj8vl(2#m!VpC zbYFws(+ry21+6CppE(BdYIh5G1icfq5jgtK|NoGE-8`U1c>r`PB4~j`0c6Eiv4m&$ zW6<~+sDJxH`t1Mz{M!yRe*hi71YZ6QYtDhsx&k$iC13PygVzDKw}93JocIs!_QK9J zl6np*y^d&j{8tS(XJCMu@Nze(H45c`)`fw_xxnKGi28-gqx;m0&!DB%;86qi7st2# z|NmOhqxtuPGTj$qV0)pnTHt{k@TBdFpbwxqk&^o!-KSq%yA5Vv_UPuF{0uZJ3_AP^ zG(C0|bP{yyfs%`_k3i3gMH*vsgiJ;#K=y){cpKmL>9w65^8f$7#|#V%y)1H$J3<*4 z7-o8OpVvNg@rOt93!m<zKr~yH?8m0 z9fq_Nkmpd~2X1>Ow|uuyWn^eQP;t}4_6Y+6L-9oq<^zu1Eypi#F*3Y921_f@wbbCX zs|ve3Ku+@d@j`nmC|N=ap=giZ6%3#y>efd~d^~z93_N=MFTiJ0KU@JtlmCzZ9=-m2 z4e7i;x{rBunjd%PU|`_lI_A#9<}_2zh{Z0lhT_ zC641B9@hWBO@J3qKuHK3n}}mb5k`Tgrz9Lf$;6=hW8+WIipL_&7d%`3|KAOo9_y5N z5wQt$U<9bG=>Tefd4P@}12q>69ODlg|L^r@e{pZ^|Nj%Z?{~9yzJQK2TYsoA^Xav% ze8RxsX=!u6gz2@?iwU4J7CKq(gVz7B_Ezw`7U^b9?&V2Z;e1>x?pu&_|%;Rs{`c; zaM=LyH~8LqkK~)JCo77qWlue4U?|S==sxVzYYIx3pgHjF&mITgv3c~`fTqH~eRKI? z!3bLFS@T2Ve~JAI1?VL(>aDj+#I$dea9iIfmBzAE5|lyq7=zY`vwZVt_W7al-}u05 zu@_4>figNMoL`h}`v1RK0dyuhD5Rk$NF&`_4;i;?{`s#|^o18h?Ta+H_Sb%`Co7Ds zc{xBn(DFz=>C?;l=MiWO@E~Zt-N6@Z9=#$bL811|<$?uc3A;zP%LR?sGB5sb1Y7$; z8gA5!j18c)3@vg%X%7@;@F@n++Bnbd8{J$lKnEF204?!J=J4pg2)Zxi;14#RUe=aJ z3=E*C>Jp%6 z^Pra65syw+anJ4#KAo=neUd+cW*oX*>pePMmwR>}^X-1;dGIfrPiO9Nk6zwt|NsA+ zAK3f!+8preZh3iNA|r!Wx62O=k51R;uH6rPnIHIcrq2H_T5ZU{(CNAz)Zq_Z?r2e^ zQOe`led-0z;{X4Bxbp;`>Px@>|Gj#7{(=^VdNcRj0XfOR z!m@<#{~^!+$2|TY^lbjeTJzSo^&5ZRYX$}e@9vg2AT>_>+kAf5x$*B?qUg}c$l&<@ zh-3E=?L(ce>wUUi=lf_M^GQD8Ykh*hzZbM`zWcmSFKZpxDiNqvQ*MBa>0;_|;r$O9 zxcYy{)B0S^d*9ZRb+R74zW+U$&-r#A^yt3!!c87jDTOZg>1DO{`~Tmg`?^;z&oA%p zmKPus96D+k?L0ubuhl&F=&U{O(d+u(qto?z_i@MOKP>!H4*Wmh(*3}t`+!eph>C(w zukU$}-cZodL6cvsc?8NAKmPN#fLg%auIvAw@JK%4!Tj+h6KEIbHa0*0eQOlJ{_FK+ z^y&7U@1uRrBl)1G^+EprSKx+Y?Rt;S()-=Vn}5Qr`haBBdXL`F`yRc%lV3Q(t>OT+ zshPjJc0cp!&OQDTbXB-duWX|4|Ns8oEw4dda_;i^Vf*bMONpX$m&*^k4p(+iJaRNV z{O#P~^TQT$EQLpJDEn(q7yfO0p50Co9^D*iPL?*FwT3>uWsE-7rStilYZyTT=BJ>_ zyRU)W!FUgHGjdBK__UyJucblVqV8+H-KW6v5AQe*6tPdCQdsu%hng$AnPg)ENpwo4t+C9LO2A*YS0)>hlG*r%F4HXY)uy|bj?b&^f`L;{<;s2st+E~M;4HP!lG_i!u zPa)9aKVrfLyx)CC0VtiYfYKH?e5_8w!zTe0%Aj;|)3f`KYxhS;eabuI79@OpnLqe; z|M2Yo;n59CDk+ep0;+F(t&j0HgYIAhMRkq{AL|oE=Rt`Dbc8hMU?Xr~fokUfAMF#MLMD_Kw5_K_g@K)c!Smuz z&`whq6$S7yM=y+y{QuwmqV+&YAm|o=5{u>(70_AMQ^1Nrrh*pPf;N<$bLl?n!F1;*k<6_ebcr3g-7zo=70Z6bsdj6S}-~` zCz>!g9&-e(S#i_>H4~dp{0B7;3qWf!U>QE{aO=qmerr>ny9^A)?BGdt(ACMU2TF}` zm;x#tG$8(W1@G7f?WldRW9k3@ujhGmAM@${=Xvlyn@2D2&KnF2;1-C=0k3YBpHAOg z9#}Aztn5DbBKZqwuHoE&k6zX(Hy9Yax>s89E4 zSI}C%5S5JXb1y_eOT4;2bf0_S3^J$t*h@7?-xcXBLC0{&Rgf9R|6RL3_$0ps_u@af zf+~%Vpk_krrBZXS2SJw=c2=4gUjhe}@kz(yjyj-uC0EdCg)u4`;40z8%_ZPg+so~s z8nyeVM=$T~>tNscc0ctz_=gSB%;I_I)aCNivcvVnzY{i$<(!V)$G%@!!B{fQ>6^<> z3kA@j#*W=*U3#6EUff{^oj!2ZqqFwGiyUU?R?GJ5prpg!BFzYD{jfZ6vhev~!Qacn z$iQIXtx+ln>OvRK1TFFP>1B<&4r-x0OL$mzfR{4zdv`;0Sn{{rVqjqC^!?z`8~VY! zo9BU7x6efmDb){yzp%@c+1H^Km9$>pw-CU*2J0VE8W@rwVF(UI5?Y}J-d&B3X$fA_MY7$2RwRt zPC8iBoU*75h4`z)4CE(Su%DVi3;nv!fz0&jJ_a&Y<=6lJua|@D>-D_=71R0s|NraB zsA6A!{Qv*52Hf-TIi&%*&l5CUaLq%}MMc3C)JF&1^m60Br~&vMgi_A`qJ1i0|8&>h z_{1;Zdf^klpz8ylUe@(jK~d%Uz~kTxh1LV5Io+-gS`U=yfNrZ5M@#UX&L-d~*KXej zpc82-m;C?#vKcf5+l}I97Ojs94Jy-(+AY$@575 z?a|Gu4;n7+W&w>9mNLB#?REey+Xrptko4&06#`50{Ctti2HN5Mzl7yK=uo$A)}J>( zzUTP?S(V)l8jS4beF72u`J#CVsGZGv1;lSw`N8o2@ar~+OC;z0|KANZA_lRJ46^3A z+fl@$`{uzHyc1S1mS}+Xh#Y*uwt}%l)}z~#4Ved+pSEvO>?Am*oZnL$R7i@=1?g(I1yV4oCEXc}{wCvmD~z z=5oTK`GLc0p%=<d0S3_&Y*Zvx)>B1-U=Spyj2j9WQd4{hc#~jL?jR*V&GxTn+6fF zhlp5sSo6j}M06n{4j$ILK@bsXh=_-WHLnLmgcBl?;bF}i1`+wb2yABv z!9zZK*})5=ZgyXNu@qD~^mmBKHwLG0e{1W*V1DrEelw|fSJrw`KK+YLIy zy8GG-MF;f>?l;`<74lMc>u~rJ$R@9r?F&`Su1eIr488_U(;k>UG@T{6o^E*HfX_X}=4< z`^n}XlD%FEj@<|O-A`#BEai4>Jz2sAT4qst_^KLya-L^tSS&;Ozm6hPH&snCDXYjU6+ zf1m=FWB&jDuTO#2Pb+{I9PbCMMeb#Ndmb_@)qNhc{n`UOI>mFMA?2dQUr>@k9Y6*x zczp?4&wl32nKV#S4Lo@NixFg7iAr;diUs%{W()8lcF;JH!3$p|up~SGb{7?c*Q`7K z{|Al39?^i_n=Ihb=>bl?2B0aB?wg>Iem!Wh0&1*ybOwCzQ1o~KYmmLroC9vJfZXN* zYVO4!h7^)KDvTxUFIKZKFuZ>7g5@lDy&ve{i5K9-6F)!=j9+KKqo<&8c+f0n1cygw z0i>2d*sTh(5Y$2f+j#)VCB~Ottep+E`*moyqe%0)|Ikv}_Qgig8g5~+I;T+YhjOWZ_pa%60R3%^FUFWtib?s*jLcO>EP2?phL;f zrNyvu_!{^H;0fS;Va>M7K-~tco5HRhM&1+#+5`r=H>9EV1ylDA(8)5s2cUB?sF$j= z^<&xHRR|Wuy1NT8p8~G8K-(#lkAVg-J(_>~E7b#)D+VsT&di;lhGs7>dktuU|0L)> zbA??D3=9tcMZd^`2E|$59tEX`AO9hHsGE;~52^$uE01p8i(t8*f6Lkai=G832W3yR zeK(*XdIyi@gc}T=-9LQ0Pjr6*pXB!vJod`le-zXh+bIniPHjCz41wq13>yUjyr*SNT5@OTMC z2WU?hx}dhxQNW|qQO2Xw zQKQ{a1ms}|AvEtInT6vCv;WfKUH*3K;&?%{o-wrUA zm>QqtU)21Ay++IU&kyYay zC?kWoU}wV#pJYcHSL2gD%m;nCFFEpWcMx&q-yXpRIQc@bEuH$@4o5LYnx*Zs@KoIFkt}2Rf!Vl z45{wRpyk+2pcX>wffD|12bF^_~AAIm( zKH+10%Cq}q^h;R=_{=v_pq)Xi2llY$t=z@{+J=7cpg`L9ga7}RG9LCgcv9fyKCsr8 z*-T&)(8^hl&I$$aR&xc% z1>JIU!-e^PORF!886?$iH8kBNc`^ajvaW%r3)oGj4Oo;?1m)_}x7c>=WX6nZ(<2FUa{JGdw~tLf3p zt9OQh;RR@i94J3ncyzLgo&^n*xu{rpG#}vb=ww}b1{AZb|3FkHYd&a5xZ6d=!K0J4 z_zVNXaaPaM3=AM^kFz?T25oQyiTOfV;BDs~*#{UrdU;(zI*+q3g0_Pp#JhR_ZUI$$ zJ}e3_K}L^mUX86#L62VEoL&Zo7odapLHn63K;aMuO6?9F-8cV>E(eW{c5eo4sWJW! zzP2y~bPm(G|DsbtGOY(nEI}8zr{?iwjdrIM)g`4B}`c65)Q(SzSmHP$rVRYLh5913+aU6ta90UU_u&;h=TfKRvrod|u_* zeGqg}+(FPq)4igbjX-N&E_v=|gaRM_^|#VI`ST8YHviz~Z*K+-X2~;nGM{ko?rCy} zVr1}TKIQoTp-*SzN0-jXpJ^_gk$+t}BL5%u>5Tm3(i!;+B=YZY8U*mmgGS#O7<@V- zKf82B{syb$mk05`xO7JT0qOb*(g8Q)J6MTNXXH1K@IR1(ABQKT@#h@yZ2qB8&hweS zp7FC2f4vLihr`Xb&6^k)nE9JPhbjA5v({~5U?>ywv1YB^#K2I_`;Ap)F9QP;f9t=0 z|NkF(Tq|*a(Wm>QXY)gO&*qm3p4ulpwJ-WIAM|Ye0U9wVOZBm4b=kzgz~6ojv>F=h z0hs%b{;g*``nTRu0Yo@}h=ikm>l;CpIEV(Vas|-`7#J8pG-&^rN8>?|v7U`DAQae= z;%&aY9`c^e4hla4vvQ2f!5LgQNfI8IJxahr|HF{m&VX{(TN||8qwN5G-{(;GKW~J%|9KkYf`RD`nm&@t4M5&zQzv?59t3IjYV`5{c8(B=dMd*&AyAcdp< z@}nG%{>x7Sl`ot}|JDbBikwJLk&~Ek^k04#C`BIqmp=)dW&h>R0%zHO`HMhB&e6a1 zonZOD^%KGJf9q$0<^R?%1j$2-B#*{JkRl1WWa4kG`2YVumeR=}8dT;(OQ-xEE?DW* z11qQUd$=I^yso~76Uxf(;ezCNkQkJe-@^sT`yeqWE8m9;T#EUC3$uJ5E^uMy11{6@ zeYn77f)6K{%0VjHCSVP(=bT6XJ_m)@b5M9aCnmg}L&NJiG`yZe!|OTu;T3{4ylS6g zh8IW-J-k3-=-~wtLkX|i=g8p&;(>w<5?&x4a(KauQc!Y(?*{~>TMkHh%CHTbuxI`L z588*s1j;WtOdmWO!DSzRTOVj*2wZDoFJ}wE`x(JGjXys~;4^=Il)`8J{3KBM%9+Mr z9|$UPBSA%OqQPhWd@qO3{P{rvAY}<4Wd&*c^`4+&I1p3}M}mssL|8HG(Rc`yn$b$* zDOgJ53V4`t?R7r0RN;RI2j6b32=d^kZxbiNN4xQO=Q1W};ygUEpj z?0g?CaDnZ^38M0SxWMJM4=0$)ffnEJ@Z=W|^3cBM$$Wxez(w$b2dF}7ej)JfAb*L3 zPxncW=7%5n1y1k_un0Qx3v&8&AN0{a;M;w|^WaPNl0tq>#@Axt*g>@K_%$5`_%%7f zrtu5-2tM#=dOhuQTI)XAWAe=UUJmn&HvyoABb34a6h^h)G}_#wQysSQ!`&@J~6| zeGnub404hN$hb~l3y)4;gNE7&hLRlcEz_XeB78MGx?MFIEx^5sP!PMhLV~5#8^mg? zP*7lAg$o( zsqU%ZsjF_z7i$v#|9|n=9W?BmP{4596*Nb~aNN}eG^W(;>H_Zlf!zrTJOzj=BYb*Y z6+F79f;IrWa8H2*Jvb5(LEPyp&J~h;7~v^CIe=S4T>?~8$KZBE2Bz)axX-J z3nT%_=AdyQn4!ieA=0nwk=+Foy^12*P+P!I!VNjbaCbeHumE`!?$eK(kxlgI?ggbf znEPu`3@LFo`EodBhCpmZISo&cqnLFqkE`Wlq}0HyyxX|8gJza^lw5|nm; z(m_x<2}+kh=@uwG2}&=4(i@=kJ}7+-NsntOd*tp?88NnDe|c1C%l62K}VK?v=l)3 zp!xyCuYmGl@*PkJ$`3@wmY0F)0i zKLW}Jr4^8T43rNVXb15V(D*4(K1_WEln+y%gT^mF<5xiWu<&nz@?rWrpnRD5Jy1SO zegYbQ3X~61KLd?F2aUe~$_Gunf&8}w%7^J+fyQ5h#@_(t!`!n4%7^LS0p-Kw_dxkD z`2$csO#TRz50gKE#y^9`zX0XK^j|^a-$3KvLE}F_<3B;;zd+-^f%0MD^#P6l18pnT9;N087A zC?7Pj2jcI5@?r8fpnRD84=5idFYy-Qer1qm(9#PiUkb`kfbzlp6$S=|4k%w9D!&5C zSA+5|K>0BJAE12DIVNBw?;!TU!k-1o2W@)+$qPXFF!c&hKFobCP(G|Y3V`xq2eGk*t^4@+McpnO>Pe1P&Lq4uGhk6yl^mrv;V8@)V0FQ3rUzraUGcz_na zgPaf_pOjdfngRCzhK<+6`DN!g& zEh#O^%LGMJf~yBZLQqJEC)gDXuy}>13TQk-`PdBxrGHquhD1mzjLVRapPQGd07^r} znV?jWfCwZ=PC<@Tko(Z(qhnE2B;+RMC8npQ5DHXubyx!xWFK<;poJVF^ikpw7XElt zGcY8iROTh-W+p3S=4F;-Cgy;;5(;VgMGCNV0h3QGNv+5%K}!C}szB)rT+At8L@To6 zK>mOxGNK#@QjZaic)bHl7ts7(l2MeJn1Yn;8DQm^f|3%rDuwft^WziC6EmU3C|sS5 zEvOV@U{DCDEJ#&wNi9w;$}A|!FMv6nyfNLFF)55)>|pdHH#jx%s8V z3VDgSsl^3}$>8z^nmrga86fo=j1QyX?H|_3u&Ng(MHl)3wBA+t1aV&ilul$QV8~?9 zWyobHX3%9QXUJs8W6)(tX2@qKVn}7sWk_SlWJqF2Whes6=P(#D=t42X*@W~LGgLC< zF(fl&Fz7NsbQ>|~G8jNKGcYh@gU!xkNM*=jFlK<&x(p1c=0cQ%+VE~U#f~{S`Nrsrf@U&cZ9R}y zSq6p!u)Z*eKMjrF%fN5|)|UXu_o4Co(fAY4_!H6ilhF8+(fC`KQ0?1_#)q|IVeNld zyB##%4{{$e28A_88YAd*6|gX_eG$*IM~3=G)JgP6(yw-;m+HgzEJ7io+PkP-y4-0wgDB%Wbr z@C2gr8=4^eFHrgiR6UG75(Sahh=$Ms%@Dc)O2f?cftniwRlfjAZ)k<6e*>i*sv&%s z`6cBLKFk~#4U>oQr$Ehz@k5||n7ThucVB_hFmX_rfOckp@(2in;u%DP(kN&dEGTY3 zi(NteH&EPz`o*9$0ZOAF8YBjyLE}RpIZ#@M$$`uT=>^fC@)2Y%XgMKB4Aj2?^HAAZ>aHb_Vd}xgFmj@i+rYuYl4!pmY{PB7-i2 z7X!$jpg61om#EGRejpCG9L;CYW$)MPL`FG88iuGn6o7fZHjF3@K>s6HwTJTusP4kQqhb zR!=&-g#rpgSPO-){z`^ou>Ld#P!2>7HA4C!DX@s41gq_Y!@B|;3Xn7p3QLWJNgBC zg4pdcVWCo{RyJr&jn3rQ`?&CE*#HHLjtOEU5y17aWz3=9kcjL>#8l$L!_2<|<==tQPoVS%D9ykG2^S71EdixfptJ^*Hh|I&P&xui zgW74JAkKjD3!roblx~319Z-4#l%4^l7eMI^Q2GFrz5u0PKxqbMh&u(Kv<8$mfYKIF z+5t*?KNO zei^bb$UZpV(U*ZCz!zi^1B0)xeoBgdCD>e$NJ>gdijIP>udlBHh*4PymGbbg%FVR` z_1HkF7#M=VJjAQ}`Gjtr#?=?ox$q=Ne*{tU?sps4U; z$Y&@69T3Ej$^eR4i20>pQ$gmqF@Wp=)e<0kKq4SlK244n!h7^Vr27QJ~B=>+sKv;)CfdQljgcZQ*Kq4TOAk4tv!QjDQ z#gNO8%U}g=8G_6N;Z$&2Hk1L>9|ZA7I#ysnhZ+nph%SST@4+B|7q&29LR1}%3<$`` zKpaFip@{(jnHY$JF#X`6=MkL*8XB9LTUy)NJ370%dwTo&Crq3)dCJsj(`U?_HG9t7 zdGi-6T(o$}(q+q6tX#Ev&DwSAH*DOrdCS&q+js2TwR_Lreftj_JaqWT(PPI?oIG{< z%-M72FI>EI`O4L6*Kgdsb^FfUd-oqaeDwIq(`V0LynOZg&D(eHKYaZ3`ODXD-+%o4 z_507?fBzX6nV4Bv+1NQaxwv_F`S=9{g@i>!#l$5frKDwK<>VC46?PY~Y$$_I^cg7_X#K4`2H z#1DY-L1T#^egu>c8e;_U6QF$1*dd6Y0p)|nPC@(vC?7PY2;x^j`LJ~{4NyL492F$r z0p)|nQ$hR*P(Emk6vUqa<%9ZsApQa$_I^!g7^oZ ze9)LMh<^gghfQ`}fbwDMYHmRJuyrdBpnT9+EJ*(gC?B@Y=>wE62a;r9VE6&$!`3Y^ zNI~KgR>E^Y`Ji!QkQMrm~@?rCW z4p2U5Oc*5Z0p)|%ZGiXzP(Eng28bU4<%8B}fcObeK4@(Rh@S!FgVuI{_ythD8HmHc zz)%6@n?v~xP`(9}-vQ-YLirP*e8{XS1H%j`-ySNz0LpiO@>f9lpmBDP&;}?UG~N#4 z?||~b0|5*S33W&0>A*u2i+12 zQsMyRGehMApnMi6A2x2!3gst2<=LS80w|vy%5Q-3IiUOrP(CM=59@z&L-`A!@;p%f z1}L8w%0B?*^FjF+pnQHP{{fT_x*`(fpAS&JAXFYUA0Y(g!{#G|p?n4zNO+4t`2tYB zD3q@N<%>c222j2Pl8sR-gn zK>3bP^%+pUGn8Ke<-0)n6QF!oD1QNz?*`>>fb!j;`~y(FCzO8y%J+iuA3*uuQ2qxf z-v`QPkcar!56TyS^8KNF1t>oN$~S=WgP?o|C_fC!4}kK+q5K3WKMKk(fbvtJ{01mL z8_J&m<>x^83!wZ)D1QT#&j@XR9Dwp!pnTXoBRiCT0V>Z4p9{)2fbw~ud981Ip)u@@GK# z)=>TmD4!9!IAsTv&k5z9fbzMZ{2Nd{Bea3}0?Oxv@_#`2Tu?rT3dH}6(1}k8D4!F` z*MRc5pnMA`pAkCQ>;dI-LirI;J{Odq0p&A78>kgfJ{OeV0p&A-7BMq0FwB7RxuE(FuZ{AeIWcFFg~;a$)O7IKMQD)Gy?;J1e7lY zfW+(;;gU6jg4A8tDhz6~5gV3PSV$l2~ zL>*||07yIyJZj9qkO3b32GO8VZw7`;sCk*-(P0J#(0UM%`fP@L5XF!O9pTM`@(ZB+ z0;qb>tT{*_Xv7#qgXYaabTLCVh+-&aD1_3WQD+A5%sNP*1nM5ph&PCz2_B7SU?_#^ z1Fa1Ni5Eld1FgIO@pHhV*9;6fQ2Wyu5<$WYWekvo_ZiSJ-b98fuy`tXbf1AC7iw-I zLmF5-8>$a9yABe_fa(X$4}RjW(hq1h+?fH^F9FRe=rXu4!1_U;bOYkMLX3yb4!gtG`GC@mE`u8b ztX~C6KOjDA9S|rT=`wgSK$AUq7DboAg8_8W9LPvex&q0=#>YYF3&alrNir~i)0HlR zA6$PPLlOgs59^14(wQzp09+oF-a!6^*$+y0x(q=KF!iAH2jau*2c<)hdtmB8=@Aru zF#m(nr7nXb-27sOGI039!UMDdM3*6i0h-MjK zB_;+)If5LIkn#j!0;F64r8r2)LCP19iI5al$N&i$Cuok!1Fw5R#A_~iHMbwUJOR~L zAkzb(_Cv}OP(1|^fXt5}+y`1$1+pyyBFz9PPn_WC0#ZI8^n>ahP=1HSTOK(4{GhG_ zt*->FYzjb1Cy??n04;q(@-?Cy1Jw(#eBjJb$xs9>e(%ZLEPm7FMlBJ3WmEA;w~Q~cYxOGBkYB^%N_1+n7d%*Bc!}_LULy=Ll#nr z4zb?_o_-+q`@-WBW_j^aHU6k)I&`ae@0E z*<93kg_w)#et-B3H^f{oBtEF#4}<#$Yd^BJj8rQB>#g#Clu}7m^$h5}y za068S28hGJz%T*I2i=4O5?TP|gYNJH@i##Epwpm0`~y&aKZwJ?z;FS|KM&7PYib3n|p?uJZ?I0o8JP2$ar2#5G8zc$p7ee`ce9c&&DI_$>4VG0R9Si437 z%5Mi52HKAgowtI`BWgh9VdXPy-VipgXaSW6ooWd(!UM_&?LPqVBcOa(d7J^|Zw5(% z=82&E)lfccoHc0lF3q4KbKO4vN+45&P8o(48=2_05rSOJv>U9b)^Vh5BDx|$ut zKLO>h0dYY4@uB>aQ2q-je-f1c1Ih473Bp{(5Q2tsFhk=2C!yFPG_n~|V zD1S1PuL0$QP9X&eSwQ)_K^)Ne15iF_KMF`F0?K~~;xI5UWI*}1q5KLc{~naz0p;I> z@@GK#$Dn-JJSl8mbp=!&HqQo|*M!ZB?tsdJ*1~~|fX$o2=2=fb-~Ve{-ipz>3o>NzYR;ky*dmw@uuLHQa`KCHiH z0p)Ll%6mZhd!T&SJS1%1H3BLRI;Rh$1U4@Uo5#(7%ERU%Ve|aZVPl30s64EH0h`x_ z%@cP(j;n}DsWfXy?*=G7yh>N`P-LHP^HhxOxO^X%Y7_@MF{Di2%H30qeHTZhmAl?SaE z1sMrjhX5TWW|#q$hm4*vFsy*`L8r@t)Wg;hz}6w`fXajR!-3>aK>48kZXiBvULAB^ z1&DtGDi6AE5yXeh%Ugpup!^1v2knys3BlGGK!=SPen92tf+RuZnH3~HA)|H-3=&X2 zWYm*^K?BN%jTgbzrNGv$SU}~cLCy1k@*%A<28IYIe>zkiwvGk1&LsmX54r~jqy)BZ z0lv-xDi1nC10)Yy_X3^9VCaC#Lwe^746t=Duyryspz^SF2rHm`&>4(i^Pv155C^nw z0?MBc<==qvS3vo&bv3YcH!q;_u>Lx1osBqD{ST--WHf<+0k&=eI;_sXVGRlYR;YRj zC?B+c5hSDm<-^7}EuehRHPIk>*t#9qIv)?Hd^AWBw2lH=9>CV!L_p<1Yq~*7GN63W zZ6qLm1(Xju<{QNCfbv1tW`g)LpnTA=qagkYDE~Bw1FCPK{NqqQY#kA7-O&lCd<;|` zHm?5|%D(}X2i@)h68Zq;?*(x{>D2}jUdy0-1t@i@QE~t61bu`dv6ov|@JZK*)NXY|e_`}u#bwK4o z`&&Wsuys_>X)cBtP4dBFlqz;iB?k^&o5S zK*nnlp|e|{@eR=UN)kL>K;%Kbf|w8E!}1-3586+OET0LF2Z($YJf0!^JT&tQ;OP<~ z4;rmUHV?F~1euRW=MeQ(@N@_Yc~JNv{0E6ASU!cwCqqYtLH-5FgZ8w-%!lw%^@H|! zBFjVe)__DH=7C5M4`yCEboLO&&w$Pb!uYuiuy!IyCupB4tXzTcL9-Fa<`p1?C&+z} zy+I%qF!iu@AA}DY6$i<}>??(*YlwUql6jzU_EaQ3Xub!e3Zfq}50wd>-DCit>jF95 z1ty;lKJ5h-zL4=$P;P?BgT@CD=?5YYI@bkR9wds)&w-~$kPPUQ8Q8cCXg*b!0pUK# zJPjgWLgpvA83Tzx=GhYA=@&8&2qHnUkok38 z_$)h!4+>9&{~+@oAQGY;H2<#4kOkhe1rmYGpQXdYKbs+&L6;#Lofk=ovWL_Ay`T#a>j7UF_c_I)AQxCEqSv|;n zM0o(pIiUD}l{*csC-BG2O75hwwAt?t$<@ zCj>y;3*i^T%LfR*1YUna=KB%$gU&mG=tPj9F>!-DMg~~l5;i8y!0_QeLKTSh0X7^3 z;(&Hvpvl8VgBck9!y3*|l^{EyOfUsG85=gb0~TUn_<+Vo7{|c(R86${^ljL13Rpu0 z65n)cp@#X&6|mtokbHo!%VoHFRlB5n_V1aIju#uvUc}@ z=mpJO6G8NYty?F7=m7utDIl65n0*?EzHoT$bP)YvNzhCXt?={fED&9Ac={X=y@1VP z9*Ev>^xAw7y?}Ao0uZh6uzewjKEM>Z2u!CdE(XyP1mA+`2F4vrK>P<5O-n(vz)tUF zAlji>WI2dFFyjuGzVK`D3NU|F)=Ch4VWq(;5Uud@E0|`OwQDtqKcTm74Tu)F>bMp} zFDPVL2cip7j)Cb7>)O|Y_y;sp!0G3MS__z-aOp9aHqde22$FX&Sp=pNUNdY0@dbk7 z!SsWSydxXZU4#Agu61k(wOhrzVLGMOD{ZS zdO@wtUXXah)rnx5;mtEJz2KnrK9Kl^unAy#!RjYq`oIB;{UGs%X+2=tK=%QdUT{eA z07$&R-x*9N?9Bnw4LsApG=uGaFfHK!0!)8!5fawhiXTbD?ZJ)t(fPwU3kUoVzCkTBZ z6HGUJn*gR07U6;L1({$lU9g}MLUS$v(+m;Ez_dZn8!+v# zObA@Q87#8^(*ZqkV0uDC3z&A`UInHLmYfIE4k};4^o1^|V<7tiZrFqA3p}Y{x`X<&MRZ8w-Un7$rN3*5X6rURINfN2FW znG+y=69gT=^ntI*VEVzKb}-FQxf)CxNSp`L3l@9=(*;6e;PQM!t|gdm*c1b%86MVy z>42Y$z;wayqhNZ&^A}+H!(Q%FAp08X^uTn2W+0eeu&)?Q7uZb$(;rss0MiQpZh>h7 zyT1@RQ~oqazeBwvm@a5Y2GbvMTEX-Nm*rsk1N%uZePG)wFl`XXa|Wa@;JPk^_VfqS z4$BL`w86)TVA?@_Gnj7hyaJ{LBEEuYhG4O?ApHqe<`9}M0!%ZUuK?2pH8a8V0VETjLZ!m38EPW27f5Aa(FdgtW8cZjs)qv>-Hgh1f!yYi*U~~seUl9BQrXSps zJ`d7=VWu^hUf>iBrW4P>BZ91t7n|aztJ}QQr!#Qspo7nbCaxHK3}#Cw=-M%D(Z_Z_x^`A8O}#+ z1(zO6INSNtcD|mxLVnU;+p~Lb?dbM@X)9{r^!`Q%gWcLn?PbC&9Ck-8zdIm4oz;%X z^UB(CueG*(2Ie2^%lPaLe`9mMp7hXGWRI`>8Adj{{ZGFIKKT5~_Vs5eIqoV>yW>m; z3OW}bunjyO&cL82V8@qt_8mjCsNMRl%mtcl_ib|*n{D11E@0>Xip}eUx3JyXJqzdE zau&1Gdi8zF@-$hy_kX@yJlOQjw&O#=v5=RaZ8x8?;^Zu1v0EOi{=C0H*6#Vv!t#0d zIh&n#Qq4!^SZ2O%Z*0(Llt`a6!L- zK(?%%_UJHa+qtCPt-T=r({`RYb9jP- zs9l0|)s*gwJa%;}Yt&QMircM>pMTW1L(s120$ainL28vzy@+^z)^tqTLQd z!$=2leLGW&6xHtY(sm7RyJc6z%iBGK+|C*~salA6{wNnN=I+En6jN7s^(|8CIlc7qX`6kFkuJUC^S$^V(^eb_VK41W!0i z*qNP<;@+L2V7G)(y@khw%kElb|JKkxDZ5#7EyThIF}+1^ehIq)XmY&|<3 z(XrInR`oj1wWZpVV&57r)*c4`r;-tpbFw%cXS6nXcErQPvUuOGbpEM>QbSG_6t zoT=Teom#;q{+4zjZ5>n9P1x-|ct7T5h~k09qq^OXp0`_68C2~ST>5mb`=Xv*NGTVO zo`#~`spXNzp9^^HR2^0b*VSv=$#p6o&NDE!3n=XdRiAb#ve$b|H`v*gOleg*QD$ZL zxb0rhF+N+n^$~3k&MeWlo5ywF(xMh?yNl6>K5ba4U^nwyv{J$~TRZa)vs?K$a@ajQ zJz=YIhn?NGX>y+hh0W|{@h^&Lm)Emfy3^9LXsV9gqX@gIsjL=uCd~6+seRP9;|%MI z{2FX&=W!(LNB%)GyDy2K_?1qp*ewdSy{hog)Gq8(XJUPjl^y?_EC2t5S=imWuF<5& zV_^5-zRQ#g!XIsyMZV%o7ErYlyl%u_p{Hhd{)d3nO}n?Yt!KUKyi%3z6xTL*Rz$Pf zrQ~hAqN}fH$Me=Hd69#0B<(uv8*6(3IGF|G2 z?W*mkWpXs^>?U(5d2%Of*v059Iw;Eh-`0&&=DBN#sa+Yf_h)^?UTH$U8;scP4_ zp?_oR88f>RE94k*-A(M|FN@9Vus64B*Q(?d2sgI-#+bOS@}jlfqi=`91Qzqy{pOgH zRG?vNXP?S6CQDy2^OXFHw2o~JbC<;i{%8#`_TN4^gmE$ot|ueCTi+uNCySjKTCTiM-{ z+!@y9WMa4M<|f8Tr_AhRCTm$WS*Y6?OcLko5VW!T7nIw3$JWqJ{H0Ro)py2r0e7=o zCPix6b*t;e``+fYJ7UVF^>OJ(TN4|djt@?5c5&|Cmd}2tW%ne(tGV7=%}%e<`H>T^ zrX8cdFo%M=k6rZnYhrp8UUnX7w<==-T+Q(pf6lHy};#~<~gX4gJ9yB*8?{$|dxwp+akd8e%9Hc zla>_OI^S_*=KQ5#_vPke&VqhDJJ&9j?r+lGc3~@j-4A+aXSX-?2?J-gE3|y@wM%$p z-nJ;u!|uZ(o{#HO-Rw%i2yPb}z&4Smq!1wG02kvwSj( zj~&mlrRT0Sd)e&@KgwHh&A^Up?+c-vlP-3m%8w^Y>e$*jHN^`n9#^ufExF}uH%r}4 zd%0ug{2za84LLqCE%#KkyItB?6w3{UJu}M2a*RE#C z?T(M^R(9Wt4(gixbg;uUzN7F!{(=01|Mnl)|1j1c_-`-ti*c3A!vFRPKN{tKH2$~W zdV9edf#m=8g-%}cQeFPrZ{<>U`KJ2co3k`-jzr6aU#i37EcAs^p)2$y3IYR^k8bi>2;VPPF=GF9!zy?ByOX$~|EG zXW!NKaYFn#+_ve>;Bqz)ypY=n)KJ+L}y3Hw(`IBn~F*s*2Mg^ zm%ZXBd&Tjuy;Ss{#X9PL?Mn{i^>5|*YkzFNOHAIUKla?SnLER7{IP$2nsHk0zCZR8 zAI7n6Uh>D@sq1%?TK6A&nd5~r#|!`1w|VkjoD%WJ{=<*MjQ#e1>}3|{S#DMPWB=el zBQrbSAN%g!ws*~6f7^d&o6@O$_qTnuT}SHQBfsr0>^dm&bIosi<^K}ea#MfXcN^cb z&8huu&-!lP<438#?fs=+Y-#lSZGVpKhL?x=Z~L1KISytDzwMVO-8A&({B5tXe&L?B zPrvNrCQPY+ar>9Obiq-nf}_9e|GsY5mtFtMeqVA{!uuJ&>?0o<1U_r}WuGf`VHsoY zFMF@940gxxU-nW<9Ho{x{<2>nbF^Jc=a)T`ch%3!V!!OA7BEUJVEko&(^z0?-reZl9Xvmt6#TSbSN@oL zcg#=w2QRPv+2HZh{+Z6~`eP1U}XDY?@-V9 zm-Wkcds+XeK-EXz?Z2?rI>ul4ZePQwH)->}@Aik^Jm64T``y0Va$EMQ+28F?EU9Sp z>H2QZdu)~jVn!_+)4j#pIgd!=v3HudpGgel8dh2?R)<@9{phQ-G0wKw|Whg z@AjNEb8;($zuOlya>qPi`fe|t@JTG;(>MF$=FZvQAAYk>JkhAO?BX|j@tlKVIS0Sl z+e$6w^4$2%enL_3MVp1+>r@^vym+kvsB)(>MEj2fB8I8Go~PNMbDirToo)$~wc0%_86I*~B6e8d<;D|IyVn zN%{8G{<-Ld9nsIf+An?d=5YFrulC^rleIfeezl+Y%l+7%U0>}FL@{QwuK8-e>WuQo z#JOMX-$pbVTY+~)n4?+qgU**U+s?`5qzk`|J7bJfKfDn@vHr8pSwx@pTF2! zvg$8?@brtlkItQa&Nsf;=dD+5-*M`T{lorcckT9mv5(##wBXwMFZN!HWozpfeX&o! zu<5bo)Gzi89*jz?9bfFLMb^1LtomY~mJn%jF87Q5tn*)wpHBEGqnp8B?0?@( zO8w#X#oqVbY6EqvFZS*7S5?z=zt{&x#;I*p_+l>t24C#cQu!`6v464uExf^=@%LwY z_Vr7h`rm!FXIlAWkItjd_Qy(BO}u&av;Fhc)k~(H{A?epseChG?`L}v>y5(J8$a7C zov5-&-QM@57tz=eYW4UCp`Lz)o1%(vRQ9q^grA07tr>4to+%2+v}GR zjdLx`wabsdt1JJviH9DZ=v7oPxjLrybq{8_+-BzK$ns0 z>L>dJI*q=+Pkyo&G>_{0x$l#`gEr$@mMx#`Sr2}mB(w69{XC&3nvU~6*)L_;5nVL- zlfCeU4xtSlpX`0lEwuPm`^nx^y>UlC@h5wA#%nd3Gd|gWoYYXD6!*z~Q~AWYxxt_8 zC#iT&Qt|v`ADtjReY@Q!`}=!lRfL&*veyz?pv0*4$-d&ZV&iuCPxjA3JsK)SKiS_r zkj~@I{mEWPfl)|-@soXl{J~n5?;q`bcGTN^dGpb}WQV==`$r$`_j>82f4%Y1Ubb=3 zTDJ2a?IRz^{82jk(O&bdn}gTxkM@sueM+y{_|bk^wN&EHoosm@?HP^!1oWnSwC7bXjhBo5 zXn*qR-^DuvKiXTL<>HI?_-L=O(~tIR4!rH`*7;~}Y!LfALiwY; zn#XcU1F4Vpf?)8`zCnO--*5Jh_JSY&34HkX!G4kI=3j5Wez2b~=UMjGHy`W;6PiNV zo_w&M=GMPL;r0i6t9hnjE|)&oTi@E_UwHC^eW7D_+wub+>`%;9ee-Pl2m7sW^osP? zf3ROJkipfs?1Ozm^ZI4C=YFsc;bgS5pZdZ6QEKVt)jc2VTLhdq6k9&nKYF!8bAI&) z`(xkTxzvh3*#8!)oU=9SgZ-bCA20bPeXwsUEn4s{@`F8#$@TBk13%awO%Xfe>G{E4 zfW=XO#qopvANQv1$1FbBOU21=ooMjE{-tL5pA?M`_8crsjSdPQ?9HnJ%~T{l*b9Kc z2m1yFMkW>x*gOu5W?=XMy@%z`3CMi|0n;Gs!#+T12hfBC1NDJJ1H>M5lOrBM+>rsL z(dEGhbYlq8P9P^1yE_x0?kj-O6;QeXN_RkMkjv&+R)Uu!gVv0*Ff%Y@#4$2t1V93I z(pd(EzOxJrv(GXxbe?5kIC7SOVar(thUsS+7+TLVFuXd;z;OL61H*%}3=AjFGB6xC z%fPVVECa*jvkVN4XBilz&oeNHoM&L*JE7_OXWU^si8f#KMB28R9T85p*nXJA-;o`GTEc?O2*=NT9dUtnO^bAf?j>jege zbr%>ImS13CSa5-XVdez}hDjF~7`mYwM)WQ+Fo;}YV92=0z%c(J1B28h28RC^85llX zWMC+`$iTpRiGktjMFxgr7a14=E;2AYzR19^;UWV=$3+GPgNqCd-!3ySyuZxA@bEGN z!{y5i3`Z|BFl@Zcz%chR14HL!28Pnh3=C>l85rcRGB5~UWnf^w%E0jT3IoH#D+~;0 zuP`v|yu!e+^a=w*(=`T$>T3)Pxz`vN;;%6<1YTocaK6UCV0w*#LH!y7gCuOj3n&6; zh#|2Ev7n=ikwGJdk%0k(Awn1=NWBA+d;k&~q!?rdhz4QMoF9k=O~!)F1#zGlWDbp~181G?QHO(3&iW+U4VG9M%l!!R`<{)R3_28CEg zP+0=vV#Of!7O@}_BJF|128n>o0MQ_fY%j=MkQfMq_GmCSFgLWsGBSYn|7gT9GJwKn zrw9YXc@YMNesKndCJ6?HEfNe2M$!xn4$=$^3#Azt-bgbr*vc?4uqZMxh$}KMtW;)T zNYZ3r=+tCjVAWz^kkVpc@YZ5rDAi(M2(o2hIDU$O!TB@;L&RwYh7C6u7kRZUo;2;2T!yH8h1_fsZh6F|i27?oj3(+2&WMB|rVqge3!@vMq z%PVk$fnf_114F|d#Jx-m0uVX9lGF;&stAyo0ecu2zLz~h72I{C$PZuRxmI;U|@(~VqnnAOi3(BQ~@tfj(Eht09rS#XJC+=md?O1;SmD^ zXz78Tb5Mv%gfn=H+zeDP@HUwRC}N&qbt@h*Fo5C@qSw%H)Z z0pxWCh~5D3QvL_1>LNf2U!aPC&HI2N76MYn@B>v0td8L^1A{|31A|@>$o~us4pEE@ z2N+>|P$)8h^K}kF47?OACzg@n4+C6XS$DuEe^jF2!a zDoIxHbOgI+0g6}@*gY$d#X=zJHlT<>)a^)QWH`agz@S$Fad$&LBLisdHH5DMUVbT1 zz{mg!G`&=anv4QQ2GITtXk3H0*3_ViftTA)0O>=d2@_D9y(nU2$YX`46Ua7@21bSi zE(QiYi1Fa^2((`b%vUL50Of7adUhxuyujx|7bEyWD!nA=8TShq86@}_81xFDhHPL2 zUofVZR!{=EUln9GH8CR_GXt9wQvqWF1B0L_2ZLw{Cxd7TJA%CI&VmrT{@M76vX84hF6uwgQk|(0;;x2D>MSDS(lmje$Rfoq^wkje*~YyMU3Gg@M~lU)p=j5`?EKx)DMXJg8c4h{4C*}Yq z=!PjKMrH;kF$Ok9=mr5$n1I7gjEg}mgoi=QgquOkNa%yW1HJ=11>6aeGRzEoj51*V zX`EzW05xkM{^Mm33E^Q7G2vzqDH15)lwe|zxFli#3!}-(3=Er<85k^XLTE+~76y(Y zmI9bdn3z}?n8g^_m=YKZApYZFkO|>tkTKz6kTF8|Pg0J9K`uz@gTw=|3nB-E3Ir1b zz;=Mv0|nVLFg&qmVCcRDp~dYP7`Po67#2b|x4StoF!&(xB?UMb1TOJ>;CjGuf$acG z0doQq*ep<854yJ)RF^%t38~XS{8P3J46IPIAa3MkkO|?za3iB67lUL8Cxc`P2ZLk? zJAssV)Psai|8{j{L*7! z0MVd00nwbGbWy^Ak7RyW>935U_c3dP(j7OzyMCOXl{e#A$|sa6Fvt1N!$gD{4DVNB+1Xjz!t=0utbA_ z!Qu-8!wC<_+A&Ev76v&J9tOclTmc}tgf9^BDWC$7fq_8?x{;j|RBi-8;tS;evu+Fw z((Vil_iiyTq`5ON2qM`93SW?#iEa!Gv)mXMj=>tk0CLxcFANNjc;;r1OyOdX4B=#u zG~ocn=>tJwMh0%Ex*K0Wxru?H2Nq5eTnrK^TnrK+oD32s91IdhA|Hev2ozv*udF`< zgStP$y^^4E$BBU<;tV97n}Qe^I)fl=FbxV5Bc=jHRwf2k6LyA#U`yKxP`PBl$jQXOIf*F%OcyZ)U~}`@5C(?5 zAqY2PQ==Qoz~CH;UrlK!1H)1RYTkx0F#JZc3tZMGF)&E#aWcrJ9AS_(Im{r-xQ_u+ zf-*3G()a^b1_nrZ#l;{J!U^`fNRU7QB&~8V@SCtBmG=S+yqDM@bwLR;16K+tTp1DN zIxJkoxfsMvgc!sp34Gvtz;l7?00$&3f%70QgJcR1gJcLa&lib4fRr743^F0S3^FD> z3^GAT<(oDqgA`*118VMsxE<6UlGJ8rkSd8_kTMBpkYWsB;0}PuO<;ogi-$oZgquOc zgbQ2_OR9p(aX|(#69ERXB1Ab33JXx%6kJCYF&RjL>pO)1VQK7d83Th)IRk?#bi+QQ zDkp<#N-%?}Nf3i7qaTC#1JMGJ00st#yS^|;nS5rDV*CJiR{=XLFLE*P7jc8@c2L^u z%x7TGC}d#ZhM5btpPPZ-1fmYyzA#~8U@L(63$6YH*QtCAA|bpCA|^ZxB9jE5^#-U+ z#;iBMX~T(uK@gHhz~wy19fw*O7;d&QFxcG&N)cobHxXbEFB1MB_<;Wc?*T~If$E8koeT_VT?`C8Q2ocd7#Qv&@v-GOwhjgc z`3^*$V-#Xz5Gvtk5HjIo5Zc5Yz{tbIz*EGEHBYm3GcXi(Gcc@$+9wFoYa+lPv* zxKmgdxJ{TCxCd;5QLq;J?HT(ie)NFBpeDXuSZj6A})L;IKoqHz93wE(XyQ zP6kmE4hGR6!4I(T)L+ZMP_`B+4{$Ita3sO(h3fuVjq1A_$gKpsXBP6m-f z=&cC`20>{K25A#M2I(O2526o*F9;ssho=+OoeT^~I~f>^pk_!Kb2F%#C^1MfN-^+# z;CaAxf#U#M0c!$F00YB|lMD**oLD~b7x||HsArqLSP5PLm8M~MuDG^c@ zI*2eZNE&i8$cId0k~f*cB+uB#gedtSY7#^k7$E6}6W-?ll?VIwFfiEeWnl1xx{Z;K ziGk0E%YadWjX@%Wok7Bc4OC|*FtIR$>H#)T--3~ok%7~Rfq_wgjX@xVlR?0QgFzsO zr$A7Eg+aiC6U>H%-^xP_4BHMdFeJgu2Zi+_>|q^yl!0OKQKYa2l_^3@2AoLc5X{`( z6ATOoKw}|yAT+oSVgP9yfZdnGzyNP^Coma+^8@UV1L$V`1^J*5fRuwU5>(#o$Y*4D zfJF{8)&)`r8*c)QPZYooY5++Fi@S=|{d>Y&QOdk8>mrvlLJO;A5DFfdpYFf!N_ zFfuq4FoFj({6REBUVdUpNn&z_UP?|5LvdkFW=X1XJWMb?GcOY~)WZPki-XJrVS^Gz z@OTY~jgCS6bC4KQF(fP`ptK&8_JGoHP`U_8_dw|dP&kKTL;fYKRIx(Z77 zLFq+MdIOX`0;O+3=?_r)50vI8gV-+ur8S_m1(f!J(jibf0ZQjU={hJq0ZK1}(tDuv zH7NZ7O8Mt(x9{i!qqH+rKv@g0jWi4`9-;jdC95H`K5U!sYMJnOzx>A&ZR{~sd=y) zPCZi?9FRmqGKx|YQ#?}`7(|%eQ%iy?i%U{-Lo#zy9g9JCuYy<%Qd-#V)ByrRnLZMFB;r#i@BE44+v;^D+|iQgTvLTq}}O z3qVG=W#)i9!?1xhIJE?)^ly-_f=d#MN=gen^V0Ie88$I{76%mNC#Mz{=NGx9f^Mfw zh1oM7q}n$>r8Fni18iM51B16~ke{oMu@N}8Gw_343~{P!1;Y$xPf&>FX7UI+OH6ljhqDMhKE@xKquKKY3$PByOU%hkaRzxZF+G*xDx-U9 ziKBA>1H%E3&Hk>wAodfGsB-`)u`&Dvv-5Lv6Z2AhGV@X$8GfOOgfqyp_?G6BWI9!r zq=w{&XQre&XCxLexUj*PA^C85h8U1Nu6bpdMfrKTsd*)kYmJM;85quj;|rVA9!58K z-0uUi;cBD%T1IAvS1+4JgVlNlh+cV7SMObjNZy1H(O#E1_`( z3VQ~IzaWv|k`zd$Vqho%@j)RSQdyA7zyvO1NgZSYL4E5l63eK!bWnicUvx8D0 zG1v{tNk}FgVgzS9kXcTpX=$lN#S9D)Y~e+jCE#148I(abIp^mU=jWvQmzETimVn|& z9!bWh{3riH4$P^IKvzUa9V+SAsk`{)MVIMNT70e6c6qY zfVBz9b*0gw`?@n>hmDb8$k|whOKDd?u7F@rD+1K!h0N4}4TNyPOi14Y$^=s=k_-@e z&{=w*c|NcLni1fIDOd@Jl?pfkM1H7~xG&;__zd?&kr4UeN@7hCU_pqFaV87UumwcP za3Y6zG6AhRLynFm%nS?(O_fcs^N5#04{BYw6r!qe{sYi-I)g)91DIaH%)oGP@vX(U zBDe7$M4tnc-b$o;N2vO3%nS_Y7d=@d#qe~|i$$tdW20eSnu%yJ4_*B@yg+p;kih~0KHg)J~KxSZ5 zS5jG!8lRb$mhS*sO$Smniir*Z0R{#?0R{%pIxNt7ybYi=dP$57Ao`df1H%!}`Yb^P z1`itx|$N-|(3NtXw0I3&dV2BZ6U|5mF$S^^Kfnl`>14BX*Bf}aI z28O3l_6rdP1{qO^IEXfcvQ0!87-FDo5M2mmmxwYjToGkpc#^~jrdh-wdO@@VlntVT zpzIJa28R1$3=DUY7#SXjF)&n!GcasPVg%E3#3AA!`Y4orL!5y@L6U*tM-n5Lj*(^YJQ3~4e93?j*l;Ppn+}Tc5Ul}a zgJ=sV8$<^}*&*@_3@K1Hh`uP#zz~qk$Z$iRfq`8CVy2D)1H&W*h2Bf|#;28NGNHfVtXqasAyMv;LbS`nf?Mv;MGp(4c0C5j9Td!gb76d4%m zl^}7~pv1s%TnVE7gc1Y8D=7Po5(9&gGDNS5G6O?4l%1o@z_3@Df#C)y9F!RtlvE&b zq@u#W;HLsnAE3g(utf!8K8S8nWnh?*%*X(ux2i$HaEBTL!)|p3h7HM#413fW7`~}P z^!`w1VDQ#}_}xc?fgw%<;FdRu{WH8WV zV5rw(U=T@RWN6T0U^uD;QGY^bK}HFi7b_#AS3D7^L(W7~Z5XGRWvNFx=5+V9-fr z1k-B`7#Jp`GBRv1U|^^>Wnd^sWn^eDWng$~&cLuDm673tIRk^PB?H5i6h;OEO9qB? zYX*jhR7M8Syv`bHi20zon}1NYhz$cnm<_}Y5jG4APIe3oH7Se?E_MtI$L%2MPuMXq z1UWD;7^E;Vgg7uTymElV*Bb{0hMSHI3_DU78SXeTFr+v^#2+|8*Y|?*g);-gT4x4^ z6CgJ`Gca6rhM0N7nSr6+g@NG?$o(!14BK277~Z5ZGVE|+VEEz!aSw+p14FSJ#LN;m z28K0m3=9!zj9@y)oq@q3jgbLF`+G1j2&6GG1b8qo)OtY7Z}4DXc;dmp@FSIxLBNxN z;j9+}!-O{an)U@-GzVAzw!$Y9~e zz)WpD9gVEFFGz_2EbkpXl;j{ z!-q6RhL8XThUoze3|G<^8Lk8{FnkYynDZxqfq^Fw!UoZvfe^Qa1Trv8fwDpLd#Dxoq%$&rE-;FQvSXqc7#2i9)Pv|lQ1+211_qvJNH}OjGcd$M*&Cu6816&a z526_uykZy_Ix-j;d}0_FW`J-KBba85V_*mY`8SS%VRak>!;B0@hBa{v49W2f3?&(i z3@Pyp3{CM23_cl*3@z~t45#BEZa5Rqz%V<3fniAoBg32o28M$P5H}o2U|@I#Wxq&Z zVBk)KsOL#!V9?w!_H(#THTY(z>ty3 zz;Gvn5lk;iXJ9yz!N{;Aoq<6klY!w&1|yhm%VA&;$Yf;b$YEem&V_`zPA&t3YaRoG zPbMRSM;-%1WaqrmvJk`~{*vK-nOAM->A@LM9^vh}N!V zVBpANWN@fvU`VZosQ*#Tz;LaGfk7gRk>N%S1H-dgh#x=HGBC8(F)*lPF*3}kV_@)V zU|{gcVr1}XU|?9$00~_xLtPWZ{S8eF3>%stYC!ZS zDEmtj1A}QZ#GHU;28Ntw28N6*Murv53=B(K7#Jpi*ewhU8(JadEr@>I%D_;N#mMlc zm4QL04PrisUeyK(=QV8%49}tBAKDlgl-n5?)`0xm&cIOK&cLuEi;~63?bQ!U^=OTfq^HRk)fr7f#E?H1A|C5Bg2a>28Nby28IbB@ool&)E)+g zE!m6=89fXPM|&6;IF2-{28L45r3^WY3>DKD80Jrdg#UtR3=DkJ85m@87#U=y zGcb5fhxqr#bOr{$nGp9^%w%9#KNC`h+?dJ0&@c<47ev3C#lYZ_!^rSq76U`*Y)JSQ z%w}MiJ)40cBZm=XO%P~pki>ijhK?LY1`usApMhaT4kH7IR$l;#FAWgAfPvuzNbdp$ zhKMB$3_Efd84{K-Fnn3Uz;Gjn5llBPV_RbPFTmlz`7n{KF4|nhRN$080O?M zGE7;|z@WN;fniE6BZI~U28P{R7#LXc7#a3#VPH7Cm4U$`kCEZXRtARq+aT-*+ZY%^ zb}%qR`Uu254M!Ll?2bapH;1DP4BL+~FmU8EGVD0Yz)%UgoG71>q2?F^ zgXeKbycZm2U{E^2z@U@Q$k1?tf#K{41_qOSMutBp7#P$~Li`I__vLyLV!p>o28P8a z85kn+85s_oWMH@l63=G@uYXEE1<79-rx+OKoPy{D(fOwt7*g^X846A_Fg!fXz>ou4 zqjQFV!S4(MLq$F#c%AU#Gmx-4aE5{5&>02>jbuiK2WJ=Z6!-KBY2G^c->Q4#BX}Jmc%5MqBY3?bcx_w~BY2G*c#T^UBLj#AttkWf9YllIegZ8Q|0Ids4LLTKLx+guVa5MylUI;v3U|?ZnV2D_huqb0u!J>*q9g9{h z+OTNHq6>>|EPAlWVR69XgvAAm8x~JkykPN$#RnE&So~n|hs6v_1ePc)F<9cTBw$Ix zl7b}-OC~H?uw=uM14}L}d9dWe5{9J$OBI$HEOl5Kury(5!P17M6P7Mmx?$;or5Bby zSo&cp!!m(o3d;>2*xxjLTd8gB1=d0#+ofC|J?3V#10AD>ke+u;Rjs z2P;0TU|1=zQemaRN{5vJD-%{0tZZ00Vda9A8&)1zd12*)l^<3ztP)tIu*zVS!>WK) z3?CR6-hl3AT6kgMjfEVG1r|#zwpi@2*kduo7aB_qmRc-zSn9DfU}?nCjHLxjE0#7a z?N~Zt>5QcdmhM=3V(E>g50<`I`eEshr5Vc$mRBrqSbkyojpYxPzgYfZ`H$rcD>zmN ztdLltutH;n!3v8N4l6uX1gwZyk+33TMZt=S6%8u_)o%<0vF^aS6YDOlyRq)Ux)l4;ztS?w!vA$t_$NCBDXRKeae#815>kq6yvHrsP8|xpef3g0<`XB2-BmUqmF$*{r z2rQ6Tps+w=fx!Zc1r7^576dGaSdg$FV?n`!iUkb|Iu=Y=Fk``j1uGV8Sg>QkfdwZP zTv%{p!Gi@a7JOLnV*$fLj)gZ?y;${Q6~}6c)f%fUR(q_DSe>!DVs*#r8LL;U-m&_` z>Km(Htp2f@V~xZbjWrf)Jk~_4$yigdren>FH7nNaSaV{{jWsXU{8+=WR${HjT8p(F zYa`ZXtgTqvv3ADV6>E2_J+b!2+81kotmRlIu})*1#X6655$iJ6Rjlh+H)Gw3bvxFb zSa)OHi*-NNajchEud&`@y~p~9^%?6c)_1I*v3|w+9qUi5zp?%W*vAY4j0`%A3=A9# zBo=5auvp-+AYwtrf{Fzl3uY`>v0%r76ANxEc(LHe0*-|e3pEy6Ec93yu`pv{#lnt- zGZwB`xMSgog*O(ySomWh$0CVE8jCCzc`S-plmX5uGZw8_v}4hUMK>0`SoC8N$6|@a z8jCF!dn}GvoUyoKamV5ri&re(vG~N|8;f5o{;`;2iNq3(B^FCOmP9PcSW>a1W66vq zE0*k7a$?DiB`=ozSi-SXVyVVbi=`gmR93OHW9f{gE1>D?#nK;3IhIK*(^zJ)%wt)^ zvW#UF%Q}|LShix>j%6p7-B|Ww*^gx$%O#d;EVo$hu{>gV#`22g9m{7dU$K10@)OH% zEPt{5$8wGp5-T)TSgi0^5wRj;Ma7Da6*E?>Sg~Wpi4`|iyjbyL1qbL-SOrD~P%~p_ zm1evtV>u|u&!a`lHI4>Spe_{QD^&dbNGa4{L?v+^}us~sf z!2*W`0Sgiq6f9_1Fk!)h1sfI|Sa4y%g9RTJFf0^UsIbsrp~J#}g$WA_7B(!LuyDb` z4GRw}ys+@W!Ve1>76~j;SY)usVNt-Mghd658Wv4hv|!POMF$pLSoC1gheZsF1r{qT zHdqWP!x#Y;V#S3OH&$4z3|JYl^1;d+L@t1_nk31_lN;1_lOx1_p)(W(I~<1_6)|gCqk3g9Rf4LwtOQYeWcG2$gU^ zZuq$0rw;6lLb6 z!}+N0tAU!Q1eJ&JpMD z*c=zf5J#{Ogn)(*ESw;M2oe-tAPkNWu>R!y+}!*;n2Pv#?B;R66fiI_fb_$-Fmqsh zkh?s<=K6U0dAquJ!r~Mbx@hhbfO-;S4hX}{;bmZ8FkoO{kYIo&9;if4W|Dqhequ>U zVseIFN@Y%F5=6p;fuRAMq8u0)EEpIVjG=rBC?8}E$gBzni2GMKFo1)In}LBL0Ad6< zk%HU+Qj6?Is5DWOG}O&%;=bG6I}MU{w`|R}`MmCm5d#B*0^Bcr3=FJ%VEe%K@W`@g zF)%=L1jHI1P`-eg1#%Blg(E8{B=k#*i}XQ(kdv7dTv=R_nycr891dzwa|#?77(j8R z3FU+Q4Ki64%KzZNz@Px~EJ$z^kA}c#2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk zz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By z2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1J zhQMeDjE2An4}mZK`&Ry~W?cE#nPK8*X2w+_3=A8Zm>7O~gkk&JL2RgUFa_Gb%)`LMAOhX-9>KuC$jHFJ!oUC(fbM$+?d1kxkS649#~}S6 zF$~NYUtE}zS(0iT&j5B83qwN#BLg$Tj5-Dero@6w20_?1@c7KU%n}B1hzT?5BESsL zK4?Bh28IIYzIu><_(86MdH{3|0Y4)H_#6O`1_cJVeIUc(98^oXfq@aU4IJi8kze3us*%_EvK%oM13g}n?h(p207&v@TU}6Am`34z5 z2*ZvrV1T&|y8k=a-zvLzgTN=|)a8Av7Vc91-jx5Mdh?yBI$re>Eow3xYwOo+ipW3q zGVK7%^@|s?nfxPI|JQ7(scOBox7(vrXE`DHjXR_TJQoQ^`m7Zd*?Z~!*|*%P{wI7T y)Gq$b?OOjU%=2Ko)(Y$8i$DEq+i1;|mGo~)=;}`ldlw#dmzm~1Yd3cw*k1rGLkOh+ literal 0 HcmV?d00001 diff --git a/extensions/lib/noattach.so b/extensions/lib/noattach.so new file mode 100755 index 0000000000000000000000000000000000000000..e3265c0536bfbe0e53a5a82e785333c9921923fc GIT binary patch literal 15304 zcmb<-^>JfjWMqH=W(GS31doBi0V?5P3S}^W#4H%N85|g-7$m`JSrAeftRGNG7|kF6 zQ3A4q6~u({Vd5}47NmfIfdNLt#6iMfBNafJ85kJQ=oe677>%rtje&uoLJy*#!VZ;Q z0Wz3@fnf)fhUsHsU|<00>wxO(fa-(M0Z{cYnge1i1IUdayaHqZ0|Ns(jpl3ybbTkF z`p{_=sQEA&WCutn_-RQBh>dO!jE~E{0H{6{r~-6a2V^({0|Sf(*#Qy?d|HwM3KtNY z7z~T%AgFz~;-Lc?o-i891&1fd3{aYJ_X}lUVqiD`atkxmau8dDfq?9$PAFVAop`Hu&{sztFHml~3ol#>dP!!8q_T#*=`mYJ8B zlUbF@P+XXkS(0iTpO>FlQj(aQ5ucftSppYLEXZVFfaM>UJ3fFShk=2i0h&Kx;v1mi z5@_y*@o(5eJO~PVP?$h?3=9vD#6fWe6Mumu4vK4-_y;6$kXbPCA4uY$Gy)SJrAI?x zGz3ONU^E0qLtr!nMnhmU1V%$(B!<9eez{*B&2Kn7x>;Z9Gcb6x9w=e@f5D^q2*+V? zaQruYq|dA&h@eFg@8c?OXBPybctf_W|s3?99bRi;Gc5fFo+ZC(Rm@*qw}*zujzyT|NjSi zbnBkiV_@*;3}rC9^nbz)CI*Jq10~WP-Ju{)AK_zQFg);ok_Hn<2{U-uASyZ*Y!Wy; z;UNg}{U{y{fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!84e4S|r0g{=?ef!Pl395OJ#`gj4*b+D39dDyyBX(%7oyOV+IA4m*@%Nar8$qpGv0SQ3yb1==z09*GD<}xra`~v%nn*o;pVB(++AB+sb z@N^Fo7h^l*Ls z=K@;H?-J?f=kJc&Pbtoi&q&Nm0WIl|clQg8clCg3^Kc1b0K1SO-rdLF z$4xlaTe}+BXDK53QzPTn0x528M6{|L4Q(ht-oX8Z`b3QVi3F zZofAJ0|Tgzgz1OXqcC~}NHYTi1E}5wm5ng{u=+3loadExtension($connection->getPdo())) { + return; + } + } + } + + // Apply the change to all sqlite connections resolved in the future + DB::extend('sqlite', function ($config, $name) { + $conn = app(ConnectionFactory::class)->make($config, $name); + $this->loadExtension($conn->getPdo()); + + return $conn; + }); + } + + protected function loadExtension(PDO $pdo): bool + { + if (static::$loadExtensionSupported === null) { + static::$loadExtensionSupported = method_exists($pdo, 'loadExtension'); + } + + if (static::$loadExtensionSupported === false) { + return false; + } + if (static::$extensionPath === false) { + return false; + } + + $suffix = match (PHP_OS_FAMILY) { + 'Linux' => 'so', + 'Windows' => 'dll', + 'Darwin' => 'dylib', + default => throw new Exception("The DisallowSqliteAttach feature doesn't support your operating system: " . PHP_OS_FAMILY), + }; + + $arch = php_uname('m'); + $arm = $arch === 'aarch64' || $arch === 'arm64'; + + static::$extensionPath ??= realpath(base_path('vendor/stancl/tenancy/extensions/lib/' . ($arm ? 'arm/' : '') . 'noattach.' . $suffix)); + if (static::$extensionPath === false) { + return false; + } + + $pdo->loadExtension(static::$extensionPath); // @phpstan-ignore method.notFound + + return true; + } +} diff --git a/tests/Features/NoAttachTest.php b/tests/Features/NoAttachTest.php new file mode 100644 index 00000000..9ba6079d --- /dev/null +++ b/tests/Features/NoAttachTest.php @@ -0,0 +1,106 @@ + [DisallowSqliteAttach::class]]); + + config(['tenancy.bootstrappers' => [DatabaseTenancyBootstrapper::class]]); + Event::listen(TenancyInitialized::class, BootstrapTenancy::class); + Event::listen(TenancyEnded::class, RevertToCentralContext::class); + + Event::listen(TenantCreated::class, JobPipeline::make([ + CreateDatabase::class, + MigrateDatabase::class, + ])->send(function (TenantCreated $event) { + return $event->tenant; + })->toListener()); + + $tempdb1 = tempnam(sys_get_temp_dir(), 'tenancy_attach_test'); + $tempdb2 = tempnam(sys_get_temp_dir(), 'tenancy_attach_test'); + register_shutdown_function(fn () => @unlink($tempdb1)); + register_shutdown_function(fn () => @unlink($tempdb2)); + + config(['database.connections.foo' => ['driver' => 'sqlite', 'database' => $tempdb1]]); + config(['database.connections.bar' => ['driver' => 'sqlite', 'database' => $tempdb2]]); + + DB::connection('bar')->statement('CREATE TABLE secrets (key, value)'); + DB::connection('bar')->statement('INSERT INTO secrets (key, value) VALUES ("secret_foo", "secret_bar")'); + + Route::post('/central-sqli', function () { + DB::connection('foo')->select(request('q1')); + return json_encode(DB::connection('foo')->select(request('q2'))); + }); + + Route::middleware(InitializeTenancyByPath::class)->post('/{tenant}/tenant-sqli', function () { + DB::select(request('q1')); + return json_encode(DB::select(request('q2'))); + }); + + tenancy(); // trigger features: todo@samuel remove after feature refactor + + if ($disallow) { + expect(fn () => pest()->post('/central-sqli', [ + 'q1' => 'ATTACH DATABASE "' . $tempdb2 . '" as bar', + 'q2' => 'SELECT * from bar.secrets', + ])->json())->toThrow(QueryException::class, 'not authorized'); + } else { + expect(pest()->post('/central-sqli', [ + 'q1' => 'ATTACH DATABASE "' . $tempdb2 . '" as bar', + 'q2' => 'SELECT * from bar.secrets', + ])->json()[0])->toBe([ + 'key' => 'secret_foo', + 'value' => 'secret_bar', + ]); + } + + $tenant = Tenant::create([ + 'tenancy_db_connection' => 'sqlite', + ]); + + if ($disallow) { + expect(fn () => pest()->post($tenant->id . '/tenant-sqli', [ + 'q1' => 'ATTACH DATABASE "' . $tempdb2 . '" as baz', + 'q2' => 'SELECT * from bar.secrets', + ])->json())->toThrow(QueryException::class, 'not authorized'); + } else { + expect(pest()->post($tenant->id . '/tenant-sqli', [ + 'q1' => 'ATTACH DATABASE "' . $tempdb2 . '" as baz', + 'q2' => 'SELECT * from baz.secrets', + ])->json()[0])->toBe([ + 'key' => 'secret_foo', + 'value' => 'secret_bar', + ]); + } +})->with([true, false]);