From e24c2c680346fb73bdb65edb9fbce215d915c6bc Mon Sep 17 00:00:00 2001 From: Mondo Diaz Date: Thu, 4 Dec 2025 10:14:49 -0600 Subject: [PATCH] Initial commit: Orchard content-addressable storage system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Go server with Gin framework - PostgreSQL for metadata storage - MinIO/S3 for artifact storage with SHA256 content addressing - REST API for grove/tree/fruit operations - Web UI for managing artifacts - Docker Compose setup for local development 馃 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .dockerignore | 34 + .gitignore | 50 ++ Dockerfile | 48 ++ Makefile | 97 +++ Orchard 路 Wiki 路 BSF Integration 路 GitLab.pdf | Bin 0 -> 254872 bytes cmd/orchard-server/main.go | 85 +++ config.yaml | 28 + docker-compose.yml | 116 ++++ go.mod | 70 ++ go.sum | 171 +++++ internal/api/handlers.go | 442 +++++++++++++ internal/api/router.go | 153 +++++ internal/api/static/app.js | 573 +++++++++++++++++ internal/api/static/index.html | 183 ++++++ internal/api/static/style.css | 603 ++++++++++++++++++ internal/config/config.go | 104 +++ internal/models/models.go | 110 ++++ internal/storage/database.go | 346 ++++++++++ internal/storage/s3.go | 158 +++++ migrations/001_initial.sql | 160 +++++ 20 files changed, 3531 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 Orchard 路 Wiki 路 BSF Integration 路 GitLab.pdf create mode 100644 cmd/orchard-server/main.go create mode 100644 config.yaml create mode 100644 docker-compose.yml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/api/handlers.go create mode 100644 internal/api/router.go create mode 100644 internal/api/static/app.js create mode 100644 internal/api/static/index.html create mode 100644 internal/api/static/style.css create mode 100644 internal/config/config.go create mode 100644 internal/models/models.go create mode 100644 internal/storage/database.go create mode 100644 internal/storage/s3.go create mode 100644 migrations/001_initial.sql diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b8ba722 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,34 @@ +# Git +.git +.gitignore + +# IDE +.idea/ +.vscode/ + +# Documentation +*.md +*.pdf +docs/ + +# Local config +config.local.yaml +.env* + +# Build artifacts +/bin/ +/build/ +/dist/ + +# Test artifacts +*_test.go +coverage.out + +# OS files +.DS_Store +Thumbs.db + +# Local cache +.orchard/ +tmp/ +temp/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cb060d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,50 @@ +# Binaries +/bin/ +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary +*.test + +# Output of go coverage tool +*.out + +# Go workspace file +go.work + +# IDE +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Build +/build/ +/dist/ + +# Local config overrides +config.local.yaml + +# Environment files +.env +.env.local +.env.*.local + +# Logs +*.log +logs/ + +# Local Orchard cache +.orchard/ + +# Temp files +tmp/ +temp/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4a6520d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,48 @@ +# Build stage +FROM golang:1.22-alpine AS builder + +RUN apk add --no-cache git ca-certificates + +WORKDIR /app + +# Copy go mod files +COPY go.mod go.sum* ./ +RUN go mod download + +# Copy source code +COPY . . + +# Build the binary +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ + -ldflags="-w -s" \ + -o /orchard-server \ + ./cmd/orchard-server + +# Runtime stage +FROM alpine:3.19 + +RUN apk add --no-cache ca-certificates tzdata + +# Create non-root user +RUN addgroup -g 1000 orchard && \ + adduser -u 1000 -G orchard -s /bin/sh -D orchard + +WORKDIR /app + +# Copy binary from builder +COPY --from=builder /orchard-server /app/orchard-server + +# Copy migrations +COPY --from=builder /app/migrations /app/migrations + +# Set ownership +RUN chown -R orchard:orchard /app + +USER orchard + +EXPOSE 8080 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1 + +ENTRYPOINT ["/app/orchard-server"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fb90510 --- /dev/null +++ b/Makefile @@ -0,0 +1,97 @@ +.PHONY: build run test clean docker-build docker-up docker-down migrate + +# Go parameters +GOCMD=go +GOBUILD=$(GOCMD) build +GOTEST=$(GOCMD) test +GOCLEAN=$(GOCMD) clean +GOMOD=$(GOCMD) mod +BINARY_NAME=orchard-server +BINARY_PATH=./bin/$(BINARY_NAME) + +# Build the application +build: + @echo "Building $(BINARY_NAME)..." + @mkdir -p ./bin + $(GOBUILD) -o $(BINARY_PATH) -v ./cmd/orchard-server + +# Run the application locally +run: build + @echo "Running $(BINARY_NAME)..." + $(BINARY_PATH) + +# Run tests +test: + @echo "Running tests..." + $(GOTEST) -v ./... + +# Clean build artifacts +clean: + @echo "Cleaning..." + $(GOCLEAN) + rm -rf ./bin + +# Download dependencies +deps: + @echo "Downloading dependencies..." + $(GOMOD) download + $(GOMOD) tidy + +# Build Docker image +docker-build: + @echo "Building Docker image..." + docker build -t orchard-server:latest . + +# Start all services with Docker Compose +docker-up: + @echo "Starting services..." + docker-compose up -d + +# Stop all services +docker-down: + @echo "Stopping services..." + docker-compose down + +# View logs +docker-logs: + docker-compose logs -f orchard-server + +# Run database migrations manually +migrate: + @echo "Running migrations..." + docker-compose exec postgres psql -U orchard -d orchard -f /docker-entrypoint-initdb.d/001_initial.sql + +# Development: Start dependencies only (db, minio, redis) +dev-deps: + @echo "Starting development dependencies..." + docker-compose up -d postgres minio minio-init redis + +# Full rebuild and restart +rebuild: docker-down docker-build docker-up + +# Show service status +status: + docker-compose ps + +# Initialize the S3 bucket +init-bucket: + @echo "Initializing S3 bucket..." + docker-compose up minio-init + +# Help +help: + @echo "Orchard Server Makefile" + @echo "" + @echo "Usage:" + @echo " make build - Build the Go binary" + @echo " make run - Build and run locally" + @echo " make test - Run tests" + @echo " make clean - Clean build artifacts" + @echo " make deps - Download dependencies" + @echo " make docker-build - Build Docker image" + @echo " make docker-up - Start all services" + @echo " make docker-down - Stop all services" + @echo " make docker-logs - View orchard-server logs" + @echo " make dev-deps - Start only dependencies for local dev" + @echo " make rebuild - Full rebuild and restart" + @echo " make status - Show service status" diff --git a/Orchard 路 Wiki 路 BSF Integration 路 GitLab.pdf b/Orchard 路 Wiki 路 BSF Integration 路 GitLab.pdf new file mode 100644 index 0000000000000000000000000000000000000000..efe54e2555f7fbf80fc7e83b6bb5bfd49d7f6ee7 GIT binary patch literal 254872 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%0D@8B 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 fvJ(SaAZ8Xpw2*r)F!Pl^&I52ga zAYrT*FvN&!52ZFIAZuj6S%{uodkPe(vSVR*&z;TL0IfYl%Vq6Go5KDTv;~>u4g(+E zO$I;B3$NK3Q0QN#%LMb(O)QD;gD{YpsAoL^Wn&wu>6)nzOA84qO$Fk_WC5lBOdgip zCqY@nn@%3tV)$D{L1&>BtZaG`GLJo5z8rR|$x?DlnYrjZIi6n;Z4Z>Wg1Js!k>ih6 zjI|G4%*T{I#x=#YrYhf0Ts0+#{=qXB9bgPw7>pf+`8pCveEmY20R|%+jW_jzUuR^v z2l)AZnI?@@#>j{>1jb!{_P|UG>ig}73b2nH$^zCm)3}PJ(Jq}}=SbA+Tl zAbw{~>Ac9-iPBHQ#`F!h#R}WXWHcKiy{W$C%#8x%0I05+uZmVdyQ$g=6{%ZhNdS$F zk{(cdZ$w#WXJ}_xC@~eGI@xksshuKjDcd(?hCsnkqw~y`+^5R!8!3x=LW08F19_n~ zeB}6s$q+X+fU(4usZ*_zAys9|8#+?n0@|>&(j?n<&(t7)cVWUCEc?JB&@>#ZWN`iT z31qZrS??l9LAg+FRp&hd7KPOa&+*1zH~hqoKoaOAsVK(z0(!-D`BD^~Ob#HN;>uUB zed9BD;Ln}u(AXJM6~^DyR~ab3#as(Vb`R5|OqO9C@v#S8APL{ohjY>#DB7N~_Y~&GXa6FQJcwm2Z1h2oxEXT-8~=>rd)vQ+rXB>Sf;5-GfTh4 zWH{kQ3mCGt1*8q}Suq3EqO0GEl1?~VQy*s3@esoFb%jA_+60;_3VZlDR+36x-~sX_ z!F@Ud7TG{w_RZ!vi?xVn@pIZNB6!y697IN}>=*qWuh zvX&Yi|FC~ReD(jnGSu|+L^Lx~@o9q@v}%6;h~b9322REp%lglnhTIjaZrQqD1fU^k zNj~<}bil%17LaUIZ9||{!B_`0o-}s=^O)Y>lBKiA?>UzlWnGIiKzxouP!i)GueDMJ zhuzi51Zpt`JEh#69x+{5w7Z}m4fH>=qE}BG(1OwD2Xp`5}Vy(xsTu-TIZfej7DJi*1x1g=GGql2!KzJB6V#yFW7=*K( zCn(Fr-Vtp#1MpSI;3Z6LwiJJ^it~Ct-=Pi#Ob3|$Y5fFil%OkPwRQ$JY4q8IBOWwO zGBI8*EKx*fSmx|MHwo<9w1P@j&rhg3{ju=X8!T413txv=NiMp-}IwQ#l zFCr(2no}eu)TH+$oD6P%fRWu{&H2nmb`Vp)QM2BmaOQm zficRMTshMXN*B7hxgjKYfmd^7v*=XYk6XFxGUF}ATV0df<5Z*;*TGt9J>+$N@Y6ACx{X@L@y<1g=cP_iJ~#US~IAk zjugX_W`4pvCkksXIdZ61xg3(>M?I<^e?y{voaPZ5K;-s6&JlJ`8Moy|U;@pS5eF`v zUz>7BF9o+>qiRn#`)cG_@=#VHo2IdVmLuy2mTB&_oI6&D8-Lo0fR9rg3(=~PZFlyw z5QGEGcs)Jwr;P~!;lIU_znojJ=4>#P7)3hSxQq-JDfH`5hi#)(}F$yfwe#@kQPnX)CEBj znLvi_Ig$HFoC@Klt=DVj0`R1tVE~drTklMfk0#cDFzZjr-D+>nGA^pc_XLNN4Qy- z-6=|;4NRp<14#shO@{r`Xp4YgzX7PO(zz)>i$Nl9fTEp*^8@L&m5oa93j^tx@k;O0 z1?Q)9e@6<~{ve02c+Mpjlp4mz!eofOhy^rg`!J961eDcn65`PC8beJg;3+ZLP(|+D z8)L994<+2eI!h;57V}Q!l;9{xb7<5(;+1Ny zpOuBTmyEGg=G>;k90gCU2l`4Uh!&zCp<)!K7ndT@CGus!&@xgd!X$j;=MixpX&@}= zr54eJq-IS_Zmy$8QX79MX3nA27Y3lhhxJ;3PyOCXvv4|Ec{As0W{P3qN?zZhc7etOa|NNHw>iP! za6CNe@@w`pvgD66X)TQjMn6bCT3#PUEs`Q78J=Dm${o#3n~4Dccd2l003O0kjhz+P z*x>C+6ck7GC#{SQH>V7tuQvs2jq>Ptm>Sj9EI9_+5?}RrGzU{;SWP#n6F)^$Fg+L( zBy<$kDo^E@S10s4xr@0yX2<$-!C<7>RJmJ=W`?>xW2exwG>+4%ti>$AbH}T1Jm4L2ZZ->k z@VC)D55dOB+xgcg*&@#xvc-eKNvqcmt(DDc0217k!*{vC=8`mM!38lRf z##q#~v1iJe|Cdy!pteM^FWVJZaIGV)TQsPOPEzatjl&}r}*e*R602d^D9bA0@=jI zReji$+k!Ra@3Yx>6^cLG({m!4tA}P{_L9Tw#b;vXkTdM2Hvsdg2nt?CX-`F;|9bq3 z=AN}U8;9@nwLIAP@bu<`xNS?v*L!=9W}a;+ z7`_Vh*IVn?u=?A0zQH$_s^sJj#*E>|5B6lNLy_SkD4^YP7kY|5?RcF16VREhu`GHQ zerk9scfecU!fyJC(kaAM_m7e7wY*4QQoScz6QykZ_#EB-R>hfJ&=uEr{MyxvBX%13 z^+B8Da0KY|+Q0p}jKXfs1j9VqOe8v{_K8$B9Q%}*)`haj?!Nc=i_NFSqdkT%qlDb* z%HeTdDw3uW#8|4<#%MPALlR6{%b<)9h1#T2Qge*sO>e1fgtF@c_buQ{=pa=0r3IY4 z43yzLa1>-n9YpnqP%>$R+ zbDar}nx56>gX~~M?vmVh1`+N(sLYwn2YI{{jb`_qi^j##9fS(Ot4>^$w0uUkI);w6 z+#DBvy^p`j=XLqK9E~q_6QI-C^rw(>;23c4lLCRagDnuM;8(Y-OLn~;m65h(krq6_ zY__Gj^nPw9neYC*9jwDk4dnfCa`M1X&-3y0@NuFz$nDQ;@(PnGb8Ep}#%gnk&1S{f zot<={H@JRKIq$)&Zf#oO=c^M_MfZHylW6vG%D7gbOd$i)PEv>4o-k2#KA{5kWZ4`-KKV;KdQ8DhY6+heuuuN<(#Wel7 zc~g*FqQkVQFPFU>lrWNtdI6i^xP^fc4aRWa`heeo&vyJq3=wRrw@13=4PaiCSs&>> z>WH1&Nad4V_~_hCm~uqexCtLL;LXDoxaPM9k)yCP#sdi>a)m_&8h4HP?9jbz{qr%_ z>f7w%S&2MBH_Q3&e*b}>bM~|M`W2O}+ zm82wTSyRc z>*)*|5(aX!2524Q{C|yn-rl@l&lb* zVBB>oMx8;xw4l42xuPazS~FErh`(V=S2>ONHo6{U;jg5iyL_laG=TGGa#EG$3gBY* z7CN(9?CW|nD3J23fE=JUibish{U^=O;C#wsmmS<8NvxSo?vMBB361^@pnaDM&G;87 z3Kw`lf8s*DdB9c?=6?C-n%Ue@L~*&qx=!_UIuA_PSk@(Y+-lOS0^vZ_z}(AbhVFWH z&KlcZ3PKj`nX9Ry)px{DILNE}L@fWqcgEx#vy;x$j@|=gi9I3c|1SyjV&6Hi_cw*TDUh)C7 zd{Gt~FF+kZNrzoR*Sp6LcYU1iOqfq6T6%#KtT74K@a`U!49K|_i9FVuY)JxfUEZ$e zuzFL^ShktH4(Bx;4cAauay4oofJUZ+uXF30|$>M;?0%BBhjJbA}huLtMTMfIZwuSI;g2d>jzZ9}dN zB)Ho0evWekZVf#5YKd%ema;2}ESU;U{ zTM%yuxkjQ+nic>Pqc`4WU`XQS($C)MOi|bOb&QlEJcqajOMkq<202erhv-qU!x7Iz z!)`B3=(2IO;1?yy-IJ*WEaL8WEbbZ6jhVnujN5M*W(k!uR?M_+bTB8vr3MYv%*v!p zoHbjJH+i|R?n@sbHaZci*Hr*L@!I0}jhe~N|K})8Y>bvB3gzBat0XyuwTux?7S4~S zm07{H@b|4@w%+1yf^mAQ;Eaxffmo74cq3e)KbQP-4T9IovRA73rbP zHcPJ(*BJn-tzz>7!zpoy86%y}8*4O-)NoXvzkM63L6|$aCaJs+)K5&U*EvSj2w$0C zIN(avcWU6m&~3P0;{^QX8!rWYErZ^KOQ=zF^f){N38XYS+;BTh%py?trI^o^%C`Ck zGrWH=#I8i1CP6@PvY4ytm`xyW7ENy`DvG-Y+yIGIKpYMbu@bojK3VbZ$%ID5VA$wQ zTsb7dA~iW7EyY-Nht;6Lw5|B+8_M#kPmnvHru83#YEOW{rtW@Y+FL91=&Ntpf^6q_ z^9+yyvvC}dz;Z{ou0HN3Zuzv@-4XsiEc?+e3=4WTaOmgwwtE%sig=no4<;=yCzVy% z`@JnLE!of~$K=GEf;BCAlN5ZA6gBfGa!)ulrpZKFK%D50~_{5l8s@$snR($JxU zhnu~{B`@=MdD275Q*T6CEO~9HH2fC>%W%;%N`=5VzeJoRlEero&>HGTjzniZz_t}f6 z#*eG3Rkx>+%712?rY|PQsA`&xx_3mRsKo1s#}yfq%AS8#@Gj7}Y;x)8e+DBmG|Y>z zJu#YCg{?6pp)zaADq6^fyKRmH*K@Ap*N$u_rqu7mYQ zS*u#^^?3BtZnnA2-S0Lcb8=Y9$IB1pa#Pxw@_5_vMzE{LUG}S zTkX?q$Pa&0PkTRlZ!|r%(F1py$YZ;JGM4?UI(Tyie2hB&{5INOOa{2I1ZZWOwugG* zu9tgvi@drZ_J6Tku5afVn!fKyR%qMp{EouD41YTzo!=I4`r&X8SiDWS6$G;3)&@uF zOkbwoHb!{O;ad~elsXpVCmZC}><|ImZTWJ5!e71_vm5cBynH! zh{dR#v(i9G@u~KZGGQLO2n!E6>Mf4+^S-eHr`u72$*}rSq~_AVt>>?l7b=**h)1f?Cr&8pl^t)sy89?lbBpL1G8JEngf&%|qXDY9 z(kibs=pcgtyIiAHuhzD1dA*VKWLN^Ljm%@?v@~yhPpGxyvDTvO^65-I`~qm%c>|rOW&MCim8+%a%=W&q#47sep3FpQJ20gZ&-=q)ji2!Md~Jx# z>NY&qCQKtUjM|(kS%rl{+qM3O=8l-H&h|4A#(~ORJJ^mu0UFQR@Iz42Tn!{)>97NZ zJ|kkBX2k9|hP%!bfU4$HZ7hLxyoj4MvN@btaLT~;;b2BLtR*)OI5SnVuB_g*RqH_& z$Z1sHd#G=Y$mGD|z&-OMzbn~F?+?^%Dk0+@MVtnbQGUiqH%wF3Sd~0xS6;}7+5*b& z5{4u35j&#teMD)W@pR=2;PWaME3D6oqDulZ1#tNzl$e5OcYV&jPyYJ{Ru4~$8z(S|pwvJ$a&nCeqOpBnouC=`35&MVfBTl+KN3Oh(kwidgs_xN*v zPN)0LF24UdrzQjH|Hj)p#^@F`43=fvwr$(CZQHhOo40J+xMlN}ZM$mfO}_4Y)9K9g zpPB#9d9qKAch+9ZOd1EfP#whN<8K}Lpz}=KgQ-%zQQL2Trmt`eq_md`?77fkrTGRF zf<3|V1^b62r==lSaD_dj35UBr_V>>oA5I7M4VQFqcKCnZtHRCQ<>P13Uy&j4^Z8Gz zJjgD*W@+&x6Dzo3gojBgJ3$(`2Lf3iDvg2cCAzzKDr%*!>9Ub;6c#4{!(XyJF)_{U^J!J?x6s#SFmfpsqDMhY17l)<LQ1 zufoACdDh`-shIAxR)@gzLm3_vih611baHn(XZVIYkK%8 zp=RDb2%CyOPjr(DPp$GcL}t2&zq}qj*1+81G2O@=9H5Wy2pn&>-hk%&kzskyn$2`; zv>kSaPj%s@r^mYaL}Wj}EsAbJf#jL3elV7Hw`PB?~Z)oTW?4k0y!QNO(5K02Wd<8$|GKFb5G}f^blAtUMtZu zhjX7wM7Ah$-KdUS6yI6`{b1h=M?dJuo!G!P!p#j=?rk(5c>zYHP5MSD#NX_^b8&UK-o3pAgOYAxOSL=q`d-#??)Aopc!xIe zjh~hf`V?{uQ71kpIH2dXYlX(Cws|}k-TQ#9-lFQIihX2+5v6+N37VBGAN8#BMg;%p)>FsLEAtboSPI*~R6RQqS&9AVOfTb-g z)jfXEw*zdl53szg4 z-n#56;&#ozGX1nsHRM6H3rLbOpIy1$pF;)-vFXHdM;!?f|&cyrxfO>?I{e=^aM z_z@e9BlP#vr=7*ItN5__0OX@Oz8~ASJJCQm9)DlO>&fY5<};xV$!$;HFQFf=-qr;n zsxRI1@eBTttlmjrrIn+%YrEX*{j{@MM)SlmUv@ipS8cx2jS(CF_tzp11^J`nbMzT0na7}`FpiSqpmm}1=aK<#$Wijd&*P_y8@;dcd+0{U z?{fcq-M(+PnPDv8HL^3`G(RckM^v%MF(gRP+pjA1Q&0H4nIpyl;||G@#lDKisx7rN z-nWXi?l-#RI=wynh%@+#S{1b_JAv(whd?$T+QyJFk+c$J@5YooNzug@f1RH%E_Qbv z>Zs|}#68WhFgZfwwWp5^!gsxN1R{#vIlF8>^{eVjx6AVifN>t$kL_mL54h7sm@hZ> zm800ju!^fzV33PV3F|W2$(JraZTa0B2G*}u+bkejo2tSKNy_{b+n(HJFY3_BEW@s< zPQ2|&`83(45$7iYl!|VMkgZ^HJ&Vh7M{V|G6;t>);boib!n;X9%vL5Dw*iV%v@WTv z7zX$VmJ``pTwxYFP5iu+oq%X2?CEw}G6F|R=Y{wMH*LJ^jFRnTG~C2Qa*`+ho?6Sb z6((TFbNqlIRZ!AZOVp-YfW>I}V08g^wF-VdKe{MwyV^zY6hJAzC#XisrTex5>Roe| zm(dojALsdWq9;<;YTOJimqz=!#F%^CbFo%}m-#_EZdn5w?b|@0*-G1J#0m1HFXy*m zh#iB1i)NwWF_z7_G=bp$ ztAa>`b;k^@Kcf(-R_?~@t(%bX9HjwP%?29^oHaJtv?&0|yfJFY%1+)MGnQSptb%t! zvfQdyYkFn7oHwbd_wyREa)#bSJ3GOI;vy~9Z2|FaLgj&|Ok$|rP7Cm7CO-n8>6+2NiG55zudBSfmu1nQ0w zPKYA|M?`JK`+y_Lcm0b+^ebK1{TL@U*>DY=5R|HaJvbbJaF%>K9tG)Xw z&uM`@vcYdS?}DkqKE-DwSKLg2O=twpy0F#kId`6i8WRQd?Dat{Q&-UD<~3U(b?F*u z<~<0Tf2L3lszePAl@K*-RZpk`8IPJAQ<2BRYYoh;GXv@A4=X^x&Ikj!O*ufPvkvJm zJ0u~F_M&j(oO8}U$nhWSeC&0nb!kw1RN1-_#K)mZdbGGLeT};uteza(*(b>z_gw;{ zdpDa7R~rdA7@wN2qNh`}A+Q|7r7k54SVK~1BLJ@OFzfpq~iM}yuVaU`)ULRJ}hIRnd!H;*U z4}AOc0bmra52~S1GG>_#c|TEeEUe&5bM$S_MLB+9ZdZ_V2n%%7k3b^f^;RefZuZ)q zKTwU~^E?cRA2R@tY^=t_Dv(Zr_r6E04W>VdBufE!0HkmgwXWwQqI(Oylb1)Hvv^wl zrW^sAWg|iy+~y~P_tk+G>Rn(PtcGXydWl0!=9$bAV(%oTAEIGUPSow6lz-DF*6E)? z=jy|le}<2f82&!b1)HF9245n3Pk8N4K_;O`9r7X8R`}-fDZcX$> zFYGCQ3i=3WUR!4%!}t(GPkQ5+VQ4E0E{TUA!7SrAr_oJ(bp*kIl0ytAk!I-z3t$=* zu`!<*-81G|yJ>X54iQSQZIQxc*{A2O46b5;Wj;e7ZcJCKR{IBHQ4orIS@G11v6>~V-N^Y+{T*2aa%+P zf()(4oiBq6o26KAFw?$Xs3BgN+1Vb~wk3~>mfYjKo$l_eD32XS4N%P6VbR8nSQTwQ zKC5j`yUmTCAd!;TIqG%q^WnPDtaQ=}x!tzNiS+T*m%cCGN{EM8-O%JTp%r~EJ4k+P zp8{OGi-#v980(b`;0g(>lbRy7Kez6d;@|KmflO_;wT&IGA4+xoq%bVE3D)UHt*q zQ+^|FS;Wxu`Zk7t`ta2W8=;vDiKm0{VTo!n;OA>_m`u^WOeu}Xt(~OoX4MJ*SPMvW z$It7FoHu074L>uH7Ewwga%(D=oW3qxk5VPqMd`yrx)71%#FrJl-Do_f&miuDU}Y16 zDDp;-O1m&#?F(aW%HMLE*~C#0D;hvNZsW#lLOT*+S0`sXx{tRNS&P!q1ZuN0B<~#A z(Y#64(yAi{DLHTXkxq#doJ37G07Iiap!f5udTuK*Iqw5VsLoXxo~T{xByjx;5}AV+ zR<6(5HPaHd3Lu5;S?eF0-Rr`J`?vP1KHf_2n*+P#9%AsdUfp6&j1*co{BSxy@8ZU3 zLSuN_0(Et7uVbjEtnne89NM^n*Thw6qI9D-d^9*@-vQ(S-G)IDQ6@QzaNHS2~1D330ZxXi4^WvUV3&D39$A3QuB>RXdtN(8GVLVxLKGT1Pl@NVRSF9 zA$(zfyt7{1ThI!&|K1_~*?y)SYgPW#q`-0%vS}@b2*3FJ5sTJk&zd=gzM8XU3#M@QM|c9a1wwXb^x0Ah5? zmc^Xel$r^w$}}UdyAB?EI19l`{x||Kp+nZUDsTFfF*VPm1G>i-O~92*fg1+*WTg@^Rlf?=U8>e%^@kF&DwM_!0gX3jXy0f z6Zf1dI7MvPisijWjaV*V8DEBR8={!^z?gQU6P9hJT*1pDmL;kn_AwDN@P747k~#w; zK{R_Fnw-<9$5QHUSUv_8G?9eWY<$9H#0N(uzra?n(h2B1Rt#^1y9lBIU+hM)URB9? ze1NTD?QWj^6dp*S8YD&WOFg*Q_er^#Cg}pS3|C<}4q&NUNcRK|Uv8?gvKgjrlbBVQ z^>j9@Y81t(!8WO4`gnL@F3^OQ0IwC+s>~M8<|JvMUPH=YhN+7F1i(uHdtDYTprKu$ z#jqF|^0bs!44jadS=gs!W==t6>z~m`{FH8RL>yM8(}*)dqD~<(7jI}xx3CB$@f2s= z>uw)|qt0Y<4vam19nOl-=-?e7E{}EaPDr?*2wO`x%MAa$A-xZDq>MRw(jbLoj!6)U3-hw&FQ> zk6d1Bsb9Fnn3y(p02}7D3Bwu)?p$xxxwVvS%m*H2$fn0tYLAP!^ED0DZ^qm3pq%^ zIr6KJ0Kk%H0Rb5Y(V|=bgA(ab1sUQPsDG4?b7hzO41AMKh*cwYX_H1AHbD^Sx=)4>lj#lY?~_3gmc003N`81~IyL^MY| z{_5%6K78FO1m&^3<(rrpo}(qf4d+$Q+UbwF^3KZ!@O*OnKEb;C;dfj=64|bW9Cdv< zf|omlCc&rXbZSW#l_9(;P+6hrkLRz63Hq0sz>2Aqa9vhj;RIf!SGk&$B$CjW9aF>h zk3Ys$z76^lN1l{&@Yrjwi-#dyc`Hm;VvlH(F;li&bncP=CT9epa2JA0IBugOi~fS^ zDnTLAR-&3Ep0?zL@r`zszRVfOOUyoIQsqLnd()0%VOfqsBL@k8KMD58T8;{+QK;i> zPWI?ndq!5nvYm;UtnV;-vD*`b$zhx93~6d)h;SpfgDWFg!!2eykMVQ_^iAi) zdQuHE${?X^W5~(UVDX>tg%bx1a}K+g7!Mc=CQme(XNp3jc)7(7lzd?39om@sHQbHd z#m6^+e^|eP)Zw4e7?9wfqhG#c#(yZJpzc45XOmwB8qHA<2AZtW5i!k7ke%=oIJFH~ z`3wizK755TK+9nf(ul_lFH6*h-s;p>0F3759Q?^Z1S*6T&wGzgeUaY_~SXgB6DB&e==fcGjE}YTY`j2Yre! zg83UV-W@OQT8J4{B@|P8t1G}L!@S(LcVhSKMJVOK8a~XrANVez`{Lh-HoSq%s{gPXx zGOPhoFdh!tPLjKDRy|>#A(&2sG6>4rDJl+bx<(B1^1#5_(sb@XNd;}IJo}I^a`&DT zAJ#dIWxQF8_oMyUf9V39qe~U4<{p1#G<$?H$pT3cpW;cInFB zs+Mth!`M`^lkgZMmU?Bd9P`@z4WLr`4tiDD|o#V_y z9sDH?%^{+D3{-q22wcC8LyU=RYO|MnXz(yonxSL#Bv%t5|DnCbC6hF4dz+VZwTyU- zNC>28EKN+6wpgOkg@2fsQCz?xig@+9S>+H09~?gy|N3QD3%4ZiQb?lXRLf$3L{k27 z7oj_&yu@8B^3;mOd0$9YMBN&GR&>KI30nP908wdQNve#tLQ%O)#DjIihNXgRu&S*M zOP>@No4t@GJ=9K7H-rA?=~e0^*jf4x-4t*w`)>=4fQqCjl>EIWVEB^2iZ$7=8$B!q z?&>zYPZzbBZ_%w%_Bz3Q0C1t~p7K8qdX#!UO@Gj8c+22dF{70OCos#xaiPcy%yvPi zp)^SIbyJ}wP-x=ozf&N`R9NyTfzXN+620DadlcLyK4?9aM$%)S}%cvhu@$ z++8aIvG}RxyIfV!Z21}9(!k%(I9;kVrePo2$@OVeJ2z)YO;g)=rmDnsOU7_B=vi2D zTzf&}3-Z}Shk$#+J8TSt#Ash@>v2JrUG#VMQD-ZI%9&&>A4UlsEuIH9hKRedU}aA2 z__r;ttyhVA4EVU=^4AhobT=QDcvfn$@pgCY#NXFdxhhm`h^c0NJ=RunN0M#cN@wS{ z7p(yLKpnph4;DNR1aLo9GGL$&{1EpLeQAfOjVusP{>+e`q_Hla4{X#B&G z@%R_)e89z+Wm3T;20@YE>&xB4*z6%uty6Nm8O77vg(rx^*FCOeGZsrnjt_qOiAh z?q4)$vJeP&e%I(p8*jxX7a&Y6mcPlxm}R;}9U8U&BoY7Q8}idYu23SVH(5bz4+U_z z_@=%K)h_5puxbA#EhN!YdvO3B?G9~^EviTbm$yvP$B1tn6q7-Q)fE*PQ;$H415Q63 z+8oLO+j!vhwkG5W;3BtpOK{xTqFph|{o6uB9u}4Xy!W1pl4i(DBMj+btc~w8$rZ@9 zUGMC=W<>i3yJesY9jo=wtyg>A=qXzEI6+!g3WPX~=(WB~V*WWOm_GY)+*H+_??}D{ zfDH2F&1sN=nZt-O2>$o82ye#=T)zp);b55?TD+*yDfex2Caz;rDlc?vFO>)Ax?OC! zGSPbL@AL??|7VYC??zDr=?4jM)%nrzB@retR!}Ow+F1;|(x^Sbf;*O71m*G?c9r(J zTJI(%CUPQ9i&EINx!^K#2^QeX*ZjT<-I8DEOIJ{_Mv(o5?wT5(GotB%=8R@=%D65z zj*Y&E=lER$A<&8u*N$BTOdc8rCIY){HRAk?;1go+^mOxYy#o5F|9&K9Rk}4vk?-3Pe4PD2J(RW>A)sH==>yCgJ7fHJ%!i zR|6wOBWHAeOwgE92r{;iT9kzqs%TK$HHb&(1#y>>wC00p5%l^|A76^azQfq-1as4H z^E8>hBIRz|03hL-;=gB|B;oI{r)2n#RF`lRrVdeg`r%6Q*#z5sh&oRoK)=Rrs9UJS zf7ges_+YnS;{4o*x5q?9w^?*yFPDIbGhpD%)s*O&_nN(6f^RVF@GxBSBTtBv(h~a+ zj*CXD6AkUWz)r^y#ekYI4#Us1KD9lFc9Z4wJ31E&i!l+wuw(*lg2ZbC*3B1zyJf4U z(FZpVhdfF|Yllj`^fYhfzc)R3JNwr5VNfE~`1Y$lYJSlELZH;FT`V_3; zuXGMib1-ULxzWj~cv$eE35{TAs|2H9r>pY>FkFD>;qNqvnx%ou8e%ql;$Y+_gn5p9 zf`+olX*VIbs+m0dF^7n@!GrIo^YV_f!>=t&b)nRQ7 zmoNxA47qTn{edBV7_xx1i&OC@-c=(0zJo)5Mg$CDf)~OhC8NZS%@!+NHEADy4nkhq zmBQ9Zssevmpi-vr2$q&mA|u^JvJ}y*n{c3PZeu$Q<<4;(k};&D8=iRy0!iD)14O-Z z79=cT%>|NvNhyZu0H^S%gQ5LoAk)Qjd!b>__OjlhkoAQK$ThH=E^XEcLHL_7H8zZG zQUlhV_u(v}R*S@;a{%Jspm&$)%fgp{C!H7CXvdUu_0Y4O-0JE8TZN_YuxjoN;Yo-; zc(Qgbu)$A10l2fIVfAC+ys%4v;KvC!TCnhjSwHV|w#2v2yt_ozdLY`aaOHgG}f@ z&r_|2Ou`#1rpVNFz6)F4GL@UtD_*d9br-@&QlmK3NC>iFT%j;vj1-j8!W1?Gz7_z= z@4>Q&m1+#@sWy)=psI%^sLQ-kdMpcPOx|z?_E89HvH3Chrx4_&Yt`LsJyY|lcp0EdxOZxvpyz2AD4KwrgM@ zuB{4W+g57JBt{j35nNHnh&#)mIa6hW)eHJF-j1-u5J#FG=@)d=HIZFe+sKbcE!%Yp z2da#PW#4-23Q9OEf}7P~Bg8_do9pucNtZ=JTkdiTS|SW!*LHs@vMcZ(r@CH4Qt*QA?A!?Z=f8c zgLm`_FUMmgk$TZ@ZU_Uo}0xYh!)A$LFq0{W>qZg3u-Dzu#* z2uB&>Ot#^{Bgv3orFUD6#Dxq8S7cc_vN+`H2)J z>_zfF|BNZu1ZFA+f=+%CO@XDniDrmpb}Z0{iWtetNdj|?Gzmbc{kwmgF+#!BHHzkp zgN{#%>aCyiBg&RAf|3^*SR}W4Qe2Tdw?Z#EV8L z9HH((zGt%s#Ha5Y+#jFps#wffKu19?s&$U2PPV@gQf;#^jT6~Rn~pZWDt?(rz~bdX z>>M?lesm-n=o*MKF{qmrpKst=$~!|WkZ1M%?E02|)0^fv8NIJes3)KM{i&xEZPLs% ze~ax*X-%~njO75~bPW8@2ne&G;={#I35V<71l7yr7MlHr4-{{UZawn`Wa`kvaBp6D zpNE0PHrM`|f)FwTX!|7z%U)n%N$RawNbGr<@WCzUr<~`jcVUqZ#AJD4Q_6JsVEiNH z(!n0$w3QeRD@zBMjK+mxIpDx?yk1la0Pff!@g_a@blb>fI- zzZ?KqJqMY;wTZMI?hL7LtZIV|_UMsstUkGp_xN%T!f~dNSfn?Yn6vd%)D%xsOTEEd z&Y#X}pHTe+HznU#R#`qu!vO&;jOcD3DJv#poZktpsX9h0-t_0%Ys}km2oWe}ct(~k z$1M!zJ!^kd+o74R30x_;gM|JQ8F4{UR=E zGW02yHk;_0zk=1vf(#YtQm!NrWOZdpxz!o+bj_Wq>Yf{L-n3OFp1B>+b&5fYR;63= zPg#FxI(kk!_9M{X9{W4Qt}Oj)MoBY}((aeL6%RRYRH;x=@>vx%ZG0}&S6KmciT{Ng z8Qn(tVSW6{4p6AxO;7qbGOqRK_75?X_S2y(u|x*U;tAH6UySQ$?im+UpD z-K*>vpLA5S0cg_caz!$!x@9Jx8)hH-e&2?}@EoYQDFpHD&!14A7iv_%q3uka78b(q z?Pp7!sDniFHi{9{ssO3l*YL2nRTyb_myk7fYMeosi7En<7@ro+gr|uli1V54* zggr`w?>7O2J1A0HF>wOi`IpJK*IL;1zB}7S;?sf-|H}iX8+GYj^`qKFibx|P%r9+YzAni#-(izziNx!}23_1Havf~d+EusA5CAVZSh z6E#alSjgL&)nxF_G-S>HUcGd;8?PJtwZMF5*fK{*$B2Hu1#nX4H{c--ZA42mFZFP3 zO%qrH%8o6ao`k}+tKw{xjd}WqHp+VG9y@*(xn}DV33x4|f;KV4z?f@RAAufh6o5dO zUPo0PDv5wn?KXGcTiXMm5OEh-D-5N?kPK%`7wt5vCfHGhy^yZ6s&8#D0|M6VbYnkJ zHEoTkZc>R1ApP=TpnUBr!0lYYH=>P$1_ozsoCfBYIJrNeyPH6KUl_8Ch=`P&{3v_dNE1|2f*J#wg3b+*%yWXuX z!9kZwFkDza$z$;Gc*BKX$qRiD<6qZX$2R{#Y9t?Y1}|*ei$^~D3?+qx@p5dNbl?Bv z6+&~L)sa{--Bh^;;)mPd(AVQ$!x;AG2oJ*~z-nh@?N;HuYT@Q#Eh8q6+6sN7wKxY0 zWbeN#R*Q~-sZS8_eS?NWQ1jTT?ELeob(8Z5f@aZWi9UY=j)Y!?7D`yoO zb_c(a*^YMU*ex|Njt3_xwUcy!moI2*2oT;}_Rw7NKvUk3)i*wXA1z>aNa<3Z8WZa< zNbTbm$&^^0wB)IXeUI8D@}*j>07{1jx^u(=20h4?5zHgqxX_d&f>-;9DgNXA0&vnG z_E;t$3b5xOW0W{=%pnWUxRzlX5oLcS8YfF8D8Y1(C8;yE9}~i|=8ou&s2oKCa%K(< zItxvq6sB+ETn`2nu_=#6$^@#=37Mf#WI&c3%?4Tg8LiD`Qn!}#NtS8HbPnB}lD(&C z9@fE)W>UAv1g-?pYHJX|UR@gkFD(e2S9gSe&-`WouL~=u4*RRR9O?pY%RC8@XO8ep zh#{jHE*M^VUjcsCdscAtDNr2>o}t@>KP?BqW_Iss(I>J=H%;CGTJmX>Zvm{&ocnma z9}4Ql%i@8_=x|Ct78jIH7Bl4#zSAvx-s_;tq4-uNW?MPj_HQO_8=y(M8yujiDOJ?^As~war!w@q^0K)ZJ8w^dGZhV_fkIoYB~sk|=SDM$r|d9xSNUIo}N65_3M|l8baTM5ViN5$^kxEUqc+r#bFL^H47MB^#Nt z;;~xP+B11>0TaVr8hXmYgjzXct7ztF4aCSNWT&{edqJ3$6qbDhFy~==(FoIz&(XMh z0hmc4GEn)+GBN||fSJRYXp9j>t-QN&q3D6}D-ro>7wy88I_xQ`bd>5$hX)RdLl)xs z-;U`0-zIM7#h?6_`0c~all{H@KRusrZu}o7#BcmNJp0~Gzm9|7zwV0aX= z?EW|0*8fYt>3_p*{jUKh_WvMG|3}=`|Mvl>-)hvaZ|Hv@Su6yM|20?@mH!TL{daDQ zjezmLn|@RAf4$mf=J!lT-`-qhraigL+yIGdC>YKfD(%b>*cBU_p?yzYs*B!lXNWadlh9z0bADR39x~;Yh-BQ5te8G!dJDq#8af@_i zYSwYnm>*GyBtp=NlZeZvA z$=BR%CCL8>GC<5-T8cr)U=x7SXLK99IZ4@i%Our);DQ+>P=5o)q>^+r+$zZ zUCo*3+KIUkpVpE?b5Grwa1DQ|&`zp)>-lC2WlL4oF=tcq6b0{NiVAphPRnR3#c6b3 zO4qaG0@`EId5x=Rt3Su4>SmY0N^|tjsVtbrScsN6xHY)OG7lqsIY&E2c&5CSetNI~ z2Rdq{S0@>VT>4EcBR+qAp}@+Roq&DeZD`fBYP+GP3<3wIGabCleL7+;kqLQ(BCUqzj6-`CepS2JAshqM5cndq2L5a>IJBDZ?z(VKeHdRfRsD4mTonG|xU+$0 zMAbYz>C`zo0ft*f5~X@tpI{aA2dez9*Jq6A0D6RV!+(Y2q}Uj$~+il1z3GU(2F9Y z5Cv#f7-hdgJyIOH00W_cyeG6d|G}+LHL|b#r!_R2^g6Q@)<#!aXLsO=&ul*PIJ(j3u4s`Q4d*=#;g%&$9WD# z21!G44k28)80A<+j~Q+%AsMR)PTXlxZTUY+=-AXLn;(D;0^Hyv{I#= zgc(>$Q-yySL_w4AukG&HR7k|RjHbdGUs0katkw+*;A~283w1h1o#V9}N2;1bjhCvqwnMsd^%n%Thly`A}Oth*|MgdAZq?EFZ11lo(TuOLwQ6PF`KPZ)) zgMvWLNTiFb=p+Q3M%3VJ77nOvq;?xJKI&07+K+Yayd!dgK&eF~cm!hS7Fmc1$^C}N z;W)N3TCv~&Tg7rww|UbS>=VnZ^1<(N@SS=q%L81hx?(gY^E#DWjMgD7&m$1W>YNpj zI%2_SuQd1unluCX&y8_+)~&hQ=Ji zK~9jL*lHsCc`CI?MBu)h=Qa6KrnTDYJorRaP5!kx*|zr9n}>a|slC|s)`WKSeH)-- zq}*P#=OG0Hj#cWgrq>eTNQ_w($3qOH-@bBo!EG=x;hkQj4w&%GEav`47k5o|_$Hx3 zJHnm>-f|0!`ic?`C?q=ffOQvIrA8~VnrvnMB$aVD_`x_zopuOnbZ>9xP@ke5$uLCr zI>}-;QmBCwa}0H)-5^47$M@x$Gwt+)9YryrO(n+-ScFh$2BxZG_*^N*9U8ex6g)~& zS>@VtNu|ana*q|ulN11w zA+}MTvTz=9HjP9XTSHKR=E)(PDf(K^+79Gswzm|b5{w6dN#kL#?}-9D!UNyZCQm#n z(UwAI84z4ZAT2F`#m3CYj*P}1rD2&sWnlLaqd$#TNCzQ$9bnT8jrKu)iU$!~#+RKY z%vf|Z16sgyQR~&w1NtciE!hxFXjVjgBIZ-HhiG*?7w@7h9zAO>ysb)LZQKBeEYTX@ z4sPzRw2};!i{g}v8v*GLd~0ZS;swB@Hr{`7ipxaqoN8HwX;(xz+n(K6d%Jo^{+;X} zUqeuU%cN&t)J`!O%}@*+qTRDV-B1o#h9#|cv*Cc}+v*WxRcWOa`B?LZyFXZ|M7W^C zw!*eRCYu75GX@|Yez#iDBT>7~oR%RVmd!+{xJUG17bH{HZv;e}%B;FoQN&-MwpsD` zsFimc-^LFRYM@(e>K`m3)NU_ZiqeYrM3cqKEbCjPhZFJ+FX6=sn|O15jeD~HI(Mb zZ#7M}-*Ra$#Rje>K-qQspt#Ku8fwz+B789k&@hHlCB^$X2m3pwSQ?hS`=0^kaL+I zIYAeT&ab+@T_ib(smfkZV0GG_fU_!7q6{{O=n<{Xm~HTkK(GP9j9Ilvyfja+u?AS@ z!o8#7;<=B!2 zBUmNMYY%leU-^h1MSs8wYbGcW;6^xQ1z2JU&Som$e0QFW((L=BinmP=xg@nfp&;m_ zJKHOY$!~KoUKU?D5si)%xQPZCL8Yg;XppR@gd`hCITD?|AmgNgj9S)ua#SU_feHAW>AchO#gd06tgsv6&GHg6*6EIM47bh&&6=sh|3^ov0mfQk@eC)M0CBlc}HLE+MVEb>Q4Hi4|P=(&f`)~hsdk;+??QB3>{#bVif zu_lG4YwxUd!#3r@M6|q~x@8tF0N3;lfwgQOgh_puf_AX0!AWu@fs<*W zNSKiq%oH*ngEY+o9G)YLS?Vc*^`8twAq5=ryi7V>O=H9@-H^(OK*&JqAFxZ*eWW& z@>*rF`%mQS^Gl-AlMWbQ&sT*D^|`&{+X22)v|mhL8Tk)Fd`pRV zFY=`T?>z)x2w(y1LVWsJvhCh!`e6XJ(k0U=)}6a#nferqxW6p{Fe2eFM+vzgqo|E= zeo6T4@_s!_GbT;~eVnrf&?(DcQUv1!NkP6Npdk49j{R@Rgvf_=+z)Dn|6L?;pc>|W zpV0#Q$%eg<<*6>5OqyQ%^7li{8s+Z05X8qh>Q}BMY6afg^KAVq=s{;+H|KI zP#cjoF%OH!XH}=@HHMVB6vOgASF)YEbw!vw>3T9d8Y?ZV0*AS%Ak;&MtbCJF9)vj% z4_;N5yzAGdE>zwm=ZAow7PMkas#A2SVPzgOrGCOkKdRmTgmSRfIk zn8Y>+nqtyUBdYqD@jyoXlrwk92$|& zwG>VdJE8Waw9|lM(!1`QrhOB)DmZ1M3=nl0CQKX&lBj?XEQ4`1+0vz?rmUExjfVn~ zT8-7vk_3y%W!N}f0-3!{X%wDvM{H_Q2qW1%q#59AKq;owq#;Zl4tvvRG`*v?a-z~X zk`$#TEtLSo2NX#-!&ZxKouhzs3rz{o`VmRT`$3Dt3P_Vbs4W->5gLe&WI1ObF@l^6 z7*Uf5w6}yx%|=4-R+2U?zSu(uCM-RCvry)r$6pSv0GO=1t93xyu6*S4B_T~hT?=R| ziA;HHi=jtAYhD{JHalvWGGi!wRuF0jZB_80@htckTBnW(e{Uzsf}g8v+ZdIMK+#!_ zWpvMn9oRCp-?|EJ`c3j9Xm*jK6lSJ(cl#WeRmk!^iAdF4D9V5!VvTq9G$jS0^^5t%t1nPQwQQDIzJz49A;?ynYKzdK zmfQ8CZPGgRvJd z6ruzCY_Wur6qz$6WBigp#6$3RlXN4~MX=;)HOJ>b@-X@jLKs#|T71jD)$tuDQG?{o zgjS9e7?5*`lyF-T)7Z=Q8PjX+%GiM+Kv|GQ!z9aKk}@br8xZc?p7oK31fyb);a7AJ zQeCQ`#5(DEK`XzlOy>TAza@gdufFmoV{)OjH%s?nK zMRl4%I}?y9LeM8b+_F{!*#{>7`iQW>bAG|Zv2;oZDBx2^+hF_z z?D&hCW@~URbZTR9_Ensi$_CR03Iid zSp?e>DDrue=*1Ie)rHbd2RY5qu2wNfvD;?k5ltVdCRpIANPw)32T0k4aL`6I3obQX z@Hz!KPtwmRiM!VcB@yYGapXa;>+1%t5Xz&hN-@{c&|-TCAEn{5cM3Wg8a5{cf5qB_ z2h~wnZIo_DhphC9Cat{^&*kwRAa!oe3TFOT`&~VTg29c9V9zofnh_9Wl7D8mjElW2 z6cO)(%_SPAhl%|iOuN4RG#37km`&?mkAfLBG>+)GMneOqO=S%khIU)JZ321`nApw& zA@hKS#fz~B*PsdLaHeY@f=uWbO0D8-yU>**ZaQbde5f<9EF3`Mz_e8bU!#y}B_2M8 zltqx%QYcF)8$-@&P;?H_4E2C8_YOm34L~w+!AF*xYcEpLi1G?lD<&wdZB^o!Mx(Oc z&b(69hpv}kGInYSucvth#CxtXs04;bXv|y75iA5-udIo&yr|ArhEOkSqGCWO3xUm` z$PiTPvb%vPXoHGEga&Ydl8PKsDK`5^OPa2O#WY(ETyV0?AT!Zdr!CggHo2|)-vRc{ zeNGn|Jr*S2!5w`>yYX7Ln^X}$Qd5?=7=|I^We)2skBzjYZ19-uzu384LM;Zlk5kv+ zIkSfJd6=Z3-I{Z%D=5vM11gyY<%S(4929+rN#1;04&eCW>v^R6Z(2D#*Jvm~o7hbC zf|!RTiM!hgB@nR{la!^raCx0!P1+3yVA*?nLC8o^u>8nK&T&t& zf9uhA{uTk47j*Xg6<3$rTE+M+Rsp8Kg6m4## z4N_aOGv#U!x^Mk+TX6+>-BNb9-CtA#Iwz8^)Ua5&s_0~6pA)hsYA=H&nIT z^2EBdH*oredplQ02ryX=LtBqg=C;uvj|;MZJ^%y1B={9TF7QMFtR_x!cF0JI8iJY3*GpsR+YZf5-mNQ6nQj ziKZ(aorKfmhy=ls!6*a_z779GdSv_tXTxDZT~w`e?0VWw600+v-$qL_sdru8_yWWm z9vrW=W`TG~Ded}qv=JWs+X7!N_`gVd3*gF`EL+#i%*@Qp%*-w`Gcz+YGc!Y(*)B8N zWoBkBGsE@Y-80iY(|6*&co8Q;M=9k_DUY;|Liy!dmCJ@OJInb}B1XYhdFDj}UMQTg zmSp2LDzH0tU_kc{So6savL4jMfFR=gW_)isfxY6spD>?@>d-n5&+u6J3v^;rQXmJz z7A?g9@vN-DETJb-OUc*xtR;_KK=A}R>}^RI;jy9S-O2z`jG+D@FD0Nx zqxZ&_<3juwJ6!ew!U&_VqN`x|PeY~q1I#F z;OkB=UZ&-W7A%B#qgq@99#Uz8)f$0kZP1t=p?8EjCo7YO9tYH*M zLa6>6OFCAbt)g61dZg~Fik_qlEWLs7`*?;Sb9PyBd+F^gMdz{nvLXU(8>=}PGU!^H zrqGo`zau2W`q{6TH`6=#s}A=#Zh)kp|6QaB7-h^4TnOTxL{wBd!an>oCQIg?+2kz8 za88}bpNZGTi@iD|zmiK@Eik1XWUTu#;98*^*GLFs%@QhpgAZ&b=K_1|P48ES z|BRvepF)8^aNTzTyTlZ&oVr(SNwcB7hIV}>PinMCquB-5Cqma>28OQ?wqlXuCaFYV zjbuf|k1#2U==x2kLPQ1|9b)PB@1-2~1d7)VA!U&`T&EX^xFo4N&FGPc;)R@^_UUyo@{IU^u|6DBhW=(QZZSEl;jOh~&E_OZKSD(+ezGGptonHTbQ2XCQ?lx8=SxW~-cNZ&@~ z^%mw>O55lX(i-dDDD4E{!KQVwzuY&2yZFg;N|QqJ@mmFxKnug%dyV4ysRpi}wbR~| z>jeypxza741qnE{Ur=O{^5yIcIc!Bw@J@ZKd)6PxOsSaUjajbkv#Bsx+CoNF44u`@ z&%3*DQF6Kz<}1kJr3PzgDxmD7h2dWN6K8Jb_C*{rBUm2LuMHCv5TDqXZ6@!PV!7?T zx@e|6pc!xyZ2a4e{X)N6_j1>nlkdg&vXXSpy< zRFLM~`7uC)6(nRj<>`Y+_L5o>I(C_uHBvte)HLur2~CD)#y@ZvIvnok2-1Gg8Ej~J zHHQ*wKUvk{^fc$qt&Wm3khb<_{kABu?CNVj^NKbZ4`Gdk-6Mrw0(dx56{}kUs!eeC z70)rX(wP~uX&A$;ZNo5XaAMC2o7L9RC-aj9XncV~cd%3jx@MIcP72$rZ%1&I1Z-gs zzL;{)ua54QFa(JnbO39-!U=(IPHnxm?UveA;g{c56AK5v1~EfZ!?1#0l14(`P@Vrq z8U3(Un@fwR+>ez5Ys5a$or-Dcu2lBy@UKsvFDAc~Jl}V;Kf%7#eLDt<1kdO_gyIE% z3RWFDaJg8u_m_!&Q{ag7a_c|vE{h@KgKHA{WpHD?3OOpp z=Ypr{(rFN#lKy~~Q4~l@`W|3Wt+yr3mpB8koa=L25rhEeQb4r`zioxx3dv6~li*L* zcO1csw-2o?i%lfkj~W=0oJTCGRB2aobQR>G_h9OZbYcmTng<+2E5;F{#3Oe^IT!K+T;DZowcJq(HSC zQRy{KtShZ0f-K^c3E6`%;V~HQ56Z^=!B-e;0<(1v`HbxArq@T--wL&iFMXkUo7LL{ zJqDb#3SZ4)x-hCk%ojtFO?C$8G)G{&SlLf9LA};EOA?mW5=YJ%-#_SV6QDav0*O6-MB5K~kTWq+Dh2 z6b4=G)Q)&qCh6owN%E_Y`SDQlQL2!hh{7ZmBrkb^amU^gJU6%-<Ys-vz1gQurBdJiQFjx@xY0w`jp)R&t>MV$^v7zFp4yt$y z_y?)H#~S8#t4)gTJfS$b#&jD@*zjEdjA{>yTw zTdMfx*gi?a%z_`)A6{M8xT{SYJl-tciz{5(xXP<04$rn{g6?JF?)c1;@VzeaAofU4 z4Qz2AGTkw<(+5?s?UC=!@Z~o*ao9oaKRNtk;Qhti-@o{|{qC;9j_L3I&?6)gcSb}^^B-7ygm1<3 z&xXv)(@(r7Er*xpe(t^>-npUs@qax(Oe}Bf?cnYIp`UJ0z%T4cw3$yWhtpttBroEy z!C7D_qwF~WY85x%tB;`_IzpTHlCW}o(N_ML@=syz-hTKp-n8}XXPcY4YcWu0dlYT$*f(!bFLjH zV`>&0GnR81{pHWwQMX_G7<rb^-s`ZyEs~?1OaEhp;8>l7_8ch(+(Sh+`yXQ)oi_KDFS|#~(kE#|-!yH7^ zWkq7Y>cS{J%B1=*5A==`PeW^L!FY;Ry>LcqiGz3RkB@HeryzqHcm#q4aI z|5p4B;1T>6en;@19N+&9-TQAggHTNWIJxgQ|5ps~UvWQze~akRIyHgGl}aCUV0-uu7$3F;qWcz^Bl-97XQCXPlX_RcN_)&%s*vIb681RVd6 zo)fZgcKY5bY-eL{XZzQ_90c?-CbnkZ?Qwqh5dGgp=b-4t{%S|W#K_LrnxV6^C+ zp1=pXe{TdzTyVulkma^=P)~@3eC3PtCAP3mG{p_2(W~P{o;8afb9`OJ`G+wUKojDl zGF&q0{?CM}ZA|iQBDJSvem?t+*9Y~7QW}nc1Kk9$s5(M09#`)Gn$7s%mzAwor+lwN z9A3(7-K5k@#yOC>m)NEs(4}8Idw6y&F*kS~4N|FR4G*1b>`xC_ZyoesO_SCWaSuRc z(?%~Qry1%X$j-=f)rhN;`=L37p#u0BoPb_1MD zwGztp&D2N>aOP40Wq={(@9g|^ojo-&yQN}u38Pp$T*ZCf;GJA0neGazUFG>Zt1xRM zZlwo@u#L3>kGX@mkSGoTC6@Wuod#EUnm=pkSjneo6129@x4u@>JvHWXMdqYcOmm$d zu4M^rIpRp@_HaQLnEK0j@(1C#8uzxO=L)C~o?W*Lv5y?6A+T zyDdO--|K7SKLC?M3ymN|YkW^#2&)5*`79)HNP#;DANswp{vOpmWM%4E#H#8VUqu5XO ziZxvbAko{M%|}J{lGH-pNW#;!+%OWam`6!ZGFsnfTHA+SOhSy9r4ZAPDKR(kM8HlK>B8fWr66tZwoE`&apN8Ht2aqLP(0*O}CygzhT8_E6XZem$*{|G0!(g9It!oCDQp2U z0ZJhIo71~1U>;HA8Q~Z6BG?{9=J42HsDin-A(QYTNHn%FrLOc1)o2G~2sb;ztA(t- z`YsIw1NYZ>_rn5#!A0%$4wDTI2D;#=4*;fAe>GO=AwMRW-Y7= zqL*#^88=7`v0Fy^Iv&|fL_GJ z)xyX`+|j@TivE9Qp#LSCFn%Y&e`J&I<^Ls{80iB5E(K;Z($}c#10D%LG}nCf?U;dS zGawTI5vd7)W+4cDec^*bzY;@#eDTARw85xewDJH8vsBJ}eTBJT?9B{aaX07)puaI? z>=JaWe6hpSoEZ9jbA?4wn>VKM?m=X22q%0fb^wQJ^$bi53k4J)ujvUf0e!}c{OQ*} z0pgc20;n*fH#)w)_|@wKi$iS|FgvC|0dhX#=*+*FX{AB=gkg>J@K>q3yMoAI02X{FWcZF^fyv|%(?JPM~-e_|PO2h(BYd;RsSkLZp40sSFsuKO%gh*hU* zT=T=XB)3v;VO7np+4J)U>igIFu}a)8J{J7nKNs=oR1(ltS1Y5AHOzc3RFu;^7Fo{> zmLJddG;?&c&3Qa;gg#_zoIPBt$AxOn8XGu&sMh?*t1#sF@l`=LU13?_99mfgK61AA zE67aEWr|c!FP+ZrkCbX5wNyu7fFgavgYNt3lTitFvu7-Pv*!b_-%11iVmWimcAf(2 znGqXStmk-K&*zx83_n&hShj-S^XK+L(mo9C^WkRw+2Yw5sf%EZjN4YX?||P2k~9l( z;dXj#*Bf2_{UltthS_mvZuXV6VF&9G&4Gh*tH=7OCU13B%<1PH{K%>>Z~5Yc(L;Rc z$GESd!h7p5`G@YRyjpC%(@T`1M~maby1fjynrVnhYYUDyd7noknO?Wo)A_oeL8yU) zA<*P6dc9w79+RRmfCr{8JuLhgl%AoAdyLA#P|u$iw4Ph~F6*!9yK*%$E_XjGK9*Wc z(D6T#Yd(+Fw7ehC{ETuwH)oh!GMppkn)&e^2Yy;G7Eo%+EL1cP8Rs&pPCfZ`eV#Vk z*tV)0SK$kXu8S@#MPu4*R|kPXcKuKnjqhz4pD3mGRAc{R$!jc-fnIqU)@6C7`(U%U zt5sAR)KF=DXLz#kyQqN(zkIW2>;VAm>2T)AXV%o5h<>dj0qJ{=9Tz@~j}~;3RHZJv z`Fu)>N$jz6)oZ2xnTERI>$UbvL&4?U4>b|#T$~Q5eIQ?`hl2Clf^w#9aIHY!m!1wL ztRn0L>bs5l1xB$E`sJ|WGt}pAlUY}fh({^W4T}yOnc9Waiav;mQoKl}Bs+ndg0u4E z(rU}+RWTQk1JaofE}D4{Wi;G)?mue2HVll4^WiU=cE#R9;|vU^uTI{`|zn zg}C+fE9TmTOMj;Jlr-C1#CQRb$%NnPYZhlD&akJ(>XiEe2CLvF{p|tnh3?`y4OHSM9t#(AFQf zlko%Kp)IBKICSUqt|k6m&rXprn>W#8wNs+nSC5=?osA3U-bvt_f)C7L;k6 z3gG;uAi(Jave8pi_Fd|cmHtHk;pZ~ig?P@O=&z(0QtP~0{NRi?s8d^-YeEnw49p@M>d1>~rAZRnWv^OgNnzgCD0SdRIbGj@7 zCs=FBYWOq)5HO=c;mk++<(L`0nq&sQ_bw?X5@}6g--&qRKif+*m@NsRoy|2CJOV~% z(JaKRLt=~(iODbe3#wrIkn&MZoZuryITH{Y7+}@sw&NAy-ZJ&mN>nYi3#1m4IB_!( z%R%n6^CdL9kQfRX=6k`uTu+0;P@qf!^-N9(DGDp0A<$4fcZ^mO6Os^C4~b zwJH{^hHYi;SyOciksgeS;w|dVT!7ipO809HEf<6+)UXo#ONYE|EoZB&T7_CE#XEDE zZ&B27MC=bHQmS7d9F!;d%cT=E#WC{UZk&)isH-Oo%s}$!yGAeu7G$Gewi-Gc@__hab&PK?%f#?pk3*uMn-|n|AcE87s|YnAgLw#j3D5$z6yw+51q*CsNdRp>wnTT?W3PfYd@ep*eHb}lFWbWeJS+v5`;Tr67>J^Yz!{yFQ zre9ZOK)f8r@vw&P>(8m1YO6L9&G_vBo}%679nVxFz{C$9Pr56ZxX$wIV>Z^#5ZsK) zZ&7%f5qajf)5b3M7X)UMGzyG0*;kx_6$mLZ(Y|wm^m4423Rx)u9k?a%s2zO>%8yZE zF6-u7Ab>2*`~hC~9DXfAiY<*Obs#M;qcD-12T9H@b+|OSDd<9*z^dNFes-pS-(Y9vfjcyzCZF4*;34x&H;mXBLr-uOl+?svOHLCFzD-O?+7C_w!e3Yb zEQhBY1)e{*GP}e?4Dm&B zBwC^wLRe!K1Mp7J`!pX~;oE-;9=&>Xv?mqP!x?qbTCUp9v(|R^nSpWSIr)8p=`33A zGmt}Een4+Zij-*Vo59ITNEgUMOYCU0DayZ|kI&J|WR(TmMoP~N@M~=+`+j*UVlsGt z1+J_m1bfusg-hTDBdHW92ymc^B7 zmvvTt<^pFYmORw6HY(Fq5?6qRwZ1%x1hLUjN#2T4a3ec(4`y^U2ts4>Yp)Aspn$B1 z?EYBGeHXap7cWVH{{`b8BW2W<86k;8O(22Tc>21UknrG#b@QoupeTtIv13`aIEh-2 z-|ZN{Eh^TuefR|j(#75Czj{O!0^KlItRN111&|I0-66x-n~t8&MK1+_qCv@9z$3OP zY^ha+6a`W|vpi9%6sZPY#qV*5-hPod7fibXv{&Gkc+F80iYw7h13xJf^oARd0h)QN z*aeNl{cPG%7*Rt5YlF42$cn~@>Gs}IG>#Hs0JBl{4IcY2urr$~zurtV1Myj^1Tz5c zBlS38#;!|}8umIGr&v4}$x60Z%vi%c)p|4roXKzzK)UwS z7FQd$mBDb4q1PJ%Nu!G_DFLyt&n_(CUcQgK_^zOQ?8i!5@6SnE4*<0JOu!aMRiLCt zO1lxj*LS5Pnl8uz={+x5X^(6j8(Ly1PQgrcOtFJ}W&KI-wO)1Nfcl>WLpu?l_A!c# za?;=p$*wvS!>vmI%CFPGnw*zQ4eU(v=0?VF7J+D*{rvcoqO~Q^PYHp>I8Tp(}UsJ|aKCe;}nK@w` zES4rYM;rVLIK@FIs|P(BcUzfB>q6IddBz@i?26$ZL81A27B$^)qhF=mY+`IM4?x-K zB3D}$S^L?BM^hTYOrl_M0-eT9z9h1q~M`87mzsD1HV1$TgVBH9f`8QI^Z!Ak{eGa>JHVFrb}%ItTKn| zhFyfA%vnTUq!CyZ@{aoy+##WPsDkK)0s>%Bdy~)_?G<0h4AO zTv@2O0T3#!3$Jv|LvPa;p4Ku6lPoq={4BVefB-KAq}#(mh&h+s8`;Gya_=%wp@gzN z!gNKMkz*RLv>3iwYCdU0NsYMNx0X* z(b)9tiH4g?@%{H7)gNMY7BcDj8;QTp>HKuwkhqiau8R#6f>Y8?hZIeLn}X8m-J$q$ zJ3X4Q2vSvhQ$;t>;k@g<`;I2^@G#uLwdL{1gv^PQW;HDhqf|r0stX6WcODt1K42IA z6tsiQ9?E^nZFH=PisT9SJ;vB3|9(*FIM{27^OO`0zqh+L@mHvyX(W@yks0NkY^SC& z=`~cm)7k<+ygwS(w%bmY9}@<~+_mNS)txY`vbX!QMv${k?CdAbLQrBwejKkuHuLU> z_%dkpOlq%K0%1pkeR%EU;;p=GDh4>%x%LsGOAdWHqCVJ9Cq!w!%o(L}>0OY(8y9vo z_xUFi&@8|scqAY0auDxE6aQPtEXN6=ePK&MbNJM1mu&mF7@O|Jq`Tkzvt^=QKk`m~ z|9UUH#%!)PPs7X_!J^}46(?B>$jna&6WuK^k4<1&t>Fych{+_Lnd@W)hi6uDk}1@Q z004=HoG&>CT7UHl%E_~rM~Z@8-6fQC;v4R}-P*IZR$F>1RQY%xtfb9=F$%0tAiM*1 z>?EICshy_5$O8C&nS5fd*L=9ZwXSEZ!{Hkv<4@u+eR6NUg+kH=p?+Yq7%v)Xr?ZKY zyo*LXO}Zyjr^wC@>W!c=*v@Uk&w18`P{iug1gYm)UI?WH(R8lu#=*k28G!aJ!U@^2 z;M)6A?wiDO;m@hicILBQ575uHnt9ruE`4q}D9v4*B@1|g^&kxD4nO4M?CvqnxHDjD zm($ z(kf^=-9hG;B%$uete7j>TZCj&kT39_e;vdz!x~X~&>$U#HbWUe0DCW9*I1-WgcT3e z<89GAvM~qeFzt*P5BGVd-Cf7ffW$S*Ip9kdFHj@1P+nQPKwb<#R52--0-wN1RlTHO zeF()qCF*NpIJuA>(q((WZ&o}|AG0`@8}k6Zwf5NLwC;R(2Ua-+vFFB`QyF3Nf=jc9 zU4@vLVrb;yfYzb2&g~z1o5Y%@$nULQHf&JI(cX|v$^rBN_ZMwuYq5dd6RKWwy{kR2 zx1fsgoGsvi7_t~Dt8QKb3+*5WgA5YUjsA%)+1}bi!S?Ul+#j1*;&vQ-eB`&FEa(UO zvSt~D5~N2$#tl-g@+CCG*hD*I#;#s|tyen(2HVfJ(LE@86)R~%Uar@TG2(^W`;9_w zt&Se(_v^GwNS6b+2&QG_VtYK~4wL#%vUA!OJx>--Q*{OkMiuc@2%vs>E#Muz)TK`_ zb>J3HFt!k!hTy-L>n+y9YV;d=z&)yXgFrYHTVJAa%qgdF8SXZkZ?-wA9#zz^~TVX~oLteVmS@{r)^()XU@ji1T~8 z!Z1MFJ`1Nm*UDr6_NNRWT@IlD1A$K8!M`=RpbZRipAwXX$6&j}SPqY;mh@?oo$*QDCkm<3D z&0&}2l^vfjA7McUwf~I@kQg~xF-fao4AiH!7dDS1bCfxCn?Yzt6Yf5h$R4U68Y8^P zW;YquMdk>aNP0U=W|u|%Psc_- zYOpgwQgkhpG^P)L9)rKhn+$;W)|MGs}U{mizO z5sMK7@h9m=jM)QJ+&S&Kms}%eC6Ccxe)8X%TycR2A43#YhG^Dum_Af&Wiz?BS;`n* z?)JAfUe_mmkg-wdm#2zuXRJGhB5_EG$6S-D&20$i$%xO{mo%Ye?Ia|A-jHJ)<-ZNG zpFkE`9w_p!sV0S*k9@Xdt_TU$kNb_n@zl~p+-DF(#t+l;&sg8V3C6T0Q|8HHr|fL z$tQfTcW>&p8|u@0_JWfMRhPKWjKq|OhEdijpw0`%s;pr@PZ?Jr0Nw zhm-fi6%XXD^A{zII>N;?V)WMT^4^;51ps`&-Q8~M32g+D z-G;zmwW{+f@^wodAW+$N&UXJrSSLb7ElO8NI5TlgBbIH&4Ig!H0;aTzxZ+n@U z!3p@mRkz8BFcLBxkg=KAe~{b8_i4cBoXC>MR9bn zb!^d_WntphbWid=1_Y_nse2`o^jusS*jr{K!DN0>%ZHm?$AKwJZ;5OFG|B(K@%dmt zD4}}_8=gplis&Z+l!y@e6B}CYhPcAoQfpusPH6KJ;zr*t^0M#33Gj6$!_^?HTp@3g z1NpA_vO9`VT9%ly6NND_&u*oELkoS)qDhoju)U5b2Hl1ozPpH%hv<-aDx5M9`7Ui+ z8u{=xJwH6#`ce_W0UTT&NemxqRuTs{Q~J}i`u$3F|4LHOz=Z14j-$(pcY8Kp#mAVH%cn8kzPmRRZ@7_+B^TMMnxhr-_^2Pn+k+9K<6FS4TEzD>4D&7(y+?_>n^|ByY^Ge&*r=B(}#r9}J!mgk|l}F18^}i!1&amNy1a9u`2PGBV4HRYCZdJ%K zQC$o=^JoX=Nwy|fb-DF*30sQsWEZ#Z?DCEboJ`mXmpSzpJpcwvj8{-#NV>WL1OvMa z=-7Ds9?9h8Hc!pAd(a}2OD(?a7pm9UjZ|$OOYP61PK)p8vk`$b>U1H`X~!;jJL54b zIa7urSwMS2=90#UuP>D;4v`IP&kk|d!YksaxA6=`+$T}J3AuCBOn7z*b%dmv)sS)PVl-ja-5Z0X1ycw@9o%FEdJ*D>n_?P)AmTS zV^l0$7*%WBC(Ge|zj+q)qz9kOYG&=BpbcscPM_>$*q=|ueVwmoK?4Kx-nUz;C+F@U zquTN<-$pN%+@MNQH0Ub291tv&zyx%ToPY+T?$sO1|U#JE{cg+okWjq3;I2d6)l3 zL8yP>NLc@(HvU6fiv6E(lm9XW{8vEapY^W(w?RY>X6FAc6=j!&!y462{%TQ1tOsy`*#17WIaaLS+%yf2|T7da98ZLL8Xyu z{QX&mf62SUzjaLdPpPPVmrv18p6>y=38r738R+j{6V!qGKhcl&&on;6Cc4zoT^0}1 z)HLjTFYa0@mRz=v(0y9R=<^QY>FK3;JYQ@+w_hr&@p2DU6Mklfsd}X@%l3G3(}y;` zSH0gd2K?~I0CaXarup@r^>k5b(RR2^4?DIlSwS72NKJ`>p_mY&;(fcXq1*Cu28I7} zcDnp-u>P4D7hdoDOO!z5dmvHn6O`ZcF6SlPZvh*YBjIcJj{nGyYeJy+PR;CvOizcO z5a~9B@OW_w`t#g_YA!n7*Brv*p+4*so14HiC&i7K`pQ~tgVgxwuFa;yWxYk!cXlD6 zjsN47rjsJf`{97*7eT$=x;#we7u}8IFX3-fu1gH=uaC=eUM)!P<2VZ?W~*|Ye7IN% z`>m6Md9|NCelI^K87Rm>^gn$Z@6P@h(WPSau9g2mzDq)!Wyc`JW0nQzeX`RHyhU5H z*(KcN)5EmC`x)SC@zyXd&Tmqc*V8(+On<|Ee~%BA7GSb~su{#j-?opfMCL3yE+PUt z{ymDAfAsd7eS34|s0;_T)z68C-e*v#wo2P>%1qb&ol47?MYqm zb?~^uuuU0r1ho0m7K?0HMYstqoLA}>7)968=56D7fpH{pm3nHx(GGG-7H_QS+CjaZ zyv`qF$@2BJm3T(e*CjX|KnTxE_oAJv@hd1Ai>&7j)aPA4HEabmg8T-}QuQ^Gn}G5) z0NAmSH1(+R5nUkX+EsVPYngAch=UQrO25q~OPWn6!nufQY0i5rwHjn%+e!%@FkO+! z{X4^v+aUL}f0IV*Hd^fEUYe)S0%1H@zmQuaww0R&DR|L^K?RoY#R7XkXfOOx#{oif zv6^YO?Sz#rVY_0-u&4A_9N7n?)?RSp*a5pM#2RlqwjcbCfCHnkQrb$!%>0W0AAm%I4`)-kKXd*n{-sVGfoU<7YSF6GY*V~UeS+OaT95Lruu4SjvOiYG9 z8Gy|7W{-j)OyltUUrIrZcvS8sCN}Co8HlC;xI`9BWufDT!YxdXG7F;#jT|tj4CF?y zlWuU7DZwNihT{R{LY&KoouQ&k0br$?iN+`KsLes?f{m$)_o4}bv!OU8Ot&?c8h^|75vZXP^ zl!QSiXrf{k%!^dN7PUvqi7r9`GMWWtLW^e94|mKJNvPk+%AXlir-(K|htOac_74>b za|90=&!%h>AiL)BAV+|vM`(Z{1%qLL(jUYLnu+j0VnB(U!HA+yZp@D+6wU_X6fBYQ zM4JBQ?GTBKAVUk$k{OM|l?lqiRSe{T)(nF1n@s0QL)c5|5r8cw%nf@1iU8!|Pl|aV z%@NPkgNM~a3z|SpU@-SkMj@$G*OKhP3X)n7Feez2TmBJWwAj%cX$Edxs*`FLP8o(6 z&5*zbQx=9}xcrq_urR4bKN^5m2s3I9;~#Z^vpdUGETD%WiB#95jA;fG)&iMASwyI& zb3~xRN&!b2D$c&Al=%~*?WwPEWnwV&QoJJHj1Z_;P!B^e#7F-XC%)zTq7csJE=Tz; z{Eox)R~&)0$iL!nWp{>u7mq_yxv)Sa8s@G2Nqub61ertozJ3+flKcyd|JzBW@F&@S z7mohZnNofqT9Uu($`1I5FMIdu{jlFWIknI(KvkIDMau3WULiR&|QZJ$y zn5i-tG=H=x0}ND942JeZK!A@^mrUFz!a88koXT>5I?|TL$Wllc6R*)hY5JrtexG;UP+hmcsm~1}cOq z(o>K&NY)?%*)R~I)!pYgvCmwW`# zTJIUNw798BY2xH231484w3}8panb8LRmG%%dwi6hRy0KJeQaoil3Xwu_IMU+RGr#Xs6I{sj4(I9o2?9&J&f6KlBfj z)1WFp9M?#kkoXV|LTzM^I)%-ttyH8qf#+R^EgYG3HNAn2)|t%oQIa$<*74gFYi$~@ z41{=~gKo*C%sj8sYzmGSa1+_=SOO(!qoeHtxP!epmn~$}F{oCZ*L*D0-aPz9(X)@? zO{#uhI_6!$A2un~;gwt0jE()U^fJ!bC`_*OunZzP46p*W14*6Wt!3z_pV@LzR1RJX z$$`WqHY}siR6wn-?RRnlk*3oYA+owiE*M%_JI8-!cL$Tgx9FL~W~Pz;ww=^$rN&E5 zEYNF7v^-XMG_&IlzyjKWeRhIs5AVR;xvhHaH``0uoT6M8(gM}7LX|R$GIXSE;rEjZ z2rbzEh}x{muWb=l410yhA8dJ6mRj3LW(s$9)}SrYVklDRpE|TzH%)F{{B;`bNoIK( zvBGsw+`r;!4OpiIq3W73-Vxv-;u)rqeCHe}C1))Kk?`Or{zfsxqf6YiT8uydU$1f> zGN*fiD1OgXm3JVlt}*n9YQ5J{goWKnxxE~Q;pShD4tiE#{`F@A5(mhCKBCUw`DkI^ zDzg%UQsnSxD=}ec3vnvAqtxU>V8o#KxW`MSbp}L*)DAPQ62}7TU1TuM_vR2vIBit` zNrj@N-tvwY-ng2f2RE#AAk@+v3S%=?3^Ni)pZ%*|#>phXZc-sQ`qj{yc_Dof#YT{~ zjM;Q<51ZM-N&1(ek`dX*%W(AM?)S@)X_`H3)#sOw3^bZ$V+uqiQD3 z68Fe>_IE508I=-e*+o`ObY>mlp$5uus_oy_t#w;ed`gOJ7H5|fb?U#?xL95X-o$Fq zIG$6xZ+Jxe*w`?`vv9fO#d)9angXRGG$(D=F&ruue$G^c3v;J$;ViH^Nvl^VQ=6*I zDfJ2h>S8Bn@i&6Zq!o7kApCyXr^t;1>p}VPAb{U*3HpV*1U?WDKMN{ywgkr;cmo_W z`=eTJDE>Tfe8(PPgyy-JnIeP~TQ4P@D10PK-pZC6U8i`;E@CCrf%mj-oY}Ts(d9D& ztWS>siIgEr1Bhi7apn+lz9_r34$+J+NpxQ}&QJDUfKMdAT$I5vI6n&M4VMwk^}PyR z-nRf*jibE9iXG>{%qD@out6+>7qqz~?Y5V2m97OoqH=$GJWj0^ z(>|H|u8V)>W&ut1r%iB)DZ3lDRBO zDAYJ+_nu%w$P+p%ji>=-f!DUXFWjiwEhd@0^27rgL;A+fVn#Fvix2$z=16Es5x!jx z1Q)BU(=GTW7+Pl1VKxGQ%`l-t;t7PLMsAW;dFd_(FH>KcjSZe1oU43eFnAW<&K;@O zp^;NRna+@OkNq8k?N_Sa%Z`)($i){lf~z}GprcS1X(4O`cLmRfrOad{EYD=HTrLlp zZxFwM51}!0EXjr6&;PV&D7yR8L*|B}XT5#;xa``!_$uM&$?(QM8}Tr2p`^?s=Hu=X zwD>8oJ@-tI$zlpz#g1?DbfmbfoWEYtDp$-cDYO*9bv1sTA9n3P!kf!S+zCbJzuHkX zAkl|LKbk+u@auqj5P6dMHA?f^*kyH^Ebb90tK7DiPOn_;3MYb-^j6sB{IG44$A48n zrq`HRa$kXw1ABy^$u>)!*&kRgP#$8yV^?UAOfb6IA@N81OY|U59$B7)!Y0ROxCst5 z#(X#e2WDLH)rO~S=biQhPzv2F6;+Zn?>_%cEsQOnLkNfdR}Ybzp4p@Ah|q%ZY+b$b zVZ^1O!MOXPS3?K1Q zL_7f-Djf-hQOviOIU``T?PXc_ykQxmsw#Co6yb$;SQYr1A8t$sHsBy`~>U z<}CY6h>LvMU;Wc{>ZI7!g2QSqu$>lQ4m`7E%}?qB5TUQmOES&sdABP3l9h5kni0LX zs(jqfWoOhu&aS9lh!O~FB39M{CP=iF!&1^wE-(y=3C87(o2D1QF!(Ov)RB#XZ3;~v zT(PRy-u;L-v{rs=XJlKc(KJ{2l*>A>TC@{oTBre>2_hN+SbXhEh{@Rvl*aByrM!33`;$nfi*DH z!jVA*i!Wp9kaw`#7HT40h?t1kLh41cUsinuu1f14wCDoO!-)}Dw$qar!Ch1r8|*|T z)VJ@h`*gWiv-2AOM|jN`bJ(RPJwGWYr#T`5e}FRPDy`T5bZ{AVp3PIrmIA>vg{kz7zW(Uii#DUT$6C)-6jHH=Vli_8N5VeN9q`d*$q8%`H{ z$Xpgx;k_22v106|4Q+Pue`tHhFiEy{TeNK3W|wW-wr#V^w(aV2mu=g&ZM&*Vx7N4U zUT1#?_uTtq|H>yaW{h~}%#jgKM!sVV*#~`CMTIFE2UUsUI5o9jN}^>DeXII0`54DC zn4$A%@$VFdMRlLHWk1Q`F?dYNev+=NmkPZ0Te%Tgu@} ziK4HC24JNM-mKj=-xqD=V}!}sSx3MeNMdP=8f;*vf_ng1yeNyBdP$aXZM#IW`9s6Z zX%}|-M71hNXedHOX`spL8X=#>_ns2kdRSH0JNz*ZKILg3w`9Uhg7*O1Vi8&nT1eL9 zpFrwRJT-QGgsd%?2nDeClNHNsoJostW1A@PK{!OsTYr(r>!9(Bf)*0vtu-OSH^L4! z@@(#fD?;Nm0+YY2&CDSd)9^ymAk^ERAkr^^Gj&!(;epuh1-6>VKmw3iDBWQu`|k^+ zs7U>WakLc}kqQ0{OAHrq3u4SZ(vQfFN8ltH$EBM$2oX=UK2`g$CPjCOExX`$;5BRG z+=8EIduqI;6nqmlN^#Dg2p4Z2M}}iog%d11)) zOpr9WF(<}tdN2p1+?9bvflF9k+C;eE-+-HDT~psQ+Zm}U!(@ZOfY~O^A2P~~7o14Q z6bspG15nHmIVuTt!$@04(Cjo@OCBA`+(_PXasZ(WR1~<|B<_v2Y<@?&cDjeEB?CP%D-n?6wL6@P-j=_43b z0t9xcVV#3xA?UmpU%C_dI8#dBv{LvKE~tEoM)*h3Who^1H&n6eFA>RXTZ_WRB)OF+ zlQ4EcJ2>n8@#4~5<{tjt7F1fKs}qFhDCj*47*$H@=32KyZc7{`p$4E(Eqp##UKUqe zXB`Gy10kG7(t7buwr_o7Chs^GoG^EABZf=QE(a~Jlz|mGwauSg zdzXg&QIDp_cPZv+n?Ft_!}Nbju}n1VU8rv{zkk^gBH^rIukY=1%&%zl`2?Hm3G@s>PSmZ;d z9?Rhy=Ku6_6)R%esviMsUZ%ImM=afEQgr@VTe}$gHdW6qN2Uq-WSU{VK_&v8>Pw7l z<0;2Dd%gMP=+f&|Ho&0< z(CO1S;_3~1loEJ}FlX}3=^`(*uJoMvB@K=oD6j*Z=QZt1IMY`-`mU4Eg15N)BX<>W z{w@6_zrhFc&yYqD#|A~)UU??kE^h*|*tKlFM4Z&IMDg=(L7jW`Pj&tFlMr^h_l+mj z=xvKYnd9DK;@q&Qd*~KNZGbvV%OtFq5X)}Zrv6bvFPym>hn$XPwslV-ln^1t?&xQ- zPV)4)&v)C`!?E>u+?{3%FGUJ*tglhK#EAi#7aIh~ZXc*?AZ<3Dt>Kf*bRL;y2=dMC zvwiOLDz**h-3_eZ9|^@*M(@Wsu^iiy?@hLle}aA1i8k;yYur7}L>BB4rxK&CUOi)1 zUE1$=HtE#d%zxnf$^J2*E`D0;~!N6Xc~#prl!0?IuK z9fkMpJZ&u?lhJ*dxW+!38u&?zXNwe{*5-ib=e@F~hZ<*(43j*}YnumyB@Bm7@*i=F z5nmP5DtGTz@njQO@pm_DvE&3B4)OBG62I@7!YcGCOSrGrvby)62MBGWW=;{F3cQ(H zZ{q@SHd>lm+b4(h=$WFCyrXxtEYVW-_?ygAw=@$2d?#1DyxqEdtg1Ixou2UYQhcAO za-Vk(iF92bPjq@bA7`UxcHO|g-L~4A_^sJ8ABnSKK5lXE2e_Wk!M|KnBzRs~_ebdp zQ~s1HoaUC+K}D57KbA@;9%`9$Z~Cmy@AI6CXN^-lX>G;^4<+u!jzYptV0Ud{Jz*Zc z^K2nqVoqC!-VPXVSaS1ZQGoVsA_dHMdJ9?))J4$BV=fG4NBGNwmj7w*cgHKjfGD!U z5tgX4?Kc!#aCQT;aWf=+TXF+d`hKhOchBCf^A} zC`W=R?clxFJ`3`!lYccSZlR4q%xbQS7!$nU*l&vQFwOG4@OOglI{Kbq+ zG}!otuFLM!!XS)^8I-c;m9);lRSNuDRKJINEwCO@}| zOKO~Qh7}d?vMo7oajqF}#%agpx0)Rw^UBcp*DdQ1$EPis96o&AZCw%}m?0pLML$NF zU)S{>>2@tdKM!N}>pb8vpBX1~4=v%=SDi+h?Kfop$YK3;$qcKXqQGn5OLZDytRd<5 z;=D4QhL{&&KyHS?xopvr(lBVN2Qy2O>X=%)OndJB(Kj6a!y6|cRp*70OPX#{!S_#e zlwuRb(Aw>mXLa2W8_BSJw#>1GYvB){Yd8F>m)04IqB8OQ5~+}@^y8o1bHSJ5xP@b+ z6c!Hao}+3lXqz|flb!1~Ts0=xK5HBJits1dF^-vUDBfy#6o3w@Era9A@vuXi62s$A z)BD^-s$2F2pfY&~3JGS(S?aTebgDDX4;JC59UDV94q8EP;#`(yx8EFsp`|^#bzHqy zod(4;Di5_+kOyvJo+wqF?*6ox9yhAd&NOV_{-a9Q@eJDxiF>ISAmL1|^&GO!xxl8d zKsvkhN;}8E&AjfJFxWEq2C+t}&CX%9r@9qTuR2SM_Ph*BG12FLW0YlOW%hl8TEVvM zi8Cll6V3;`@AqS(ggUOE5$Imf&0!wYO>dV%JLi02!H{{f_?i*X~P@`5p zlNJ3OK2IXsQTriIPfIE@V=Z}qhuG2VPdAHuNchaf%^G{(aIb7eO}c#lM}zKQyMt}i z##?E1B^>U(fw2S&|J-8R*)IW9GocW=F{z&b6#jiADM|rp=IO&G!Iq> ze8~0{BIts{h{ZHCPq9OeWYgArLM51pPeb&V3{89y;Uv;5OY56xu^b+3_o$5J=s?k$ zW4maemZL)M>aok}edpHj3c=(aw@sX43b2|ZBaLu%mfRNp3snbsg}@;$ZiP$}i7g)^ zGRy432GN5QFi)hoo3q_*zdT3A6A^85Wqr0?qt9-qWnHBZPjV;g<@?s=+f$uHVwI=$ z7VtfLhmFkWk=k^`6OM-_?%Tsx^Y#9`n;Q#DcT;0@bdj$%PrC=?<;tVtAlh}B0HM2* zo3X3a2CcFca;Kb8Pt0(WvHRw_$GkHO7C(P98w{5uRtHm7#B<}}7;f+~>#sVx5D;3- zz>Xh|#e>7a%fR>EZ@jb?$QM7EHU(RPRQ>Y_GZ0O#Bn*HD2ghYdwR<3L>v%iBBh_kk z%10Hyy6Sd0NJ=?v_%NCzIg8&E;OBk|Fmk5%Ko zfQ^Ksm!?Nzwv?QDy@d>hL`+qUf=^4%-3p?|LOJ|C{CdduCm7r!*@ zGM?s-UE0gpK1wccI1;JuB93yQF)o(xxFn)HfaS^`(4fu9@@K z0B82~=Y_MHS#f)BmIxmFN6V($Wv$Pw+n}@W>*W2Jh*JgIHea>gNW=E|cc9qE=1vKB zD0N|XC61BY;r8jYwysUZC&sX|A|qGWrZi5LxIORq0X#n6=V?D5d58cz1K{h|^|sIZ zeo`bXSk2_#o3~F=$%$4JQuQH`a?kf3fJ5Lyt#hN0=SMQN>96B8{02Hy-k-`gKJSTW z+rB;9ar50rO^%xj&XIGgxpa!db|Psr$q$mhJwMuMX#dyzO4CeuH z4C^@IFz}c+ojzUCk97Pj*C+msckZ1^21mSU2miL|Kv(Glp2NHc#L2xJ0WNLqw!&7C zcHGvhEk$|GvY%FBz4q%l>h|K92W%*(og2?4jz>%6T7&9G_)`7ieGWP7RnJI&6<3qK zNG1k|Slwk$37#{#!4ZO`1#m@jTOS^T!db;0y$!3Za*(OHk?JhAiVFazTU=DBHQ4bocsm%HeP(4}L z*5AL0n=mm6ded$lj~WEZLmiS_Ol|UHPp)cEt%&m#z17|(a>|%z>59s-s$c16H8mtg z^QWj?HDc`IUE>b#3yqWKld$h2PHHQXMl+Ouv}& z58ynBDSYsSYM=W2 zY1z4%u+5Fbjabb|0hiGC@LZ$B<2F{CVX9Jv`DAqISH=)~wLBK>17Uf;*@p1?5&r0T zm)c~5^^#ogxuX(0pO~e@MqTuD%LS$~6o)juZ0gayRuoXP11O+pc{~!Ma&H0O8A}G$ z=o?eZ{1Wd5VEh=h1iT+90LfSE_fs9dOp~{cP@{!AaNod-y~$P@O^XpKF*m>gf)Zo* z?2WeIXN`fM-fdyXK__Ya{f95yb)i)(E>R5d>=rs>o^ToH>~7_Hb%rN>Xx1}+KuYZN z<=Q%cdJzptk-L{At~Efwbkn{xpMUykxc0^f{_%3ov z1X}4IhV;UiFQ9++#{kb1XWBJqN`y(*nRDp?N_c@26Y1#W@{D8 zz-ov%?yd=xqJYhEL4a-0rL7J(#J={*hop<}2}0D_v)w99N zuafD=7q&qo%!1yWq5%7NbT>zWih+Xi1UFj%dfwTF{z%u^O4~%x?mx#DV0FZkN1UM* z>cQWmDVyZ_O+L2O_15(%^XGCH1*~9c{rQ@V%y_SS(|6uVZSxm}JC0U(wCF%;UWGu~ z(nWmG+SRbp_VRv<6oc%hi@ik{kGdjZ*2T_|m^yy-qAloz3q@^8hwxj!XYEB;S|b#V z3r7gVhXv%8Q(1*7j*Km3O5yEc%gw~X<0cv)Ti?8cUzL=8s+SdNq2`edkOIBlh!gB6 zXzS*$f|l-*a`^(q*@{}EN!SaVd^7d*FVw`K@M6#))hb8$K?KP`YlKsHBP=C6$moe5 zliKq_;P4v&1xX!_XyMu=409J`@FWE(!WcmO_@7y!8U>&>Y0q?o(3z;%J_yC1G>;J7 zfV0Hc>X!jTO9Qo9;{sl}7j`LH= zGZ8=l6)yJ`;&r?y>>X$c58(8cSHX6f5pxj_Z@~QTy=LpZ;-kWazw1FVu9UIs!aBgy z+HGEnyfJ=thI$jk{>E$&BiQzCu= z#FQ4n%t+J4>H^72>q6M%@N-}iv6WClCbQ#2+2&i1rmh3PP0u0*l;dOpmB4fnkDZkD zT=om=0<1Uf##5tjG!K|10Vrw_ITa{z`wRxg!BVsE)W0zb%K$*1cnKCKgqdd9(#Ib& zRh<-5O86*lN*LD|U_bz%Vuy*!9bQ1z*es9{K)+ZlZj(Fz1_>-vx<<7T2B^$5dyo#Y zv1Z@$KDbGjRg={)X+`b?p|vSOgNENg-qmF83*Xc`hrN1;%wg?FAs;Zl?pc2Sf#7DO z!!YB-S3)K#d4-%G?{{}lr39J0plj6}h*61#T`JED4ZY@^e?-tOr`_BKlMW6d^98Ul zXi5X>=rahEKP)FJdl-vH@PmeA_HW(b8+GnFbM-%^K7f%?OV8DyQi6AS9kP6c1$DMm z>G&Fy%Y1n+8a6jyBL%=Y?}-epH8KtJ{Jk3&viPcRY^XR?e-6F^7& z(BWaTh*qtG;4UhaZs&N-&4Hu)&VMUZX<^ z9}AEhjJiH0rPxAO zen31vgQf^R`~lE#Xt$QpM95j0;~6AwgszDn8a1+`lLSTu zs8gsiZXAUZzX&}syCfu0Oh}{Q`yscYAPbtzQz0r! zTlqp`rZBfvj6mCKSXT5vVR|&-2T5Q;Urtm^Yd0W?A}P8~c6fKd33-92iCf!#mgmSC z_}%e_CsH$PjAOv&)fcxazA{~+B1O_ac-pL~08%*tI;sgznhs_WxkqMEaI|7HFH8{# zIt(O-(3`h7fo(B^WD!YZ-k1-eneJpb^H-gKHXri2r~(m-I`yU|}E$wZWWO_c8=U;RK;cQaLJN*Mu~ z;u$u_ua8uL=A7Y7mqrFa(CH8Uy!!Ra!jd!j#w`qvH8poC9l0d|D3}K?q@iFl%XAY? z@0=e%FA~@Klidt%zyO7_v89zC+?$_jYxm>twv7uNO&%im>CDhZ^e{Ws(paU(5N0R~ z*jO|rnje&Yz%OX(2zMGQL1e0v=wU0!`l7l_b7nnh;M%SAf;$XSHzY{o)r^mjZ<{ZFAs^0On);-n*ZTx?m?kfJ#zy(3y0B1$%u;QKbr z!o=NyyQwq=vm@7{72eJ2R|FBgXx$*58?)*X%y+72(H$wEZY7oA9VW~bOn0cR?A=}` zw3t6RgXTp)J+fx;5o#gYRZaAvXz0^B_=uY=(E>-~-__?t^xEBEf4M7_QP!AzuP7j`1G%|?7Y5LHc{#cgkZtU>_%-UanUXzn z7_yY3s^zddYPvE8)6GWARsHcG4)9?a*4K#vS|zc*RAQ)KC&pcPh!M)kO2=gdbL$y^ zz91pSoA8X&Xqpo)ew~8t67jjA;jMdW=qU*vgMa>{z@yz;{)D(^3sGikeVtI+G;`Dj zDK1fQ@nh=Y+~KfAVsBH&ln+BH0mN+;&vPXt;k%7mFE}zhr8aq-r-)V|Sfp>HT;1+QVADr8nkor?7mm%Itz)YFEbx>!*s={J=8M7B7f||<1E^+4ipXZJF(Frzvkzv) zlSBav$o3$n4{RM6{TluWQ9sucgZ%x*MNR4iv;(jdkZny}T5b)a7^F4N4b{B8ickKR zg*`Bu&AjSO6t@0#je>Z7{|R_%e!p7&8xr^t{`Sc2nvi5+{6kZE8{fRTilCS8L2;@+XQ?IAM42b`Sh5)>P{GY}lM?n_kwT zA7I}oyHhOAXENE9H2jL&1}*0fll?(8<4waaMyAh4Q&JCT|Ha`2w3lZ64PFU*|33$GF&-k!tGpDnDo(NPZq-m1;+2%uIfMLxd#2DE@zWwqRE|}a%JM=IvneR`6OZd#=O;0frdlS>r#gbos6X$*?p=fhd%Um zE2Q|Cc_eaac#g@|QK%E4b(K!@4}TN~zK#7)ipH&nEi5USlRWB{kG#rB;JllPNpGU_rJxtfKg)nsB>P`YgH!H_K5iB$zeFGXmc@{a|f@I!mh zq@NpaoY&MwGMm`lLU`y{eWw(+;Y1trAWU>RrbHDtWa2N$@hUWtTvGY6bLi8GMNF#^ zAzN*z(u@4xB;XO}n0L_Oc4)Gt8*V65qZ7z6oZrI`BTQEoEublllb^VwYW0CH=|Yc~dVHe7 zS7=hS)#^|zOrq@KcMIo=`-4pLQ z(Sjo&eQx5TkVi@A(9M4Rm=V{_e0aytWPN41 zTT$^rKynRoA=$(0AH3s7AhN$^o!9F-0T%4O^}7r+{bA?gqNJ2H!OPkqJvD(FCq67; zel0b5cSH>4og5o~zwPMbM%k%#QE@Dsi9$OXZ|FLPNFHWdlqSWSzAO`vi#mRk&AbA3 zB8aep_2v&+R+VLXD3$&c^4!Bb9#bgR7AFCZj2=LG59p~zA%5i)4QX0$p2ltp)Mb|_ zGMD^moN-|yi=}ZI#b|0;1V8p5Sxc^Wq^wcD!1yVcZFV!5Am|ri4&eXE99_7e8sjP< zxVoR8oIcDAQJ$FHJv1i#9K`~4v%FP>5rK(3N@axDnX^c+AC3Rhkf)s^@`_uyXqODR z0urv%IBmA~hcS*;p0v6X&VU=5fD=;b9xG0hA!w1)93uEAWB$!lGUwW^I5r$pb-hkk zagdCAP0r&{H=zOhWDu#|6tqK3^ykK`atHiKxV~E`tnFyIab+o6B?a`9`Hr16K|qxA z3utM(^PnUU<`S=2fLDn)hF*gtdxhm@+@{+-dz@=;ZK@2U8exSu+?Hh=5b<0^w2FRr z)X?nGsEHd?9Lwfrsl;1lk|So$V849 zeiF8kdAuIOl|c@fIR`l#Fg7~%_^1ffxs0hHlqazO@~tpHpG6+R*4wHBZ{Y*RVU}uR z_wEI}Me(eYLzdLS92^4fuX(3No+No(eYkmw)nkMwv{s1L8-iMBzpq_?km(@ILTyZU zF3@@=?K)6rI_Ry~qy-6Z1;yIg#}zb-h{=zo+Z$suYSj(Kdau*cv*)%}W?K#ah+ShD z{FEH~VY#)Rr&4mNds1@dQdWaBRH{eNGD{v53Rr&)uHDI)lQ9^VjGdq0LBj01bDoiT z=(;l|?YavpZctsR?PJt4n;R1HSG0HNhjPQ}^1|@R2qtfh6MDj>5n=w}Z9Aw-SwX|n zrL18Yh2`IX?}^k>hq^|TLBPgti+b{thWhx;bl%)n(vnvK8em=o+QFw+qt?kPMkjT0 z5l*zu#*woD3fF?u-99G;9v*wb$z zgiu_QV3B}BQa*!BS$_c+Fe+07M}%cxZb5l+?6{{n9IK^JW`~$oto~+IA9W5jD|eg?k(3|!^W}5wx`xfZ}?OWUxD8%``7p#DRcmqy})F z5GuT8S3B~E+UB06t5sC#3(|A(NSP}yyLUq-B#+XaI?h)s>%BL4ywX{6RE2LHIi{K= zTKhE4Lj^Ye%xGMhqv_0*jic^SrTyS6TIztu(en@~NaB4Fp7HZ6(htg(i!hdBHSKz- zO*-K?Ma_x)I%mTAYqpr%BFF5SG&2(8THDYKe+w0k=`3zZgs>LJDS9SHWZ}`-qLnoP zYknS`06seL97^(Vq**AAxP&v%0x3QH`Qf9@oz(fkRewkB2zc@*5`x8_+L{oaN4+mU zLhTbyC-Iu~cJKCrJCsLRf80*H1gD zcI^RN1qQNW=3K=%a$}uV2CS$ZIzqlb!5%AWBUiu5&;;p#eij0ejZ9FDXmag8xKm0a zyg1Y7`s)s3XdJrrNW)g&UptWwQ;K^3pGGiK(`XP76J@S zw_%6^;fjVLV)1k3w?*!eushS0^0B;_)53Bh(pcM|wDCzB`)wqAAh-cu#<^e8^@Dn( zCEYcTF;`l&ApWIM*udtV6Ml)bt`a1tAf}ZLzJ3n679vT9CNW^8tXagqUi!9)Wt5j4 zLRL*-TYFbiLfE!BE;DLIVUEOrqGT5VKW6}|Cb*^BV@p@i)Fk0r=C0zyLoL9ONucLf zaQb4n@RLW0%{EI=hVf-g?`bhK2e?;rRDbofCKhlxXp43qh*-zxtAr4dg%rkRBN){W zhzbRCv8+gqgyz^HPt2jgI66HOG+S`n5*Ns92*QUA-kt)2`|>*A)cb43yt-j4SnzwV z!y4dFTdoC?E=eLm*u3L{*C2~CEIEz^Ac*_?+IqigT@mQ0&t4b0f^+OA1Q1qRJ8ZU+ zTMgk)9l#DIpgx8jMVzx%d5NJBQ}`TNs<9toWHpCmjdzqrybv%o5v}>DO^Uh1g{)>B z>$3Tv*UnYcj|r6J!;$oaY~C>9z{lIdh-MGN+J>Z=;Jeb@8+s%Nop0EM!(=MGOjd>hOpBYzi2>Z`t=a z?lKHDA(KeLC|gJti4m@PK%8g|%6nwwj!l5-k1Gfhi6ze!I8>ihS%}pGQ2NGrR_Oy;3?T;c(sN_9M1iHjACASaf(y@}2 zPX@!z00$t_;M+%e^U>n5Y>nyX5#+6*X&ZBa}I1~S3I{Nk|dUBN{uBz zEn|zl=?h|CL*ds0)2l}HQkbD&89)PjQx|cmcZ3kTtE3f)_L%r_EILBp!*0?PNLQP# zwD)DPhn6J}CdR0|GcvPsm%(*FP|d6fyA>*ATH{+>34FINWCW~H>>Zk2!W;|dI7;QF z2UV^&Nyvz%T`X~bK5tLkS6|6{C(MjVHr=59LN2?*18q?P6AO)w}O+$w1kmmF@k8Cq_yLwdvY$&K*k@ZT5 z5B!s4Sjyc6Avlr58WS&B(JE!&AU1?xh#6^vfF;z7JwzekQm>>3C1nDu_EZ?#--h0H zs3g%ExGY}lR8mG;(}SOFhv%K>c!4=c?j%9IuZ`Bbgqj(YNC;-wVOaOp;Y#-o7h0*6oryyw4V~?bYG4aTGrD6{h^| zWJxAEaO>=2sw2EwYdrUL_b}QGvE|&!4n4S@>$TAMUOyf0Ys64i@a-$hEn>%-*af+K z*)@0v)tc^?Q@vgruHt@6a;@(Dp-c(6(U~_==Nkknr_0`pZL!Qi(`zjb=Nj`4%`je5 zlIl{m{CG8_G#78?#oue>#hn5N%z^Dv|DmQ^B%>q$FYy zStQ!8vit`}l_q5L-|tnDPZJB@RWfRLnWjQBCga>Zi^a0 zj&@LO{~GKz(L{E587y1s`i~VD&l$*P9<>WU)dubTF29ztNi`?`0#Gtg zkbAHRN{@@!;WhEfQ3BniWNKFFHikc^tB%F6@@{)Qov3aRLtF)tXN5L0{$Sy?bNLcm zW&j{QABI@7=IpJ)G4*u&`*z8>xqQ{NA%VYv%<%4ci@(Gl@(!BYN{^CNgMr0Q-}7l0 z&;Gobv?XHIg17iJ+h@BwX0Pv$Ao4O_L3hXOQ-urRj$!q{N5B8$-UAvqK>uNYW&@xH|f(68~vh$9$ha@ zHuHmMLZl(33m@NrmX?U~>1CqD26-SIMp&iAkyBrX%Ap6^xx8_YRe*}=SELZ;T3a%} z=nq)LKYOC@9i9xzT>7cdyh2uSSTdtB#4mMe#ClZWBg=H5$=hdrnwKa>KicrWE2@= z*?YPLK}`fm0%(IvHXt+va(@2Wu;pG5jEiMtfPBNM+f7{M+HC_>y?rGdf2H;=;(5cW zE(Rl(XJu3I+HNxggjJHpsBXJurgu*!=HC(pCJ)mKpGVo9&?~4 z#l~L})NA&Txr)@3lw{cu-N(x?L^B7`3kSV;S7Z!1eF-c7Trzn4cfb8p&tzTH9|>xrxx_wP2v;7SXYZ zpe4aPpvfvBpw1J6C17dGlVprlB`KgEdLegvTJZGCqJUIM`@-ifnBC)BOM+q#*PRAM zn^l}fnFn6dP=UhtDadZPCruKRY972yc{S?KQbRprLfZd=(aAFp=omL#<1+M^f@U#0 za7(H7Wsw?wTmZ`TEWq#9RB}2H4!zMOa_?x=!iJjH!nz>H5@LJnVG0+Ov;3`u8HJ$2 zFUrjyxj{@j)W7m zHvcnXD($ARY`Fql!G96}uzpOeB#&|+Uv$8!(|l!DHP&;w$lZM#jsj4w04QGR^821A z7%&|qA|Mhen_wNV7lJCTrao`w4-n|AIR%(aR0RBJCQ_3wG? z5!V;021Dmny4+KOA#ln8iz}bT(_fO&lxb-h!usg+WFc;4P>Yf%hfeAHnfp#Mu5}5P;%0eu|MA8R5(_DZx~Y1+lmQL3Shg#hCm#c%cw$y-90} zLEz}?N(z_lie}q-ZV+fc^pntYfI%_RG!gKik8|%J;mVt`2k!TIv(tdtnLr~ff`mV` zly%*zS8IdiWV$I7j(8@tw-duicIio(h1w6VPJdX*3-|Wss1@+CZ2T{ZQgI)>F z=_H0XuVxap(nt(xOPhG9U@gP_VAAEzHlbus0^uoc$UFKeWKF6PLWtk&?% z(yEC%pvAAgw7vxpl4UiP%^w$UE-eE0<5Dq9^Lrc<+vC!S*@I6+H-yv0ju!-r zo|B<&5NU5@4fTMG>QVEd#yK8*JXnJX15($xpVNDR*9&{nu2WyA(fRTr%N-~<&alab zF=%hRdi)zAK;U~uGzR#S(>R_)?N?-1&=p`;VL9!9Ooi84Dgf=NYhPn|8SI7P-eLkB zrK*bFq`x|$Vnb$0Ec&YtB(jPm1u=Sk6P}zxmIc;^7q&(unJ&Yl2=cWRtTOb|C{jV% zn&{m1#z23;u@QNdlvRp}oLq1r^dCTc3U6&cmP>skeL|{$%`vIrJXtMwxa?*01Q}x- z^2lTdNz!e;-KEK$&@ovEM;VwGR;-+XDKGwM114j^`>uY2YB z@bbJSb&IcI8FJdF)cOvo`O&!wkCWuz0xAC;bG1_ zA#|ZSQw7Ou;m&W|Un5;6UPEjBLMF&r~d2J?hCwg!lH*tk4F z6#$h8o#A_#m(WRu3@tCq2Z{)#xwS6jE&YZAdtN|9OSy&noJav-mV5wg8^+p!N9|JI zPeVFU#KL|^f-myB#lx61;rs7jv~fd}Lc0)kQ7w3f_*sO4U%)ZW{q{2X1UOhiRXymj zSb#nW5Y9*q!XtNnG|LHuL=2gqUOK|HfgA{Af5IZh{lV(o8-!)E9FT^zU2852IV(Yu9-0sv$V(@ zSi~6lc{l$#q@*(hZ>j!Pr1raH{*dW(6q6DDso+rJ$&NReG6-pH57>v%buI>`WA!QP z_#5+=LFgcE!x6eUm_cEkfRfR1UPOth#o7qh@wwTlx4LLQ#_bW!r1e~1-LhU$^A6HD zWr15g2;$`_UGxIoAWz=-_LP6qs^ODSf01uP6hHg3FkBp3KwEycr)Z3WifBk{gS{k! z@k}pRv?A}U9yef5*~Oi44Hn4~*hEF0477zod)i{SCsC}rP)VN!QRs>$N8@qOU<^Hj z>E1c5Jh~GJ8gvMyaW2WtL(Mg}Sb_p3!Mu&6Zk6D8$?&cNekYX863a8e9;leSHCf-> ztOI$jPz{PkSAf}lX!A~}h{im~kMG~6$chg8;Sb4*1&Ew5;i=RsvJ9?iGoEDV;H>$cK23Qf%E&*g#O0 zM%d*bQUY7MtY%T$hT>Uran~3V?L3z;?|GOPlq`aw#|Eer-Al@F>d9(Qu1cI*bpXGc zR-xR|prC4=Keki0MMN#c9MWToavjRNKFbvz#v36x9q{ zh3uN$iz^Pq2)xsr@S92Xh%>P1K?d7p@~=mA_K3Dhur(Jq^Iiqu8f61jMJl0t00Mc8 zC{$2b{147l1Rz*=tfu%f;S_HRNh*es6G--8TqN%LR3u{$fw&3^3nHqY;ci_r*Q3oZ zBM@eQvw|H+WF{OZ^8#jIqEB^N=y1JsbmJ(YgTfhs>08B(OHmq9mH-;ciE6sQ9H;>z zJzKk4+byJ9a!i{ME9BlXibVDa!#=mN;NZ?}Ap_wg@HEH!7c?5jrq9&+a^BS8L$H22 ztWc4SqDeoIYK-WSVI<>sCqy60oA|$PhAdyF$A z3KTIF20O{N_|-f>j-UJgT_8EJA@daC9! z!G8DrR9J;uIYVI8e?HLFJrMuA+esQtb1 z5);NdPHWC%gC+H}OqA3y$i1OcI7pC=IKA2(5AjH`zLX(P8r3VA<4Q%iQ9}zUKqg4o zPmR5_X2W!&tqc?47VAx^D6rv^Ag(3S0U$zLb%@j?g@ z7RZJulaI8DZ^%)4ifp6D855*RC^9<^B%$URf84q7IxP9$lWg(FM4JJ#rqt6-b9AGR zN8FPc2D=zj#h18vO<}XDqjDAl8{O-$P1|CVa%NU884km~f9x?fXA;~y?r9iSF&*rT zrR_SEYY)hB(BEa%W(?lUTAt6i&baH;r^T3~OCOOtsv&7}@VH~Hy?8Aee$baeqoc2T zB_~ikr|vwY3l*0j4(=$-EwY zdXKp5gBNCkeq|Q+r^;BPnpHfE%!_9PX%{Gmvyg7D$JtRu;5x!@B=w(Cd}?N+3->uIMrxnt9-Xh!|@ zVKnp?ILBAt)Bh@};P_uN{{AoSnjC+dY5pUs_?MXA|4WwZzmELx6;=FylTQ4X{MG+S zg#pFzw?gDQ%=O=WHwpfZdHu`e^FQ-e{|c2A{gyFv{O#^3YQspt@i%~|4HFc@cjDi_ zj5|ebmjW?_K{O zd=Fw^_y^*z8U5!hzKdfbU|{?QgyFl4Z#~C%P2a(+Hs1&gjQ<1WyAa0zf%4Z%{!|DOnZk-4?{t_B}6I#sC&c*&;5y48|&aI9Hwodkc zSIPJLMcok;aWJV+uz!K5gc*L@ z?glE?{--Wv3aa^ACA79K%*OJ~bQHGmTWCV?AODOY#W%`SipD;?v_9`(X)RQs*|0_g zFLn~tO1qFyGtfjyf1LO-W=ty}wF@hE1a&{AwVB_EJbuVcL|Noca zMvb~LCKDp7MdiQZ6w`3w<~*aT$m^qxW=FHKczDcBlge;f z3{)gclngQkQ0t}Y;`xx+O#4@_VuqNvV2T^3FaJD0RPB){?di+z8Doyxnx&m)ycIR- z?hEA{qz>$VD=5%#r$Nchk>%WDL9JavUbo9&)aDmb+6sK{CSg3LYAa;c!_hWhn7n~#-D-Ey+0zaKTPQWDwsmmeA~F}=J=Bi9lNKZu)chj_I%^ANBjuZoRKmuzPl;W>QjAKy zNl7g$Yd{@aXb6n48xxYtFtn;}SeOPCgLZkD1S|>(5KArR8Dzy#-`Fh>TKJI~UedBR z2^pI5C9-6UY)$a;I=5Y)p}6gaJJpjjd9C+P1wKS{8<=Y!`q!!kN9mypb9{O|CO%ofc|sKSo%p0Z&;}T(a~;wRl(t?C8)@oeU0~s zH0X`N>|{Woc~1&Kx{m0j{y6i#68WHQSkwlI?D8!Z1}^}7=VGBx9*jM#hSX3j=^jx-qy~vTB^g(t>0e!~dt?@O=lQBD7*hK8j`iA1K-6gRL zEUmu5l2Ro*{|=DQ!8ymrKLSYT9DaVmO9mtdn1Pdxo&8ThvT}kMfC>EP`I?yt8pK}G zgw6iTgv|~0kV0o3^5zbiDNdHg;+4QL>bNVt(3WThpME`sBsj19M5sp2xH;c61{0Q?cKcVV1*-M zsp$=LiB{Q+_7YW#`DEccRowB?+2Nl*(6FiIu2@V8Uov$el3?i-@``alw>K2oD{Oqk ztx{qpX{;L8T~eVe93b%=u5v-SG|=;aGt8Q;T|CfTEIhnU^0Re<-9(PdwY(F-T6^Yp z6Kl}moUS)rX+;_X(oR8k!M8B4nv$`Mp;3vUk8#EyWy;-S&JamtlVblnL|&vA{|F+X zf!W`LNOl$mW=@t1b2cjnh=G-Z<<~j;2T8gN7s>fAh-_xMF65e^yM}4H@ob^UA#_3! zowP-27S77<38}cs?HC0Qf;kWTJ{~9}pI%oIHAxf>$=1(o2P1#waI0@7aBEztxk*R+ zZdVO(kz8jk(yv{eRhC<(=Z!MAv400@f(M}m?cHy!`U`2uvC1BOF%%LJNE<~!-p!9aGIWu*4w)@1?wHl~Zb{ZjJ>1%r%Gh%X(Ym>(Hl4#b zvFW4JCMy2gjfg0=bqz)R@s;vV$!NdBBy@bvA@Yx4^6z6ctW2B?EFjQDOfqvY0J~fK zipfi)HK3m{8Om+Z%!ev;cn^LJb31I(GX8dH4k4dkd=t{l@-bfpt%|-nyon#8G1FJO zXDpNa*QytWNL!ybsV9=}WkwO*C)q;(VCA9#B{jTjS2Nh*N5S7&=C9s}G3{hUU!@pf z%U95|Kr7=zAH}-45?C2Z>{+{Ps+DjfG6K&cK{%pGJ=WZRn_qyek$P_KroVKVc2 z%nqtJyZP}(l;C}_NysPc@DW-xBoCRaCqt|?20Y@?B8U4Muxn>SjD2jO0HI7_n^ ztg9D1Z`(5yf4dZ0qi#a{!5k#`l`*j;E=g3!{Aktqg^pSMDzza#e>XS0p=<}z(gO5{ z2Qr^Ym)=ElvMTLZS|dm1(=0I_kz0pR`G*@9==C2%tQ^YhHoH`6Y8t-b6gDLNW`h%E zrhk~zoJkDl=)c@4n}w5&0ifEf7p80`Fark*2m8-4B%oki+LX=lGZ@3F&tgb-_>bs8 zcjRtzIxfd$k!Z87gkXyto$yh=cd3w{ZEW(eYjjPeQlCY_l%ale#rVM?%iRY%nDfft z-5R*vniuWS3UjZQS!&FDF_@{VdSWoypcmvLpBb1qj*~^p!0X>Yj63BHk6y+sdSw^J zOU}2TQ3O5>&Z#>S@U@@XNJZr>=S2$3lBBd@bW7}BBf4G@9t!hAe5Lwn#kS8KF3{v) z>{fcnn({3@I+I}+jzez&IdzhxP%b5cQkI-CWP7&C@xdvf=Xlurxm3kjy;RSFCD9RS z48(>)lNT@pWA5T61EuO5c$0g|rbUk7?u2b~l-_h!()sw=$u2lkT7t#(jkuM5!o=hG zs$;}&J3c%(-hUr0Io!D&-V+ERS_zKM>iF;pKEFOTKZ*Z0{_%8p&JprY_{USB>->V3 z3`t;zpg#m377iu`5GT_wj0Vum{w6f~gw;aP=x)NnVQDU441L~MrQ==+y<6kBh<(d^5!l*Sr+QY=*Az)8Ws)8W5V`y&II(9jQ$M@=7XMo*VEHMHy&p zEUCO@6u-nJm@w$B*EQ6V#A|3ltaOme-XC5t{y@)*2r1HC@b#^c1(^tIQCS;vA6X3a zjAE%{hjM9tajccF@Rf8Xo_$rPMf7>w5379OdCR?8v&(|=n>!4i zg{!Oyn}qnPf-LjNDPJxH6SX)xZ4}Muo=ExgNFkUG^MsW4X-xU@1FsB5r^?Q}jTu*= zOU9-)kN=JI2^UZFc&rB(N`74a##$`VwC2nKO6~8Wizs@Swb zD_=QG#sYU+wjCAnB88gq%B%D=l@AhMSf#jxvqupHpHvX|=1V-)P=k>Q4iW3Ns31Tn zs9lmK>_llO6Sv)Y;QpFG8#S>~T7ldPrlziO5hDXWQSEn_{HNK>X}0Na!XyVX1DFHI zi2X5T1JgAF2m3FQ50H_%v>E$X$)^^Yqwzj;M;^tj8|!@`FE69j3Y%Mz!V#kVL91z8 za>N7KT+iLcz>xBrC#{bl8nGCfH~uXK?_vC#Q7Hwc7^T2uAYzwkD;b;G^lcj^vewiUS!8hw;^3F7Sb6P6b(Bi7K1Ol{Fs1M2u+iVC$4hY+ zJvEGbo^DX}g%ri~0H`A;*N(}d^W1V|uh2-UzZ01`+VLJ9ZJPV#({#>807d8Kg%}R}pjLbYa9i z6a15IE7BWbozZLODOfXZZ@o_h>eHB$j(gI<1WtE4nSGSJX?UZQTG!>Nt&qd2H?MoK zrQdwolCnTJ+f}F_LzTZ(NSD&bWxI_lmTf#?tzI}jE2<6qJoAetw(FH!BXJxI24?ZA zBSx?JOAVejafOYqQuq|zi1d!l>0Tp3O9t6?Hx5m+vP2`L=U^nO=JxWwC+qhce$`?m8uRF^gKR zK;t#>7D7S$wG}SozRDu*>IrT;7JNZNN?hKdc#4M(E zoF?7RFL=3xhM9x&lu`eQNM=qTg#1&o^E&;6+id^tV4)^aOBZTXQ3O~mW;#FEwDS~s!?S6yZgGm%f zDNf#t9bp>BbnO%7ZNcfq4q{9mHBmAtHoftzI=Ip$7}XTMF4P`4EfjeNlgF~`dY{WA zQK&NWeFuH7TeTP)8K+Y_7A3v2J(1en(S6V_Qo+hGZe|72d9#YyM@prY_>p7oU^OSS zw2{|m2!@f0`$hawx}j6ZmAw4vYX$~h;XMdcwCY9aN$B(t9_4-fCvU><6O~c#oA?(N zznMlaiFKihR#C0F*S~`(?4B(DJ4F7|q~^5n<8MMFJ39jt5I0^xBnR7RX!(neyhKv- zYh}e73s^E#U&n+dTSP=J_h?SRj}q=r<-^g9)3&FzvdJ809I`F=U(eh>A>jc6$#!or z3atz^E)I5Pv`II0PwO6cO(RZRFF|7!%#Nkn?6%2Fna>jgbuwKsAD;=&)tiB3SW$Pg zw@@W!%V5IIF-u9Pb^J>kGW61PM+B_)BtmbqSP98xfmXe9$5t2kwSBscK3m7EqjT!e zhdF~Dt;K8vZm=kiT+a+TdKd|g(WbPXtx8_Zi*t_6x%Fu0P(f0rGL8SdS+i;RBTp)F?)XY$3>>6Z0V zV=E@Zcg3ol&+zg+(+Y#Z7N1G$F*mBsa%GJ^;KUKUjodKjd^U*b7`X?wT8Dfd8m811z+h#ObbP_Mt39qdg^<8B@6?k zhlyU2Q#`}XLJk-xZrhS?vRy?s-^DmC)1@e7dEjST<(I`Uv-Nk3^FMxBA+2IlR8G$P zqDQ-Q_u=r`lk7bP^f`L2uh{WmI$_U1HLN3NiIdNyPsAqEyGO2-^!a4PNxE5>u5KM% zjUtKrm}LDsH2%|^=Ct#HHis2@Pcc%$O6-wC+gqu6lMkGL`&o!O!ILy0BW@$963)nu+^pAOGi0Wpyt8S>X zCDvP3H>~tDn4_G;0ch+7Lsn5tC??Fy#J~oMV~92t<{|BD2Bm?1Z?3cNf9dX37O3FH zCU~oilIoXQxu`NKk)q#aQh zm&};hOfLkX4%qhOA{IX{?r)5XcXzSU*RNVl1O`2vwk7 z)M9M#+q#+c^}$+3!_Nm-KWc&Il5hMDk^eNQIjz6^dk_hfQ2=Rd@CB9)6jA&pkIiy< zX&OLN<>f`TwX=cfm?JyE1czO$tiTlgRrx6$>C-4g`^?wV8?+5|k4Pvv`ga5LtAod+_&P|gnN%}=LRjTfc;TeAt;ipfJoDyp-v^LY3rMzZBZ6?dYPaVxk z<-6%ap%9R2rKQ}`KnK%84x#6o zPuAHtu1qzU+XL$O?fr-$V&iAZ6h_7wxgO$;@=TTQ0|?DS#J!h#B;M|M#OTRlO=8eF zQ4@k}w%%AR-e{BkOplJ{39nzI?kVAbNTKzTTAEFFC7;*JWKUbQmJf@Od04-WQeKM& zMcN+B-LmfML&W-M%J?C6VcUuk+u%!X>-i&itxvk|(`#5clpX8u74`{}Ts6I_sO25b zB|a6&ho}`#h)*aV8Ed9;^Cm*ERFB{tL-$Xs+>LJ<8`06w(-Xjth*o>Ejqc}m)1!Zx zn6>S6`{d8Gx9A@E%`$LY!Dx2 zbs}VgaaJQN-dHqzxx@K5PTjf*D_cR0#pBiB2M?F5CDfGnN_h7-otkkH64>8XC54#Y zDzA9W8b#ls-lSZZ$3%H!Gp<*P!lZ4n{lV+6p?E5V&B)e!Tdk5SBZL#w0RiczAy_66 z2Xc-MzR1G1rSa7AMwB9>h01$xSd%Dt&&V{m^-P5Kb+l~6OjI1&nMA9IRj9h~ z+Jsg}*gvkNnvPM8v*hl#wB0{8tUT#k6DDN*z;Sfdb3>c(cewcr4CLoE8346l1`7TG zCjl+T2doLP(1+sVY^B2AgA^8^Hte(x=MSW?0JIny_x*yDOXD0MAWi=>QpC}(0?upC zHh_yCH$v4K#GJ>oHZijcK^A_CkMNh)3Hh9Y_z{0H7)mVbzWvym9^|5LsI;=wQ)}n!h z*U+-Xf~fM8muj6m6967(3sC-q2#D=plN&6T#sfgWil3hma!;y->AKHh++4i& z*7w!~e4%Ibho4&0)8_UNRI1MKNKo69i%0${1|V!?Spi`%#@lC5fr0U0{;OO%^>M zStW-kM>h=3Btp2$rO5PwtimJi7?6*_LGr*Suejp$oK3MZxtt({_{2 zRCGcVda}J1{oE53w!`Ob28KU*bt4n-e*XMoROR`obFFA=7du0}8>*J)?@;m=LiJxz z0<41qpGF(MqU7=yhMc1W1k_MLCm+&3QNqOhn~VeNr3L38Aj$j-Or8U3+S!zY_#L)F zs>D6}UW3si>ag4*+b7h$es}}E2w(My%baI|5QQ>_vQc-79x$0?WkT-OmW6#j@v@w> z=3v14>M2C|Qqn#6PNY<0kOqrhOj1mA-l7$k#b(=a%T7F=zo`#pXU}B%yO5gof%fo1 z@APoIWXvT6gld84n%HISunxigrr}Qn{&AXu6)xC!AUBshtgI->L&Nj~;B}0%&_uB)F_$gX)G%Hk zhW+qPtxO4=nm5cq2?fzzM8f$Q>rY#tlcg2D2Pb%1`)&u8)A<7#qa<-BSGJn9q<@E! zzYxy;f)ZfmB=~gt{}m;dzlh=wlz=(Tiah>A3EMB_Z>*OXyZ&4m3SjqiY4sNE_ChI*S6*ne18(WM3B1_*CEzi3 zYGc>b9QA|a7%hfjeXd}x3D)1hh&vgbWq_o*@8c07o zlDQuJF}fQ2^Mh!<`xa6jNBq)*@}k;xTi-UdoU6s&u299FTuDySSpFS8E-h>Ys5~>U zJoR70*3($_@9`r4Ex`fGgf7dAfPXGXlMFpCNNeqZZwk1b^?F>btU-{t;jRp(s7HyQ zX1$%Bny0q%0iSGJH6nu(UyNK)CsQ7#T7Jcg?o3R{ieL#*0s_{Xk4%@?eTFy?vxbuI za9+dq3oCz7Sxj(8mX>lNh6!v9FQqxv%*Tc{y_Q)d(kZDi+7K-!!DCl0)Y>I5S{SN0 znq+UtJI~zTTgAP*N{mosti0vFMo>p4@a+Trpkz^~^u`FE@e$;0A7Z{{r~WL`+wpqF z8tM8VIpLsGD6kdI#YN3pixogZYtYJdzdB1Za z_O$`9k1t|4lL7JXuyir3_}^xv3oPd}uKj!9^53!?V2m#dEYWJ{a0?*RFCu4Zl5#v8Yi1hZUA^*M_5J z-kUpuI&Bg+ETV|5)!bm^bHG~n?HFW1a_g>0GBbTyxsctlMbZks2p)GjFO6DEm7ZiT zq;UU7dl~eu(e3$-w!xVKc|~2ZGUUB-84DeLl47_w9R?soa<9A9c<^0{I^v+Oqn!1W zj?>ygyFpWGVgpk>BQafW;23bAgnOR^0I2+1E$tew&pzdgQEze|Zqxmc z$z3i|{#(8S{?TyZ5}*P&$e*E7YXZ<>Z`b>+Lmp-&PY$xC(zw+pVWau3IeLf()I3&- zqbDE>;Y}SMj|V28hG?N0P%3z`Z&acZv-wkZT#1SY#oTJoe0XS8sVHq}YOg?E&8BLAof#4H647h*NL<}U} zdyYWh)xWLqT1x+G;oPlJ95=xfbyV?W|DGawJB!{z3vZVBkFcXooeP5`xSMb4x7bcV zOBB8C^tN}xGBNU=NWRg0v33_^P&l0-)SB|3L(cWF*m|d@fNtebv|Qlz-Qs=T|N+p8UW2m5VaXC8OoPWIaG~>(VBmpK}C~XROD^F@CNGzB3^8apt&M zd4nMOb+~H*6?_v(ql};KmXTfy^h`FWHp&0~9!&bB+iIEA74!!+m zG4hB?zD(I`0y~czXou9ksK+@*L^EVEV#fqAi4Es;&VJ@$hmmhDgy(E$qXlcK-^r6% zE~3Oqh@GHqU&{Td9c8j>#b{aL(c@6kk*``-&EL>I$fU`c-egRC-?N~Y(JfL!?DN^S zbzHDkWgm8aaPQH6^kcli^*#HZ@E3RTrzYzj2-T4Ek#*3X%=Hf&@|XIR7V`NQ7bS+J z%Jpy$xm`(!kT*S!bzjYR@{J6l^*gLwRLcJESh*6ZzSxbeRD2 zkMQ0xavq8zea9EQd)4brbYEc7WW?k|s@pgBs$xFl>Y0%&xb9R8#%x4*E7l?#KaUd^ zwR;u)h)p^;pM{n%kS48Nu9h>)@Oe6RuFYB$|8hJX^MW4l*h`5@ta3Z1TNX^&q|!S~ zq4bDG!I@?v#x6~%CNbW{#aT-_Bz9CGc*Yy3i@~}MY+wWV4@f1bFWmkd)R@+G*>^EzrO88898_`}OT`m>z@>cD8OXD|Mu+|_ ztdtG4TX|AQP)D*-VLLr(Z7Y1}U`r|J;5(w3nC_?Ff#gym+S5iY=abl31E4?KxiISK zkTL;9x}2xv^IYmbZRhgu-g3%9&R@+271PdNEk(*g%E)hK2eGk$wu@mDf;brKLF66^ zkTU-0>;v>{0s*~-jG?aqzMBCr6N2bj>O+2lfRCb@5uqaPF}tn9qjoL~-B+<w&6I-hwmp(>Q26Yc+!h1yDipV6vW_Tl(jnHBO&K} zJXUj4BZI-^X;oHKRbaLr#g}i?O%%GVwO^~g!uohG9?a|>_b$^*Pf=`S3MIK}vx`5k zf^!SI`#siVoIy6Ck=LfF6z(zd{$m0ZxLy?X&(@+d@FaQ+x(3M9Ej8$LIjT2~m#Z6K zQOtM62zE!GUhD4JqA9mmyrH^aUYtuXX}jO7F=-xpf*2KqZ?c4^&z*Zgzb!EAIi}?E_U6R;ONyt|x6xHG+uWZ5+)4sn|+%U5;P%@!^s~~Q~ zAi?X1ckB^P54rA!)Qn{gN@Yre=SQ4jQT|6Rej))zJhTT>h?ADD;BR>Ch}@z`AVws< z!kb?`j;Fm4Hfh!sAS)OqVY@sit*?3aDxJ2Nrl54Uc#IRMU zv*EPk`K(pl+~B6e0^}1%(jQrTWCjrxec`pFs>_|mU2IFAFGxBl7R4>{=n4-FSAQTk+JRyicZoO%~FR;AmCXv8{R`2X3|Qz-^_OU{Q7kQ zos`tVjBysTpfnvK2qNr;n;MbsJ@(MnkIqPVl{oCr0vMA(Q31G5guO+j8r~(fidp7; z7+uaiO3v4GpC4Id(b_O+&3`kDli$Yh+IUa`aa8wuf7V2QwK2&ty&HLrul2o}8&-E` zUpEo#=LzO1MU`bU98f4oCsH=AwcK1CmL;;xu_*LPiSIL8G~IsFVHBA|TU&=L0CQ}z zA@#f$y<~3w{@as)g4X+fPY6#0UDOT~sz}`_-5J~;2H43~-EpUPCy$S+yEa$8Sy}Js znc!-F?Nz40dYeJ*rvTk2ouba=-wWd+_u5}{%JWCu-fI{9l3Ih4FvahvTCKA3jz2^1 zU2fLMZe>fyJ6K91qADEs5j8yS-Zna=+(9I(2^p>RVw!jXvqMf(g_eV{>s=P(!{oXJ zh?B?8M!P9lLWXEOAY##nH&cang&&X$hBjYi?{m~=bW6egJYw@r)J@G#F5SL!gf=z@ zwQXLS2FY!;A}lZa5HTWI=Warmtl5T@YfRK`_`Xztvrsw8^d4i$SCg(KUU9o+%g@uM z<4dMO9|@Ba+SJM(*AO_?JS;izRxOTl=SB9ZqXMEp-`bBdbpDQ`eLDx{HORU^jq^P1F$VQYYNU*!f`S4%wh(=wd)=AvuK|4n^q0(R z|B=T1a9f;!9DQ+)N>h}y#N@nQd-w>`)keHz-qLXsLh)_`*&EJCZLV;R&sP-0C(wjS zdVH_IY;W|Aw{TAA+YOt_RmI_)FKD%?1R$ccMCw$Lk--f5+GJWT=Nk5s@$laIBj24b zW%ON3VZ>;uFCEwh3U6c)QX)^&L|rYVc3@Q>=wQNCC+c0+3VWNtst*=@qAMua8}24j zWw{JSlU5lHyCL%u10R2yenV`tc%d(euZ|#~_^H4xOt`mqTbKhrzQzZ6EFhqC1hPA4 z6_uArmtaFMWEL|&lM*l?yEc_)QtveAH?n=FkHDmI z^?lXt^zY_{Uz~H-?mk>rd0ZBTQu(gW`x_ELLlrq&H)-g;Ku2KntjmdOFHVL3_o$Pv zQ?t!n{s=IcP19d(6lm-M?po*hB|be`A#R6l*VvJr5h}`zI!UfAsH5527isSsRjiqs zCty92GsBuPn-Fl>9ye&?Ub?By9ECe{BdRk#S#?*-ano^l>P59cd%2_4-2)zwF3xj9 zguQCAkZWkmVI3w6_A<8&F{?ByXShLJyP7`F8KOWq@d5--lsg16_`=`8(~0EtGd=Af z7kCDP=^lNjgv?Mu>k|(BSdpy#MDwsyc&=iFp>AZM{hJ6()K@-{{cM@N#d#}~LB_)w zKK5({LAO|ZX<+j4*6z;Zw)s66k0TNp0GH=#zWOf3g^s!SXu3?E&2EfMfWtq2h%_%9PTLP&Y_ydMvSKIOxA}F zJ9fI5f(r_yRK(4Ukw3)>4rJRA1%(T#l~WeMY4~5YHWHu>d|2S&+Kou;q{k>1SpT?kv3!U?Y7q%11lfEL#o0QtqxA?-d60{I4H4U-7JL2t%x>AN!^M&-P zUH$Ny=V4~c3jFgol!Lf1)#8tne9h5LO}uAgYx`0K<4D^_)qm57yaI!2CyY%l!10? zv;$7|Lo*PxvtbFmE=VbJ*k)55DEf*uBp|PErjxK|tnWe6d8H28^ z0fU{TrI{_GA+$TFEhEI%fe|rppFdWo-BQo*6>6s+g!Hf3iG}5C6)iI}bnz@3P{wxFY*GVAJf2_q z>{92K{x@d&f!7P~JUs$^=cSuTP{&q>UP4EgUefr7DgU(8MN9&g`hi=2z{*B2+gXLm&nCJ!J^VW~o%``WaCqtnFB44yIxY}1dU<;* zD@z+YdY~gPJ-@!rpGJb-z&Y%pM*1;F{52!7ahz6#LK`zPFhhGMgMrfJvsN<~(Qt8q z{+*FdXUCs#bdLVZ!jb5o-ilrUD9Wc7u+cHLu(bpFC)3MAY@t5g_D`E#99*c)F2$Pz z&3I0iRx^WG88}#h1u|e@X)Cll%Fn?1FTFYN{$HQHzs;M=g6QS#09Ow&bf(v_(5F{2 zhT7{-bDcl*&`!fpb6tv4=VU%@&H?n)26_&%01dR+fV!}=_SF|5c2RKqHxN4uI4(l$ z^vGpChks0dGLmxia+YRhz(fexO~=mOmR{J(SdU)7QpZOBPpe&wr~s>RoJBo<&B3z) zElr>;LrDSa0rgQpsW=-m(8LkCTKa;~PA_%t6aJmi{>8s@oDcP7J(qtN4a5XurGEs0 zn3_5NFxsD%f`(4#w+pq@W%zkEAj~@LlMc8qz(5?NY+&|(jjc{Eb$;o8XQ_X2^FUX) zvzxvwOPzWx;4!qoIZy@7k4YbZyDCnEvH=?$umLMrpiRAh2G@V-^f~^;>7O3C%qLO`;z%!I3>Zt^4q|n|I_Hk^hra@r zIY3?MUwrb|na@HiPIkacfq;z-*ns9P&~@TJTj#%Y?>{Kf#fSF%t}hEvR#0a1$3ynh ziclzIF2jkl0sUf6gDDPR$vg`Suuy@G6Lebc`?FF0ODE2G${H^^@zW!h2^kTHnU#UP z89kJcT``oO#Am!Q)R(t6*afIr{}v$vyieKlG0PEra|6DS3K1h@riij*XV1 zzMYYlrIoDy^Fu%iekDdQt!;95{g1avwFp0V|DYI)G4w8Y@7{fyv+tYC2Xv$$ZWu(JvM;Lf&u=@2JHC({Xg{eKc5Mh zQGOf&1LtEuP0@i)SvV8$PUz#zgv<_bEwCd@QJ}dTMQOJ6+8V6 zP$>tBDw*V;wnw&iS0ht~IG|^-f)UgtQ7z0QF9vv_s zr`SQvl}G{C$*BC}Fc|0*e0o>}5cq&I0o!Oo5datfIIpCR)9Fuu;egM5`oVx4Cj?OC zekf5Fyzft22c6{?m`OQUfwif3|FuxKW^B?>3O;3hB<>awGP>L1*ZCv;B1e)u6=id-^=6Lo>s#?t zUxkQHubfQp)rBa;IXoUj`QW;j;J9J4Yisc~s1x@#7KNI?&Ao-K)Em052-?>2l8j?I zjyZ+|Qa8pU$V9!4-e7*Mqk?~W-(h3U-L`X!dEU!fdRo|cMH=D5lr-)hNdhacvKFtN z`sPaNtf1R>7oQrnU=fmgl(-){x!-S|+)qHaeI>^2|Hd?0_L~9e_h}4`N%lmSF58>g z+Vvz)j;k0YKkk1;dx6;&RikDry^i2ZX8p;Kn`+m-pjf1brS)^`XYgLMVrOZ3F6)>% z#Z70SfF|+OyEd{#Q?FL~LX)G_D7fWN#_T~{4h7rj7~%Z0mZ?l}6vj1!O@ViMj>I<5 zPGXLwsO=a!f~=&e?erSP=}enkpOS=wlW4YIiDtXXsb1|vag2JXw-NG?{H4BuQIrG< zN!Vg&VRs;FM9>yqN8nKCx>f!i;nhxsLC4SsM)hj_q1gN(JG$@ z13uF3#AWQ)wFnpLzoOd7y&T^0}b8ylczr`t zkaI#NTpS%Vp+lClZksJJlc=HZ-GDstb(izO0~mKz(5H6YRRp5Mz@fo-F8#${Il_Hz3s#-|ZSO-XJk>yoG(d%9r>x z=5^jf@)UAQv0F<7cV63;=~d#us|a3GLd4EaZ!W2F7_>)~P@88BV^8B_Xzr|j#I~TW#z%A0`_Ius%HIqd7vgcc3uj{x#w|w zf#V9tJ?Z+eZlD`uV z2QO-Hwih=%7Y?r>cR`FGiX_EeR^N|GZ+7neY%LSj94T19rLhS2opXgpXXU#2NAv!* znN~*U^3a_bMjM(=2P+2-EE(z8=TEhW8br5`v!%bnXE!klxYP6aC5=%v$)G!IF_G)t zcFtU^M+W%Y^#{3&x;>-w_DL+zAII=88?2+M8j0^ZWvX?<$LU^ z*>+*7!qt==Bd2@nwf8#*ZPe*)86y1?1|7QYP5N+&n7;YWsfa#5lO871g^72kZ+5`E zxk}DH@%cNrDI*wkv2QQwd=wu-@L34EvcIZk>J`@SXj|+W>NdvYDv);RXqOKR&*f_S zc1m?LP$RqItk_Ih*541BqOy8Eo%zHaGd&@-i>7zJ-D%|M%bEKb(#tpR36^JaSuZ|y=*9L%L78;z{HbFJgn9no9Mn096lOPkQVTD zvnWst>!84OzNETbu+K%LbL$wSglmws{JtV`%joS_W%rN-v)`Jc-SbZV%FWOT(jl`%9`XB1t46*FLxKAPQL@ER+wj%$YJ`Fh zGgx3&sH;0o4}2rv1@Z@kr{(#WH|fydW!AC7awXJ0z7e5Z zLk}}Wvgiy|E7Eigd2Gd-)zM^7%0CCz#oL;AA}t5}BJOoHw{A8{6*$7T?@S zK#)QwgHT9Fc{LG)d?`rY_E_vH%Z)(0OZxs(iu8&kS99)zt`@UM!9h(o1;V$3@U!l1 z9UpI}${qx~@V2tKF<|BG?zNcxOpNiJLuC5+!pJKRix8A8pY*kBt?(}X79w1SZk_~0 zH>x-tJ@X55b|0STjeREMzL)k&x$)f>8E0b;ytF05)}^_6KhVe{&-+)$c>;sdML{u& zgx7CNB)Vvk4w@YirggnU-^KKdc|K=HYhSXlP1bI$$u|zkw1K3kd)mYvBb9raT28?!QW8uZUZ5GM%2rZ^$0{$UG=(jl zgiKj~(JB(b?s|xen^$q=L0c0){*eBSQ1&??EjGPaOMRr4Pi)cp%9?XLhTDn@>_c*# z;tT>wah8}3|C;kxLAkyKW*7bw zKkmuo&Ekn#D`V#c?(mOq2|84$4-jycZzozt4~0^=flULED2j*N@3g*^CLAfS&$B3f z6$dLfzAZp0gfIKzS)wyxaC+3YD379XZ=%;H$-S^#S4U=a`)L`ezF$|jY#HG1#t2H; zR)^ecRP->L-yIb_xE}FZNAgxew)G5iQOI=&x(=Zl??fpIl|wlLh)I=eyotw-o&ZDk zbwGm&`IznYC>LB5n-(gp(E&2vDDp96*@8r1Ic9$GoiwR)DHd8;rF8jt!C)@7U!DJh z$7W=MIv;JM%GB###vmk<%!usuk4p*dOUI}AS9MD2PhuFSd&Y>>^?%UK=g$`J4@{eQ zG%A4SLR3dAo=YUM8G!Y`6@kJkAXxU;nj;MDaS&Vj+oeJKA`5|U=J>c3+~~Kbyp#(g z=k=pXJn~Rv3>I4BG%}}G!?GS2>{A(y_%z1LKbUkM~-`D6>*4=rbz%dW-+YLawHQD^1hq-K3ha$E2x z-pyi0e`@+{JB(WDxm#zYABQH|El0YOxM>IboTL6lF)FSiUzQOeD$|#Xh2!t3LfCN^ zaccr6-^(~E?&7;h2Fr9#FHNi(Mz0-?3+*0f*lL%P)Fs!c=IOqW_~z+N_qsjQSgNI$ z#s6*xuBAl`E(fw{dt15Y=j_L*asKS|LQQH;L)=7D-oHN^ok)aG-CmVe;^t;4dJZ&9bZ6~!S0bK9scy8ju%qzT4g2Z}kni@M1o)p~7SQT|idlymI9*_X!6u{l-P z#j*_AuWPSxvrfDWtFD;&E>u_6AX)b^THV$98qB9u6c*@BZ*UW?QX#5!;nDMjP-aD; zI?B#3S$3}VrWoWF5RP%~=3tvw$U$YLgf}%!#ExbZ|7+-Bnab@ zSVk2V-~PZtySmtuYecZ<-rkQM+I-}L5?{Z?dq=GXW5?QpNy=2cZ~|Yc`70KprETH$ zRoNOGsh(7Z_}wR2yHkV#U2EdS^K{?jkoO(quD)YyQq|bdmTRx$f)6pz6e4!+vjVSL zs3y~u2}5p_lTvXCkDHuO+lXi4EOZ1BY|9G~8HO=fSKe7#EMYRdrf zc*hZ4jM1#G@#XbrezV6|7{G-F0tsD9eAjTJWGcl+>i%-3`${gPZ5~3=-|AM1wWy@F zaEr^Xi`p_>e{Ur?Xs!0D@})}*-J?>J;+&9=_0s8JHS_}oCRc9oq)U44wjMY{bTT*| zE=&TOt&^+#>%z3SnI>h$8&s$HxpzzNgTJh^Bmoh z$ZghZ#J=a`Zq4VODH7Dig-_h!{|>8IN5QGgl=%3BHiLy~H*F8qSwOy|O&uL?MR7sZ zfs)vcbS1@pX}uI)Qr+t?K{U-FVD%^nJrX?$K_)~@@g~)d-%~s@9&uhFa&tkF_|lEZEw1oP z8o0-IidN>JebfoW_{OTGp$H2SU)kaIuqe*%^Hx-+<3Sa)b|_nvv9qK=d;ctJIP^Ni zfI01(Qb5Gi9cFj?SDK(bSyu8~;ycLh`{mvV=1l9xxMkSQg{^UQNEI+Uqf7&ZcgE~0 zhCWNSd?s2nMI0B>cEO2^b3E{utjj77yG!(V!4%>gQu->URTNJUbN7B&NL)Wh1emj; zZ-v4+f|OU>e_I=Sj%PI5mP^MMLz}J;d0&CSgGGDcT3$x@HP49nVo;r9I@Y~_1(oYt@XHiJChrLIu>;NPP=S)sYkj&rks zLT^Xy_OP}V`aQKaxa;%OhM`)IgA~URnEM7+9%{tn@)eb&qqoWf#cz|>QY46?35P}n zR9;GBPoxChpJ)YVW__VrW_UuxqxgJ>rMbef&%4sMBTE5C=XL`n&kOO258X7Z3Yo7M zeDf+NuRRH9atqv&yPo`Ps$>Mh#!zbTQpmu5Zryx6_nwfK`HUI+PCZJ&jnYbat8Z!j z?6jNB#h+jdU+h?&$o2FsY*|{B92=0A#U^5jz!`*{NZxj)nO&uj$p6Mc8TXVvw>jxy zZg)#WTcHUDgUvnvL4+r~Z)>jcZ!?y{dj>wvr_yef`O+)FuxWd>+xQFCThn}{DpxJr z{sm(S%e-Wf5>2_Mc?yeboD809%ZS(qaZVM%CS$USoRUr*ZA(Ul`_$W$`k`5kd3KMk zh9FtbB{g7v{l+iF;~!wdma9Q}A{kwB&Dp}GWhkdC*>12Fd!oyk)@J=G{`L37L9M;x z@8UO#?joQBsx=H1r^^*u+vS$OQxTX%9|?K0JOtxDptd~yY>`kqIBL75IKB#%(eEYh z*R2!wK}XN(hUa7N?s32f_M#Jnb_!0HMd#Pw98u?tC5y^eEcIamDs{gyuCAW3v+)H*WT8jsjCh3q^VTt7Ss7aCB?T%aScOiK%*l z%@9}7Ke*gJm>x1%Vyrs;V4L!!CyzfaOUm56cB*xjv7RXuTkoV3PuewAbdbUPX7%K5 zOGpx)v1kfH5CIP*gzvzwU!~_2dkUJ-q0sjf*tckscwgE3G5ai_bqKa+ed&JGF8ymp z;!Lakqd4jRQ^*zk3qtOXjFf_VFjFG(zrKw2(pWy&HIKSi858AvzmqC+IZ`ow@Adh zr85K1s6FLSpFX)>6j{?eJKlPO#AK76yPLP$YM%=&kHw7Iecm(askW+Dv;RnK^tK5$ z-1IxWO{0yj$9GoyK37t~i3tfg2J5FZgYg2#z42mh3gmPNv!HH#5YhCouHuAbD89V@ z;sFZ<#mhTnZ!>&P@Ym80=3ND<7bRvVR8%)&+YoEC7+MuRSRTLx*VsP(*TH8#-O&7h zQhfiHQ9o6Dfr0z~z2FOd2!5($0>JfW()nEQgD zo5;>JCojsiEpQM*=fbWR-KT69#297&R+Y3Pec~DSd@jmW5NCGD#11Ezgq-b;>qM>?g`kUMWE7|`r7ozmIbbHY6 zF6ArZ1o&=(fk)17;}E}S#J;Xzj!MgT1G%<_uueVzexK(OMO`WOs)SO z#uyj@TJYcF7#;N+iS_S-`?eFEY~{O=+E3qjt8Z{W;eQyCIez8;HqYG^IR@+PS^4S1 z7hy$$ukh6Oc!S@hWWNR)&UgEL)iWc_@Pr6JWrXmSMv?kqHV&k1b(o10;(B_+bg7Qh zfq9*B(>5~bLU%ion$)y<4^KgYPL$A>4IkZw>ol*^#c0qJSmow;atG?lEK4M9BR5ih zl*viHySKRId8U<*0^Y@QSlvFON@gJaeQOycusPX{&d z6I#b6_QWDD4rAI+7W?JG*AXq5;CGLzyh@Npua53D^Qv~ae^kY+4=!AqbVcZ|&d zfwvVT=ex=v+TP67ih=^ycwD1s;~}M5=3`40k-S>Ov+uR_jec|(SpaOw&90uYPz76N`DvkWs}B(c5ZC1Ril*LakF5 z;rmu@q6vGlZZgD%f^H+yPze;Y{1bX9kQ>!^iJb#(YioU0rE_S{$d7X-9a;CufqW=xniE)o$WMVXa*T*A zSTJWc7lkFf6LETV8;T>#P?PRShi+!yD=Xx;pE`>4+$t7e$8{^Bfj??*f%5`!@7u@a zUQi{O-l7$Ov9@D?J%4BrBog`FZ9dW8IKlSLEVypS=t%dTv%P_?I%vnJm2p~|mo$C; z^q5wl@iH`i5$cH-o=lWaTd6!MQ^TK&KY`+dc-rnKp2NVrGVLRsWxwwyZe<`}r*WD@ z_4|RW%fvRR(Mwt7G$zQ+euzVnOZKBF`DaP+z}<}OqhV#m*oJYITFl)uUclngDg^5y z6S}JJO;rCEpI)i7H*~Uv6oww@O3SHNMV$rguw7Xr#ex?%(0Cx~V zA@x&7CLe7pSmfQwz9kX2=u(H$*P)KXTt_te7!;h$*q{?zN#nTa`fq7Ig68^UUI+;d zxn-JMlRgVLXTdstaPXd9yt3oyTi8CBz09*taPQS^WT(K_#W6ne=Aq2=CK_M}-N+?% zRW+IYJT?4)oBiz~E0HZ>&xMcHI1ue*=ff*M(;jDxU`~tfCY=uTl+_4FrUBYBRO>1+ z#_`zbxMC|dL_}}h;rC@3r455ph%_@Pl$I0aWnY8XJzPRBr)CLE0?J}&Jk-gva1N4? zyiv`hTE+VIJZbp+ktv1qL?dIMZ>;^y93Qn15K|zZakvn*d(szTSY4w+K4o(|m#Js* zTSq2g2eJekgfD>+IJT3xr5WVB^jjv2iK%`zza6y6T~rEyJ46`P=R2WsQupr{IS_&o zmf|)^KS;N#ZJDc7tWz%3ZO$To8G~Z7AOH)8n0EHgEVH}O4xT!78VL^5S+Wn`IiQta z5u!B3RY>B{bn)d3fQXmy7s{JQ5-Y*Aoc&U4yx$h-H9 zCgr`e8dHF2j8}z=p{#rLCeUi!3hhTaZNmQNlkNC6`2Ku?|-nGa+^Zty`ibJ+6 z+{%==`;U2Cp6+#YmmlK#@I`AU2v2m{TR!#TvfBW#^(^+((U|vShPbY)2cRS(Q(cc&v0$vE7}k4bG|6^`dx`TPSYCAErsI{O zE;62zuFZX6+biLq$eZXp!ly}mhXq1Jn}6xn`xL; zla)rKd(TesqWHiPYVtR8tgRx9K8F<|u3BiZeV4W&RspxPZ|9>*y?ih%O`loT6PCeF z$1;^wKGR6|ZC*gN-etKC2j)ds0%84>%Oe>RK&$%_1DBUBX~fU?U=TT^PE?QzZEYKi zXG8Up@->PkZ8d~|F(sHYf`sO=6jzdJ4K3Hiv>K*z{A5g;D`QHyGGx)8*B+DopOgmVQ4(YufC znU6HiEBz%njFd+nUOz8PoKTllxl0P)1NFjfOEr!BHt}i(&luBJjRjy>!`HE3Epd zVNe+PNjh@&d5PDo0ShYsVikTIe=5z*aaRiA)fqzelnts+oVXA2^ZR-I^OrNQ(u28> zCSDouF+K*zReYAg@M0HM!Fv6x%V{{wWJz#I{-on!iH`=9l@lqV`Y0|4eeq0sg>0bu zyE4%E7+=6wd?r?pbz*Xvr?r?1S&HNNETou$pbu0cyeG~yb85=&(dW(9B(gl0hg5jc zU05XGxu)EGCJqlxNHVcDhb1V=z@n;RlXqE{M`3<&Z-l5vm`?Fk{(NE%!OHr&TJR&< z_7$9+!83m*(be8^ycSd-wKH?!Waq;5^H01A)1xY-GM$%q6IK&)3exrKW+z*1cUb@SAf*V$5G#NAwcrEC_rjWQR6Du?_ zVzNhrJ5J-Mm$Y}++S#M=L-_7sE-;A6#!kGDWyeN`d=GOJ|f8$=4hwA@*U&+1YURtGlINmf?Q_5$6DVlY$@zxGo1kr#thkA#qeQK2nwhh&>aY zn0)OEqa9}_L$k1gUeKJP$BW@1acUs(*L_vO7=ux{m?KdV2#hJX*T~P<4k;7S52C3n zaQVS6`d;u(S?(;8U2zxGJ=9Y8A3ORlPyY9l`UAT77Zc+Dtb_jv-1q--J`9K{d3%Tb zX+HdylHafV_k5TI5UlZgI?Mo&`2O2BOo>d32_iS9TUD~@2tF=4{3m%hV5lrrZ9H$% z8{lCiWN&2U<gvQdIsvBrlSgWon zk<|}ANw+JfCi({YG1~!1n7j~_;Z##UiK>GbALj%p;`q;EHBvQz5YrKF~drNTjoMy zHy4`^Q~z*&e0y=WWIi&ye>bwzD64C5Ie-7$a&oaJZ~~e;sNSQ<6seEjJ~#BT!cE`k zmEDr+t`VDJHKl}OY72|~u|V?q`rYYyNLn+Ap4TGUSwj!3gk~s<0kxl!Y6rU%;%hG; z;-3g+%dTe>krRjb9Ia3KL{l`ard5{KTNcZ6rhG!R#U#jk=6(?!KuhO>tISbNIT8i`mHUI)e240(nHSX#-f<;~*9$&{58 zMDKtxTV;oK4HwzFfuOSva2K0VRucAZJbqG3rpERt!G$wj)T(N8`sVA4UASMM?ydse z%earX$~7OkfIhX7arIFguMZ%u>F^77y#A-%)e0fw;_TNpw(vrlmM;+|AiO=&Se5<-QRTGEWghBua*FHy!|n} zT?P2QU;vn!{n`TL<8*-ZD-Q_ip#|vl-_-DLZ88IbD;VBZGXZ?i-;Tc}x;Hctux#ir z?C{r0C(Jm^Z|Zu0E}jA4OZ>NAEpJcw_ptFF4VeE~NB&<$5CJdl9}z?bKsdvHk08Iy zpy|Hdx^phSp0HNkD!0|l048P+EwkUpnZoHgEk1-$7RSGw2HTY8s(hPO&V!1|+L8WNq3Hp#brs+S`)3n_gNt zeBP~On3Jh;N@MH2-McWk{J41#%=dzdca(N^Qc48b+nMPwFh#7#3iV11@%wf`6w&Av zRXNnPa+DFnF+cb8(^%Tswyl{}QCq%&%OneFiJ)&H6%5KOK5+@x0p^|vF8tvE^egQ|?tGqAG{ROWGA*WK71=_nX8h1LUaVipFo1lQSCeem=lyuCY zFono2H*G56;9F!AJ+8>xjwJ(YMY8GGJ_neCm}Mfp~h z`-1J+1g^*xd^hulv@0BrA5sbf&T8K7Q9cDpLiAWcdN^MG6JpB!P7_KwEw^o?Q9kE` z{7;1M8#nZV_s}kwqBI%Up72?C$di4NbSz7b^lc6;_icpu8>kE)EBlswu zrEO?^`KX1yg_#Y}TTHVtaF=MGDZjNAskE-cRZWw93|6&-i9Y|T`BH<%v>yr}RF2|j z4-O4!)6V&n(46lUNgdC$43YRPW?g(de5XEeWG>tJa~9Pd;4SC2?Qy#afFAfb2iQ*p zB)#Oi;dc@WQpUcw4)v^PIArB!+aqT(i7bv5o)8AlfeDd4E8K6( zsL7w1#R_dZxsFz=47fdHRM8lxS&%=?nE&QK&@F)0;-@VBXsEFg1DSWLjrJ4LEBp9L zK+T`C{a6tuC)O*$_Mx3Udub|@Z!#U$a~Xq3vX98hO8xV6JS%k~&#CSG&qJJ1I<>2T zwVDi&?`^#}!QDJjG#4d9o3{)UWTgsC9|t41f;vK+g^%zjiT5loA|!I;N~<-fMewbn z92u^3(5`c*nxN2Z_~{fc8IA4XAZ;uI3%Ih42x(Z@HO}4WS_MzeadR!VE{=t-IKc^t zb{`|FjHqIwpP0i_5PE?8^lFsKC7RGAoaWgSR-#m*uJCO0rOSD550fA0mpq{6t7ntU zXEfP|2+(jxg*4V6eAxFIR|Kk281*LHfmkf42#+iFj+R5K<6ffUB5w$Yk2wW%QYj(^ zHJ|;I?!LAtRw=f5^l6-O*TV~2Zg)s2w?%)&(C>;?6@5z{nS!k5u znu<6Ree`K@rj4&kztLaLS=^Qd=pHl`b&my-Yy6O zH}dKa;Lj!P(H`gXo}sCv`X3W~uII;&X0b-oA+w8wo=LXF*J+&$Q5X*i-h$7i$1lJo zJQNaJ1U}s(3@=V-VKnSwU7^A#PN23f4ULJrBlr0{6|US>mR;#GV5ziEubDer72Dzf zj%LC%Ox6n4vi@|4B?Sn@+zc8NyKJ-!mVBj1%lV3*Azcz zEx$nB(6%mT#dITFT76Ah62W8+DBCj`6_JPr8}WMpETW47@@QKgwJuj#r%DQwT?OQ% zVU(dTzQXFOv@@RnGiyEy3NL`l+YA4i1w(Jg&00;DrDd2waMF(4M5UE6wPunx*v!s_ zeUuCTg{mwHWfOQ(RQb>vHBOu$&?UbYhUh6hpT7f{aAi=Vxra8~bhwf+fbN>iaz=6k zQqA64LxK>}lB{7m4N9P%oeJpH^}Fmu*p{~)oUniM;dGRp1pDUsdEseXQR4fX95A6bW-Z8K${+D6!}FZ7D@VA zkmQsgbelib$OK1}&-logw`r>F*FJ1sfjD#K)`rY2OJ?&ivIpuFJx1}tOz@N?Ybk~5 zpTXwbG^;apwrQ>T0rViNT-f|6VzqblFN;pS?_Q!6%x8CPgHO5@1qd$2fcSne*@Ap& zz(#Ug#WlrK*uz#<>oX3}e%v&i-VId=pBy)`WQl7EBxg1IbiubTfW6UKC22)S z)iJw!Md>y;Y)qV;%ckqVKY0)%Q~1J1|6M4BAtbGXVwRn{%jnycT52v+#^z%mKI^)h zNyCaCbC(ixu2l!ng#dOm1SeUFMT_Ri#sM zlFz{dif=!HN{u+>3{0x4Gfq0YdsSrNuzQ;AzLvYwgR3-WYLsNB&K5#rQrF8J?Gg#p z>z5Cra;ZX-1l6e^0+tI&;IE_s0UI!1OyERYK=#)^iun~+CnST>nSp&yy2}RA4ci2J zCzwkQL%OVkaIL3pBx>EI@J=201vY*;oN!?d+&aT=>p(Iyl#$Z08F~U(iDP638JF}a zu8s2s%d6r`2Xl5)A5={c}jGNqsiO6upPd zx&PiF!L`g$;zzgu`ciT3{Rw5YqM{Jcsvo)_2?8$b*9SVZU>N$fD)Thd!0-~_6l^Ta1ydOgx7xbMIu4!t)=-NUxU7&6azs2*`B)UMf zGNV+HTl&s9xuI`p1TSNL`>`fXr0%bG6@{*QWO1;2LzoEe8^eKp?etu9*x*yo9Kn9G z2A8W+e2A7LNdFT2)Lb)iE{;{!j<9o)9Kb*{k&k^BW-L4gy4X+XP%Bwph6!k|g z2-iblTuxmj(T9kz9~gTc-j?=U*B*cv%8Xaxs}GMFf;=Mn1vh7Ad%{b8cHnqPp>Z>7 zJ)6Lv=0?pX^XE3Q8{>lz4IGg99~0BH1yq4X*x=a1xli|i8tGq{4cQJHqSP!a;K*pB z6^phCdylV8;J&F?%UF6A>|>6W;%h@%*K6#ASJBPGlm^nO&hYFLT+Cn)h!4i3vGa7f zakG4sZj3}L=|S(a$Ta?*wjCa{+y``#`(dM_{~IfU#3;dG$yY`dLF`T&$o9`_M!cHn z;610fD?H_UMR!5Nz~7n}9za|5Sx4NyqW0I!X&^QsViPnZFBKohb9q1)Isgg9`>uSa zuc5d_B?_~BhWDE)kJi%?bGE~_zOAo<){Gr6-6;YukkkP)TIP~<9O>uug_So< zmtyuqR)yp#A*jC5g5HsM=z%1BGzvC(afFF;+@xK$y;W}zrgRSJ%OtEy&MiTyu5#xJ zwtFcA)rsSPQ`%L3)nkUC28j?1!+?Bkz=dh#>9psgT_2Tkbp7lWrY(4WA7oPz^>dI# z7lgwYF)nF9@&Tv2O~6Vjg^WLK_DPvleEY~3b5fNejq;y^YrwK0onOT-ycbN5bqQQO zF)9|$>f_ye6iw1_SAsgMM@A9s%G`UDjLWKVf*wLAhs_7!!wNM?tnyR1m$aWr@LK{@ zS6lYv3ph859mzBwAtjblH8&2oyt1#tG9XmBt;cIMi_lJRwuHT@U{jU?Qno0@9jS+k zAacX{L@?UJCJQh`TOC9q$>8emSmeu*6zauG$J=aZD)=EPHfX*d+8nKWR$&rX!5dR` zv8eJr;GR2OD7t>+u*jNsm}`ixS{*h#xhE=H`)fLjZu#V;qDMYW)I zvjB$}6bN=3y};*_$pJX0x%eXm-#jdSqG+U2-+MQA>aVqHpMqHi>Uw7N1(TosBQefT zW14KS4g*;rBVK_|!>6uhGdD-5_}5g}1Jp_p{+5jVk$4CO}YG8 z9yoGlPYI(kEWD2c0^7ms6vZZWI!@(c@Dr!P8e3zG*OjNY={}fv%enfjb$Fno`$6JU zhqwy8+3*+ac`mlh92`3%i(H%R5g$Q^;f7WhiI*R(_yXaL1xiJEv8_6nAH&R74lqqZ zo-oikGR^)8^7`AK>VK}u6#9GQ^$$trKWH&&0jT8vUW*BU<^IlxPfTmU040LBJDP669D#UmpCrKP840=SU8sVf2gA8!iFH_Vmxtqw+j_V6#~ z{@Q!<2LU98Uzju_z%PdpfSWP_KtLt{JopPMWdXR50BT@*^9=#`nJ~OLlDuJ~fc63I zbO2NqkO28NpOar(fLil+t4wcsK%FeV45k>FSpI|p)Bm!TWq4~JU~K!V*0(LdlY|an zs0pwo`{hkS3%LKc^jDnr&Aju?u>_!heY@%{(Y=)cB#LwZV&?7GTaC;B{}l$nJ-_AO zTv7fOtNlj;wo zvsvikG04?Mcj=m5l|K4%pJJ1ivX1{KYL!F)N4n@BbgH!x%_Z37Vz;(N1N77Ss$6LJ zS?Ss37Gf~E_c56K%g@SLPluXfT$XHv?PSzd&9kxApc_NbgVWCwF1Fh4^O6nL_NTbd zoiBDM=jPO=dx0tCuKN-z7Jm1y-DSOVHxtStLj335BKgsAB}88)OlLzhZof=kDOL#4 z%)V@^&`r^5v@%>yAhh)aF0b`S;mKH(pAD|?WE@X!JaLmN*dCneE4G&f|aWvxwsTX zvweieBz7AjkCEp22^>~#+AL5#e%nml^O0aqLZug~Xmk!f_oCu6_egd2=4+hM5koGe zsH4gB+C3F>z~a9sK~m=AKF>&@HMK$3{1cc)Xvd`c@ewOu5VQ#inW8C^#z%EY&&b24 zqsGT2_Z~yG1Uxoa6j<+9`#ICZUTq36l<*;*-d9HNKKCIj?bam-u#-7GbT16RrHwkN z2eA`vU}JjY^l2H|0{CnyA4%8WAbN9&UMHz!0^DQ3sU#?wm6kHlL?;}uA&k3`w*Yjk`h zp0H~s8*s92RmDLOA#C`RSSZBM;QMeO&1)<|Q9xn0C23tS6*riZ_M}9a@NnPxs?jp} znlL7Bx2X|_u=4JdqOEzgYxGRxvh7+@fHDL!NGz-?dzSxmushNrqDqo1eu2_NPELOG zAdyB)bG~Agwj?5zf~)H}1>r($qTEI+ykx9nT^F%I9J|Sq5>+g@hP8ITg@_!5okqc} zNCMe%_0`41YP^vmQT9+Htwnr^vc34caAILZ?}C~?LF)D35nbqg90&d}VnZt{4a6d%v)2&3Pj47j&_X9QQD zrn*9NQ!CuZXjF&!XpwCGXtjgTGiYH)GsH3>9Nr%?l$zJyNMjLRCtXhV9T#psFlbeH z6tTL_f0G7ZsjnoyZ?3Vl2dA9eqUT<3+ucd#L7MoXc_nwTuR3;qqH~&j+;{<3@#H#| z!Md(!{s+FDUU}kqNv@ArlzpjvC^QtK?-=bU$AbFlOdP9R`n1Qvx8X_R>im%zkOhg; z>{kRvfjm)*qZMDvk0eI>=xAO{hvLbElGfLjLEHl{FAdsN4VHJX6$FJ7# zkBu2Fsucul`^_#`t5&}hEQon{jyM>Va`wu|I#+3FxkGUR~V)JO;UgIJuKI)-~|vLdRjpOcb1Ea6sC#w z>}6b!xO!sd2)kpoiI&bJbUK;ypL7jQc{HswoB0>m8oJP2Dfpa}9lPUa^En9;_g6yH z3~hTWnHTT0oXjv?4W%N}&WwNVf4it<-(p^tZ5t1BP7miz?=d<4AaNSQ7FBiW)C*osf~YP0)>EyFb<2}$2{ zpSG}nDB@N#RG=5jV2TSf818K=O5g2*e>oKOKqCliM%m(ff_^5w z%7zt-%sq@uh5f9R=*12;pI)>rrkr|qDvC-Pv8K6TlsoyU9dyFS*?U00%%7YsP)tXb zqTyM^%d!>Pfk8V+9Sh_xsolOaS8(tU_fpu)VEK+myae%8`n5Es43dt}hnLL3l&=-XW=k#kVje43uFEHDps*SDW3c4i|+smg1HUGKFK!3Kt#2;sD z(lhgCl(kvK){L&n3du^s3k-85`*Vj8dRb(WGs;r!#rL{oGEKXo_Dy zp7kC3g+}b%4d%)}K$x>)i7cR(6G}_K6bO9I&Tjcx924`d?Jfy2Q{c=ou13bwzc1dl55*Nh!OA@R~3=0ZXs!M$0@ zifB%dcED;ms|i?&Sqs*x$!iV{o3}&6FA@9uxK+w(4#1<8W1L1gK#u7rD6ec+cCFOT zedA2A)2@)gQgh>r)#n-oq0cuvU$^g%;)EQxwQ%E}a~(&Q)$QNcoK881FF>V?B0Ehy zRONpsVG?n;`b1$ph5Y({NYWzkdp2mcN#yh(LbS5)5F+?M{&pwwE9J3Y#`Zzk1$gkJ zV0^ihhm(}^0#9Rnyqz!badlLjULGco>`DCSd%{ABYvLAYO9ec7q8uI)`mnH74%71! zo^e%0pLcOHKGk~t^0DH!NLjaehs$CD*<&SyKH?iJifa#ncX+YqAP>>DG$W>*Nx0Tc zWNlr26ph@UrS|r zXAc2RbOWObHGjP6fLD;##u$(BMITM zBAW&H43>k+DfF^9>ICeiRYXCJm9V-OpgeIyn-IRmmzY^TGIie$N}N*7^@dyfy!eeI#lJAHqx{5>a0a>o_olNduDO_ zKy-rmlyk_2#A?C+mID5fW<9oLb@Sj-Ak0J{a9b??f0mE@iwA z&tALx{OR=9hec6}Wg!BW7S$cOgf^~w7xr;Ad-Bu2y z%E|L(u@p%$8qmYSehi=mr>4vLfeZVRwuslFzCyQJQQbk|1Q+faw|1TFU0>0fVTL8IXmr*2|JoWAq67fp1 zmE?KSST4slj>HT0gOr>R>^Tkpb3dvvpMf#fF=gGFx^lw>GFHbNVg1gqygz|Ws&|dn zAn0A>M39Orm08@@4sgG;123|61 zIqg?|JFfIRGbo59tlze8XURFZ*5Qcz6{ITg{m<>0ohhx)=;&9ABlZrDa03b!gE}HW zXd&HiyZkjqglE58Z3~YL+wYNUey$doai(#O8q2xvQW=G_ntq?_e-v9{&-jiCr?yeP zQ?VZ2!1Q=adKn}@zq2!9Engtuim zJ;T|6V_pE<@-Qo$3fH@Ezn=|gBjjGZ`0$3c(N55rPB_)vGcHlorn7DP*}?M{V3177{yJTL{W}c<#T#az`_jJn_Y!IiB~3@#*SQfpn0K|YZoxr58pOSP<`3@zZbrN5H}iM4}l zb!e=J(`yqPufrn=Dc7xuTgD|#Ky_rKPYor?nQMg^75+)CT8uw}Bh?9k=&r7beS*%n z`DMQVw4AqWQ3%*J9#hjFC}p;J&6sFlbg1$BCQJTj2~apzCx5JUdgdj8^b1g#6YetA zYP%T7YAau)*-QnS8Xro~d!#N16jmq^%Wg;Rx=46RgN3p1FNS65aCOa|{cTV)x7L$2 zc5OP5t9IoNN*?^pl0QY@UU5`qR3AJ0?#>($?#?m!Iv8kYk%y7w5V@NdWAI2s<%;5U ztCx0|ktbHq6OkkP85rlb{;M6M?n)Bx%;*6(FS+I;IbBZ4h5u zYTj{Ew26)J6Wx=p@Z5v8V|I8gRs|WQsGU*82U$s3B@$hSK=&s2(b28kt@T+rMHi7q z+gvF^L<`RQTyKc5><(BWKddLF-1pv{|HS-iD3ud*s%gX zkn`1*G=sn;YfRmyjt?qTFMVrT%L`y(iuA$Lvne$iS=b>xIt^s^P8$ac*B+ziKzv6W z%&(Uv6o(MVFckN|Rv{q4t!s_=!1S=$hrgGkt68(VJ5=!zs@?%5scZJpj^tTuODn$K zpxRC=1y$NJe0$VWzq)1~`^aN2?DSr3HB2RnAw~B&vkp2Eb(Lpy41A=nx=&WJc+Fe${l-XPjr9a`c|EHzp!``veH2==V) z*fsptAxc%Pp01{$OabaX*HT+RKR#LRR};*9X+A(RdA=MwzX3)Mpjk#LM}CfMnm0eG zVV;Rc<-0`oo?QsuiTEn;D9SG()}|#{Cv-YnQOW=`dQ0%)kr~G*D zp08Tw?kgi6_)fY$q1c}go&Rt-Q4ym`&H(oGxTp5YYFltDBcVcM)l#4?U2RHLt;78s zj9PL!`=w72d4?&y@xIUh>iWq%aS|nIJ7|n*jZS6V3`5(1a-8ZsFuhzUp!EK|kHUwx z3cs4#g#jr>@R_zfs?uuTO9S!>>~866+xXxEDLf@gLgeMG zzJ`(Mbtly+4X-dM)}DFQvrF39)%WFQpAgA=Dne4wCI$svEp<1bDIb*sk1H zkVIljQWT%7GRX4hUkPgQ1ZGfzVld#RpJddtSLToJD17s;mtWXoE^oXziPd+AhouSU z-B{Hruwo^KoxT{m{*9c-eg$Q!2?c9aPuqNcdi3^gZ%o(lK zWUywKIu5+ub2tivu~Dr^z8Hfo%=j>YFfO*Ef#(Hz0j*U__Rfg!QMyiS!#ZS|h3CnC zs@OOE2>zP1C92+DCKCAL{*az43s-|Ak-Ac^r{>yLLb$CK@%aj_r3VENE8GLWC( zGcf&#pSZ=n0H(YF4zx13bYVz=8l?nlE0QP8CdW(t`-iB0w} z$-p}*4BWA~ty0>Fy?y2j8_}OPK9SlovvG!sw3)z9GQnF`Cx3w4)VUs}u5d3L?z~*D zi@$HzA(K)Nw^Ns@wys$=`qQd)FRn5h0eC-dO|*rPxn~8%llHw9<+|JjY4LM|*aTn! zQU`}wb}K5GxXj+Wo?RCK3jSL2cby^N%za(ZO?V`%wG*?C*rM^nC-HoqEFgSoJDk@} zK=FmDx)$gj7Q{~v&^bn`^IkbqZW;8#TI@XaPJ?)q~PWSRlS9WjAc7C zT@v~$Nz&v8*Kd3xXF6QeVT=%-Wj0c*Kx|J3pAu5CTsVcDcFT}P_VTU+s&q;PUEQQ# zKFY$_;6-~~@3jX5JWLVS>JBWQVL|FidBk8fGAuS@4z#~4AoLUytw0L1L@h$#Z-4cM zU+eiUQO%+`hliRF#N%gR{P`f?8d`%ZDMd)rOU1605*IgD2WJH@Jc5jlacbX6$aVTD z#un6)gvlRL2Yf3RHd+fPZ129)7ZT_iE;&sSWM>fLuI*gaTrASM+I3jC9~1hWMNib? zt}Fw$JF=m8G|axBH+dXAgf}@!WYhWss>gf~Y*q}pr4Um>oH~n>p!($t`DaZI)1znS z7Uex{7Z0-C4H3xYqWKHe9pgMhq}q1;s7sm?cw!%%98i_-F7-VXa1pSE?EUf&$Zm7? z4ohDAz044nNy~@1lZ5FX{l;E-qY)2?Ur>ok6W65KWc~U;WtjTo1@2b4OY$yUnvlRg zoor7>sgJeJ3Zd^NO#c8d1`LtYx1@87km^H1>*oWxTM{}9z^w*wW;fN{JQJNc4Co0I zn`CBHpfSzYBRO#p4=YW(cFm zuRwqxZ|X;YBs3`LvCmplF3QiqyAI7N zkV4=tN$vOaSXPGLy7YIddz4XV2Hil(gCuJ{%&i5iaqQyXI#XdZ&?;>n@t9BxzOe4R zYwC=AV612j?p|tNmsCNWADRxGF6dyoNVzpAqyJt%W^!n^o&!9JX$l?>Z!8B^I>TBk zpjL8ZVViG9seZ-uF^-{=EmC$Jn2~m$nFIN*1~2YO?cRV6PTPmMwtrQx0x^6cCN4^E z1^P%2SXmQGkFfAI{3e9_vJ7D3dF7an9RhyM+%-Hf_+aJ^GvdFuzNn@f2K)ZWneJfD8AfADcQ1WJ358DzTI~>=U-VdXD~g6w{oIOn8+;Wq5;{Z4I&#|Q zEXk@Yvc+)mjK`Lk8&ub4&NOu*djD~_)pB^(Yx|PNZD3d0yttW(meiVcdP~7gMeUux zsJZ9YhLSK&46;#Eie;v}a7M>+HOx`-_W}vk>W=7W@!-$joodVEU-y!yvot0cw;OXn zOlt5n%{w2=z`VF_TvPh4&r0y491ThF3MA)}EQ(P{;vP;5lD5_@f2&SEWxc9uyiKo}Gn=W62Dr@CnByCn#!4ClBIN z>{}jfPf|IuX2-PftyQM*uN&Po<-_|t-a{HXYW@>?_Rp~de}qx|ClQ7s|08<#FLq8; ze~v8tt9#CW7g_i>?qUFw85RId`nR;=pG{7@tml-o8?!Eee=}1G zHuI=5lJ|A28b;F=-d7({2iobeuxXhGW>rhSb@h(rX)4|20`1NP+`b($hB(0zN~Q7> z{z%%JyI8Wto4Xia4+Q&>Nl$J*spp%!7^3d5Q9x%E1U~1~ii&k2`|w}g#c13&y<@ql zOFGtN0q$aVe{~ldSlWG7{K3_`iw!4|#bY}w#K^3gU6BYm+!qV0tVa1Ax4{G738ZI# zCpJ}Hj)z@&I5sx7_#jQU(<97I=J_0;5|{q+S9dXl6)F_o;!~#Qcix#civQT(wA6og z(fXsq|3#qTzv$=RTky4&>vJRfGGbjCKf=X{|6C< z;zF|D5MNdzHVNVh!M)Hw#w(%9%K$ex3S5NRK`{LAS0>rWGQ&Vq zu7>bdt_cKFM)%?tsZR8h8Y|4w=S!V*I8_BRQrfjTxqlpSIB~gc#c?tD@E953c+8$qx}!L#Y?6^^Qm5&febaIvo#E-O ztKMcoQhZE$iA)tQ$(C{qcZu4}WB4^-TD!~#m);N>=@==_%4_gc-7TEq`W2GRn7q7# zmWrWitVwC5zn0v;jn-bXh}_TZy4#p;41J#5f>;GvPCtU#E{#D~uw3<3F@fC2kna;{ zAiD_V;8{xt%pk81gKQXEoO6WD%_gjJ(0&hEN-rVg2cVf(xco|+FoXNz0R_M>F_;-o z<0u#91Oy@lM0qLM&)hn)y0UUP^#@Tm9}iiRei9C*gg+q-cW zyMJsbGE$XLnN=_AmoMK(O6DlRAKWO16|0vIR402X$Fe_E3}y4iJe>QvZ3OB>ZW40Z z1(3~==yyF&V*I$B8Cs-Gl%3 z$=;&TY9NJs_d>sPNXl}XILFIlg4T97VkI7BUqp{Cn({kk#Nh!wXC5)i9jP%3l-vxV z@trJ9v?mNk8WHCLv|cG@skc0~Z)i8qQUbDM#@O!t80+n#l?N#oOLEauHEPNzJYsgN zZGqA4%!V@kR;1|Dz7}=*;A;Dl*w;}&#(MqYn%Y1Akb!EizhBjV{~iC8!Y%!eg`43o zC>nny)+hpP)&6D=`I`6gi*oZH74Sbv!+}wte=6R8Qe^&Ky#G%c{?84~`0Jbhy?*_@ zrTFI<>bdMrG5J7I7*}D0Q{vXooJM zi+AvvcDMx4si524VLv5Hme+6I5_&gi=yDFMla0@8!52o3?aec@(t7>@ybUo|%S{qP3gwGTv zuw28F?6cD+FRve}kTuwST*iV^nS`wxgV?Ph8qf=Pyv&3;#pFZBQ0-+tZxJGxXAjv< zG8$DM!H=X$f`mDENm@VB-TuTacb7~Fwu8+JV%~-06=RMj6@Wo}|3*68#0C&X4C&k> z{VA=ozhq(=CP2{Ye&0E>^Zq*Xo5mLN7SZC{X3^QQ^Ecp)qRT(OUs`w@y9&Q8FS87n zo0#M3LU7-)3+Aq)oKjGFLl_~?48y@$A-ny>U&m5B_@;)o*wx^ar_b#`3n&f;jXa>c?cuEf(VG3aA@JgYsyy(v@5-%Sy@W00#^n5Mxsz$rRLZFC9QrMMeOGbC zKmW`a{&m0TuhdhSf2yZII|pED+Q0LTWCXJ9eihIEmUrZz_=>>J%kNCZ-{!CS>DTGE zSHH3TUKxJB{r$oD@fSCc5$M|Z`?}XT+iQ~AE5qMYo{Bi z;s&xFIezuE*nqZ(tW4~{_j>g{d{vpV0?Bf0z+5vn;5`bMANSi1e>}wN?yothuhc=H zRQz=g49|U~75*Y7a&W*f0x5*Ak!i0|a-dlJm1GF?O=JODQI z^4B^bNs=9yE%s_v`D#bW!p!myH=O^nVEnJO>;Hsc{NIuhfr|NmtfPN?$opFzWdKI# z{oVs+VE{&b{->36H^tRWrMKbx{MuexfKFV&K%1T!ukgEf9~6+^3aKeX%ko1(y~ zT9d0}dY_d50!57iDPc-&Hir##`(9gutu|Jtp17Y?IHT|HhRf0jKp}&zDYljwA^8`s z(dnEWMI$oP%x-ob7Qal+liU-DnMGo7*g1f7c!{=L7kwfM4%nWy*;_Ul0UY)RA2IoE zq~guJpxH(?mFM}#MNjvjS>jO5v5G72Of~90n(+6s@+F4EIXro~jHs6WTx2Lbo7COj zE*YV@!Wo5P@9Juu`MmKVx`Za;S%W!eXa(7>)`EKV@SUf`ltH<%>`$hB6i>+?!t2}W zVh>f9=ZA_N0zdK^5;-Vl0hQ3L;Bv@Kq%IY8;nwl$)q5o6%El6*Yt%S7p2T#`^3CT* zm~CRsqJ$0>mzD?1B;%2TZ!);~L>e!w!eygdXO_YW>F!HXV@)pz3n#|nXrF^e>f1>a zsf^wXPNaCpNuKExY0k4&4s;1>-61?5R<6m;5!}fXWffaZ z&E^vjcUq%3dQV8Fm=$bEM|W3*pVGE`N|V;Gsc^9)@S~IR#3?uAvGb!d#ntDKDCkh~ za+G6+KyKtH3nfvCDPI-l{9A=mGIybm@d`k<%QOmeMYRJ7Z*zS3UFthJb7E7e?O3}< z-#2NStamBcS2b-oJ}Mpc>&w2YFW+ByV{qIV4n*i8ecthWutYjU@ubK%9il3RS4zz5 zld7k!FLz3wnw4Us_7>Uq$=^$)rF2wC&Nr^JvRP!=ElF&tS&4C=i>p-e`FIz;%U2ww zt?wS#Na>}q`4AFM^&F_HNwMt=RYNGII2~>0zN3bc%*;x_b?$wOdZ&!X9`;hxvr`uA6gplP{OZ|i*YpoaUZ&Pw8su*!E{5GeABQ?C z_^*h(KQ<2MHw)p-M$R%}g~fqq((C$kCp>-IaSz`yw$sIKEo9nyPp8?QDTKVFjo+=Z|*q5I8MxVfn&+ zq>XPo5Pn`=7C5E!+4iccz3irX80`|(x^Q^42z#+B$%V1AT)VThB-knWdd}mX=4sr0 ze&{U+;3{sckpoJ;AMnNLqZiW^-s=fCn7!X5H=pF z^$p9+oab6U*~+wcYjO3=B(6=p%FRz0UXXr_Z*U#4WAD%g5&7`NC8Z_en@;OMa5OAz z#O`7%N~q=4WQ69O34VyZJY_DUrdwaR%Mzm#p7gkfrqe+UAw% zd=YiBHwwf&3!0Z?)zIXET&}B^PS^ua&-X5D=*LSI)3C6{piM=-UPG4RG&xD`)F>}2 z1UqC_^3h*0y4)ss9BiB+=fu(m6t~p{jUfO<=ip*d>Osg6xrlf4%nB^#x8)PlPk>VW zZ{UwSBRQ@5fR7oy@3O$ZU-*BU4e#bRG1JBwt*kJRimP1V5+apU+b7-bb`MlR&ggSh z*3c6@a}oX=CH>cv9`OIH3kePdTM#fQuN` zRnt~QLyxavVlk(P8nVQ7QI51C((FSbR!n+N%0-#g25^URbn_c3**^q$ENrjmu6`Co z4fEV(NTE`w9@mH7GN zhUfiFw*A;)3R%|fAoVI*OPsn&EH`zrZXdsIqzep!MMd;xx`FLJt&}m;nGpp`h}z;> zN~rU)$=;BD6WO_IbdGFKe|7Vk2ZnpgWvJaTxkUwNeXFd|5wlT8TK#bF2me7Zku%L6 zM33+`a^C#Hx(T#15S~*O5uM!I$$-Q!fV2%95=zNWt`X9th1Dy4o6;<_Gg4b{IH}vB z-~2QQvn@T7P*NkL{xr;DN+;(aHGi& z4O#ns%?WUwG`rN8>%b?#+0L7`xTz7XK{_rma%G>uPd$_886+yN6XQtC{^@_);Pg%( zG4i04{PC%1fi7jp+=}xdgS1WIhWi{zl7FdG>=Mg6;BhBQD?(D&$nHsEy=&aY;70Rn z^fElD%#P$!ge}=!Y8XCp3P{9#&jq6$Jv>5zUUf2RX7UTe+CI^kmk@o`#OWI3IJ-7Z zztr}f$a-gg2UX>ih5uN6wE2YF7xeQ`)B}YlxaRe_8#iC*{_~9mMkD#~D?vQl&xQ04 zk+{B)sVQ$^+f~yXA;p9l_n_);VqcCciHna9Dn5-c#?|Xje&VuLVM@ECScfob$ zkTr)l3R-h;AF@CjuS)7F(bv}qe6$j#+e4d_IH!06d)GwlSBkFx6#1?$;jBe=9%EMf z%;6}PCtY+peMOY~eyiXUGQO{$$$Q8&v;@svd>hLwZa>IlT9l8MYHrUE5k_cx0e2Q& zC=E;*y{Q}Knna0HNMtRmevl_e)E@7}O6t$)rKoE<#UE|b2Y&h@Si<89;tikl# z@WT`)m;REFLn@77+!HOQ`4N+o_iE)`d>pjqyjvl)cmJ%*ZU1f&;_J!A!5E?vT&Ho4 zvZb>o^xY02-j2k0_kii$+4=q_uZcal=GeSoh-53AX@37(e`p{$J3cW;bBJ=c4?qkGNPg~+Bpad3S~qVhRva%`CaMI_Y|MGHu^m;vV3rH^Yk)flCHOoZ2BTH z&;oK(ZXwsQUXxZAhSJeYgh+z0# zMjgMm9;Pm<3NKW0K1+!ivQll_rjQXJb$;wRvH+-gPsaU>e_2a1R3+zwzs{7yIA}eP zuu`+GS63^aV1ByC>c5#SSf3K~MXr&HnvU3_M0Gm5NJBAOXU=_WBi6;SIt(!kJY8P$ zC#3CVjn5Xn?Dvj#BQ4X%WdsLgd;2!4C_zQI5F4RRc~1ARvLEn_v#^&szR*WhJF;ER z@<>5>&AaR^m<5rw3QnX;qw4bKY4Ho~+X04P%W$VgxO3T=Tdo--#F0XUwfwX|$u%jW zdOlrFcjW`}wj;8R1wKwF)WMuDo7htES;c^1L|Eq%+%;)1nhF^Cnl=T64=DADWJ%pj zw-=7}S{lH3kSS#HK&$voY}e@4{&iLdR%g1fD0vguBAbUXJX*u7rtP$85o>RK)Ok~J zcQ)I+HrY4B_iaZ273W)3E)9!CCo$MPFmifc89zA+;dB@Yc#~>j0-E^dHNi?}d6h

y_)Zx2p@+%C<4wNSaKMdCMkN0>t!(Slx!~hckF3&h==IhNvgBK zvZyi)nVwtaC)`L5Fd9I>+OCugp&HB9PWrccg1QGLN{WKs9$qd_PIwrQLjf}^`U)0y zGPN)Pi~46qln(yM_q5JG{rku5j_N&V8oAThp2)stsUuvYqU(IUfw%@qNj=izk`FQ6 z?vBw2f>)*bq2&NHqmeShuoPSP?we;UTGC>0n^`v^65>4x?Kb-YsQZC9^H!MK6@pL; zFV0h<3(+9CjVqPWv)*c6lhezQ(d)78~Jr{d<^7_)eq< zJC-CzBpOfVKi*&Nk?%MlfZUzzVm261#f6O!Ki6dn9m+8wUi3WWE|T2z#BCjYTpfb0 zGHbZQMXI&cJCg?Rak$74`OQ{^64Hrsz7$S!enz^m@Ma*3i{xm+_$W@g$mBNCAqU`lXs zwTD;>1PJYaF<|cWR3;297GiY(_0$MzR=AX~F*tWdq)=H{lipbpF>#1W{oxBBS1jYI z{#2j91gLxt`Y6|G8`Cm4x@2=_%BFB8fv=6#2d;c3cpe(MdAffO&DL__m^wY2=95If z;9hITws;_$8z9syN9fjr;a}z7i$6N;KWW2`dZ7$QfofiqX7jYpE~8t1gBjFQV<-W& zgk0k49V(da~h@wdQ=3R%yI=w=!gZtBoX^crOGG7S9s!;v8gkvM?`kD zzf#~EB8nIFLyO$2&$eSXS5##}_oaZL4foOUt6FXw3qk|ff}7sOfFAY;g8?isUo5Ir z5BfgMT{Wt}Ep#|!lMWB#h9kQ#^F+K>uoG!k*qH^S z|H8`s22cqtRX6PZt$*(r rFOk^MC0i_m?& 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 literal 0 HcmV?d00001 diff --git a/cmd/orchard-server/main.go b/cmd/orchard-server/main.go new file mode 100644 index 0000000..9008026 --- /dev/null +++ b/cmd/orchard-server/main.go @@ -0,0 +1,85 @@ +package main + +import ( + "context" + "fmt" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + "github.com/bsf/orchard/internal/api" + "github.com/bsf/orchard/internal/config" + "github.com/bsf/orchard/internal/storage" + "go.uber.org/zap" +) + +func main() { + // Initialize logger + logger, err := zap.NewProduction() + if err != nil { + fmt.Fprintf(os.Stderr, "failed to create logger: %v\n", err) + os.Exit(1) + } + defer logger.Sync() + + // Load configuration + cfg, err := config.Load() + if err != nil { + logger.Fatal("failed to load configuration", zap.Error(err)) + } + + // Initialize database + db, err := storage.NewDatabase(&cfg.Database) + if err != nil { + logger.Fatal("failed to connect to database", zap.Error(err)) + } + defer db.Close() + + // Initialize S3 storage + s3, err := storage.NewS3Storage(&cfg.S3) + if err != nil { + logger.Fatal("failed to initialize S3 storage", zap.Error(err)) + } + + // Setup router + router := api.SetupRouter(db, s3, logger) + + // Create HTTP server + addr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port) + srv := &http.Server{ + Addr: addr, + Handler: router, + ReadTimeout: 30 * time.Second, + WriteTimeout: 30 * time.Second, + IdleTimeout: 60 * time.Second, + } + + // Start server in goroutine + go func() { + logger.Info("starting Orchard server", + zap.String("address", addr), + ) + if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { + logger.Fatal("server failed", zap.Error(err)) + } + }() + + // Wait for interrupt signal + quit := make(chan os.Signal, 1) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit + + logger.Info("shutting down server...") + + // Graceful shutdown with timeout + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + if err := srv.Shutdown(ctx); err != nil { + logger.Fatal("server forced to shutdown", zap.Error(err)) + } + + logger.Info("server stopped") +} diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..454c0e7 --- /dev/null +++ b/config.yaml @@ -0,0 +1,28 @@ +# Orchard Server Configuration +# This file can be overridden by environment variables prefixed with ORCHARD_ + +server: + host: "0.0.0.0" + port: 8080 + +database: + host: "localhost" + port: 5432 + user: "orchard" + password: "orchard_secret" + dbname: "orchard" + sslmode: "disable" + +s3: + endpoint: "http://localhost:9000" + region: "us-east-1" + bucket: "orchard-artifacts" + access_key_id: "minioadmin" + secret_access_key: "minioadmin" + use_path_style: true + +redis: + host: "localhost" + port: 6379 + password: "" + db: 0 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..105ad1e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,116 @@ +version: '3.8' + +services: + orchard-server: + build: + context: . + dockerfile: Dockerfile + ports: + - "8080:8080" + environment: + - ORCHARD_SERVER_HOST=0.0.0.0 + - ORCHARD_SERVER_PORT=8080 + - ORCHARD_DATABASE_HOST=postgres + - ORCHARD_DATABASE_PORT=5432 + - ORCHARD_DATABASE_USER=orchard + - ORCHARD_DATABASE_PASSWORD=orchard_secret + - ORCHARD_DATABASE_DBNAME=orchard + - ORCHARD_DATABASE_SSLMODE=disable + - ORCHARD_S3_ENDPOINT=http://minio:9000 + - ORCHARD_S3_REGION=us-east-1 + - ORCHARD_S3_BUCKET=orchard-artifacts + - ORCHARD_S3_ACCESS_KEY_ID=minioadmin + - ORCHARD_S3_SECRET_ACCESS_KEY=minioadmin + - ORCHARD_S3_USE_PATH_STYLE=true + - ORCHARD_REDIS_HOST=redis + - ORCHARD_REDIS_PORT=6379 + depends_on: + postgres: + condition: service_healthy + minio: + condition: service_healthy + redis: + condition: service_healthy + networks: + - orchard-network + restart: unless-stopped + + postgres: + image: postgres:16-alpine + environment: + - POSTGRES_USER=orchard + - POSTGRES_PASSWORD=orchard_secret + - POSTGRES_DB=orchard + volumes: + - postgres-data:/var/lib/postgresql/data + - ./migrations:/docker-entrypoint-initdb.d:ro + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U orchard -d orchard"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - orchard-network + restart: unless-stopped + + minio: + image: minio/minio:latest + command: server /data --console-address ":9001" + environment: + - MINIO_ROOT_USER=minioadmin + - MINIO_ROOT_PASSWORD=minioadmin + volumes: + - minio-data:/data + ports: + - "9000:9000" + - "9001:9001" + healthcheck: + test: ["CMD", "mc", "ready", "local"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - orchard-network + restart: unless-stopped + + minio-init: + image: minio/mc:latest + depends_on: + minio: + condition: service_healthy + entrypoint: > + /bin/sh -c " + mc alias set myminio http://minio:9000 minioadmin minioadmin; + mc mb myminio/orchard-artifacts --ignore-existing; + mc anonymous set download myminio/orchard-artifacts; + exit 0; + " + networks: + - orchard-network + + redis: + image: redis:7-alpine + command: redis-server --appendonly yes + volumes: + - redis-data:/data + ports: + - "6379:6379" + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - orchard-network + restart: unless-stopped + +volumes: + postgres-data: + minio-data: + redis-data: + +networks: + orchard-network: + driver: bridge diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..44af019 --- /dev/null +++ b/go.mod @@ -0,0 +1,70 @@ +module github.com/bsf/orchard + +go 1.22 + +require ( + github.com/aws/aws-sdk-go-v2 v1.24.1 + github.com/aws/aws-sdk-go-v2/config v1.26.6 + github.com/aws/aws-sdk-go-v2/credentials v1.16.16 + github.com/aws/aws-sdk-go-v2/service/s3 v1.48.1 + github.com/gin-gonic/gin v1.9.1 + github.com/google/uuid v1.5.0 + github.com/lib/pq v1.10.9 + github.com/spf13/viper v1.18.2 + go.uber.org/zap v1.26.0 +) + +require ( + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect + github.com/aws/smithy-go v1.19.0 // indirect + github.com/bytedance/sonic v1.9.1 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + go.uber.org/multierr v1.10.0 // indirect + golang.org/x/arch v0.3.0 // indirect + golang.org/x/crypto v0.16.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..b6b3d7d --- /dev/null +++ b/go.sum @@ -0,0 +1,171 @@ +github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= +github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo= +github.com/aws/aws-sdk-go-v2/config v1.26.6 h1:Z/7w9bUqlRI0FFQpetVuFYEsjzE3h7fpU6HuGmfPL/o= +github.com/aws/aws-sdk-go-v2/config v1.26.6/go.mod h1:uKU6cnDmYCvJ+pxO9S4cWDb2yWWIH5hra+32hVh1MI4= +github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5gbadPbWdV1WcAddK8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 h1:n3GDfwqF2tzEkXlv5cuy4iy7LpKDtqDMcNLfZDu9rls= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10 h1:5oE2WzJE56/mVveuDZPJESKlg/00AaS2pY2QZcnxg4M= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10/go.mod h1:FHbKWQtRBYUz4vO5WBWjzMD2by126ny5y/1EoaWoLfI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10 h1:L0ai8WICYHozIKK+OtPzVJBugL7culcuM4E4JOpIEm8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10/go.mod h1:byqfyxJBshFk0fF9YmK0M0ugIO8OWjzH2T3bPG4eGuA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 h1:KOxnQeWy5sXyS37fdKEvAsGHOr9fa/qvwxfJurR/BzE= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10/go.mod h1:jMx5INQFYFYB3lQD9W0D8Ohgq6Wnl7NYOJ2TQndbulI= +github.com/aws/aws-sdk-go-v2/service/s3 v1.48.1 h1:5XNlsBsEvBZBMO6p82y+sqpWg8j5aBCe+5C2GBFgqBQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.48.1/go.mod h1:4qXHrG1Ne3VGIMZPCB8OjH/pLFO94sKABIusjh0KWPU= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.7/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U= +github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= +github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= +github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= +golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/internal/api/handlers.go b/internal/api/handlers.go new file mode 100644 index 0000000..c76abda --- /dev/null +++ b/internal/api/handlers.go @@ -0,0 +1,442 @@ +package api + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/bsf/orchard/internal/models" + "github.com/bsf/orchard/internal/storage" + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +type Handler struct { + db *storage.Database + s3 *storage.S3Storage + logger *zap.Logger +} + +func NewHandler(db *storage.Database, s3 *storage.S3Storage, logger *zap.Logger) *Handler { + return &Handler{ + db: db, + s3: s3, + logger: logger, + } +} + +// Health check endpoint +func (h *Handler) Health(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{"status": "healthy"}) +} + +// Grove handlers + +func (h *Handler) CreateGrove(c *gin.Context) { + var grove models.Grove + if err := c.ShouldBindJSON(&grove); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + grove.CreatedBy = c.GetString("user_id") + if err := h.db.CreateGrove(c.Request.Context(), &grove); err != nil { + h.logger.Error("failed to create grove", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create grove"}) + return + } + + h.logAudit(c, "create_grove", grove.Name) + c.JSON(http.StatusCreated, grove) +} + +func (h *Handler) GetGrove(c *gin.Context) { + groveName := c.Param("grove") + + grove, err := h.db.GetGrove(c.Request.Context(), groveName) + if err != nil { + h.logger.Error("failed to get grove", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get grove"}) + return + } + + if grove == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "grove not found"}) + return + } + + c.JSON(http.StatusOK, grove) +} + +func (h *Handler) ListGroves(c *gin.Context) { + userID := c.GetString("user_id") + + groves, err := h.db.ListGroves(c.Request.Context(), userID) + if err != nil { + h.logger.Error("failed to list groves", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list groves"}) + return + } + + c.JSON(http.StatusOK, groves) +} + +// Tree handlers + +func (h *Handler) CreateTree(c *gin.Context) { + groveName := c.Param("grove") + + grove, err := h.db.GetGrove(c.Request.Context(), groveName) + if err != nil || grove == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "grove not found"}) + return + } + + var tree models.Tree + if err := c.ShouldBindJSON(&tree); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + tree.GroveID = grove.ID + if err := h.db.CreateTree(c.Request.Context(), &tree); err != nil { + h.logger.Error("failed to create tree", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create tree"}) + return + } + + h.logAudit(c, "create_tree", fmt.Sprintf("%s/%s", groveName, tree.Name)) + c.JSON(http.StatusCreated, tree) +} + +func (h *Handler) ListTrees(c *gin.Context) { + groveName := c.Param("grove") + + grove, err := h.db.GetGrove(c.Request.Context(), groveName) + if err != nil || grove == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "grove not found"}) + return + } + + trees, err := h.db.ListTrees(c.Request.Context(), grove.ID) + if err != nil { + h.logger.Error("failed to list trees", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list trees"}) + return + } + + c.JSON(http.StatusOK, trees) +} + +// Fruit handlers (content-addressable storage) + +func (h *Handler) Cultivate(c *gin.Context) { + groveName := c.Param("grove") + treeName := c.Param("tree") + + grove, err := h.db.GetGrove(c.Request.Context(), groveName) + if err != nil || grove == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "grove not found"}) + return + } + + tree, err := h.db.GetTree(c.Request.Context(), grove.ID, treeName) + if err != nil || tree == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "tree not found"}) + return + } + + // Get the uploaded file + file, header, err := c.Request.FormFile("file") + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "file is required"}) + return + } + defer file.Close() + + // Store in S3 (content-addressable) + hash, size, err := h.s3.Store(c.Request.Context(), file) + if err != nil { + h.logger.Error("failed to store artifact", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to store artifact"}) + return + } + + // Create fruit record + fruit := &models.Fruit{ + ID: hash, + Size: size, + ContentType: header.Header.Get("Content-Type"), + OriginalName: header.Filename, + CreatedBy: c.GetString("user_id"), + S3Key: fmt.Sprintf("%s/%s/%s", hash[:2], hash[2:4], hash), + } + + if err := h.db.CreateFruit(c.Request.Context(), fruit); err != nil { + h.logger.Error("failed to create fruit record", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create fruit record"}) + return + } + + // Create harvest record + harvest := &models.Harvest{ + FruitID: hash, + TreeID: tree.ID, + OriginalName: header.Filename, + HarvestedBy: c.GetString("user_id"), + SourceIP: c.ClientIP(), + } + + if err := h.db.CreateHarvest(c.Request.Context(), harvest); err != nil { + h.logger.Error("failed to create harvest record", zap.Error(err)) + } + + // Optionally create a graft (tag) if specified + tag := c.PostForm("tag") + if tag != "" { + graft := &models.Graft{ + TreeID: tree.ID, + Name: tag, + FruitID: hash, + CreatedBy: c.GetString("user_id"), + } + if err := h.db.CreateGraft(c.Request.Context(), graft); err != nil { + h.logger.Error("failed to create graft", zap.Error(err)) + } + } + + h.logAudit(c, "cultivate", fmt.Sprintf("%s/%s/%s", groveName, treeName, hash)) + + c.JSON(http.StatusCreated, gin.H{ + "fruit_id": hash, + "size": size, + "grove": groveName, + "tree": treeName, + "tag": tag, + }) +} + +func (h *Handler) Harvest(c *gin.Context) { + groveName := c.Param("grove") + treeName := c.Param("tree") + ref := c.Param("ref") + + grove, err := h.db.GetGrove(c.Request.Context(), groveName) + if err != nil || grove == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "grove not found"}) + return + } + + tree, err := h.db.GetTree(c.Request.Context(), grove.ID, treeName) + if err != nil || tree == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "tree not found"}) + return + } + + // Resolve reference to fruit ID + var fruitID string + if strings.HasPrefix(ref, "fruit:") { + // Direct fruit reference + fruitID = strings.TrimPrefix(ref, "fruit:") + } else if strings.HasPrefix(ref, "version:") || strings.HasPrefix(ref, "tag:") { + // Tag/version reference + tagName := strings.TrimPrefix(ref, "version:") + tagName = strings.TrimPrefix(tagName, "tag:") + graft, err := h.db.GetGraft(c.Request.Context(), tree.ID, tagName) + if err != nil || graft == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "reference not found"}) + return + } + fruitID = graft.FruitID + } else { + // Assume it's a tag name + graft, err := h.db.GetGraft(c.Request.Context(), tree.ID, ref) + if err != nil || graft == nil { + // Maybe it's a direct fruit ID + fruit, err := h.db.GetFruit(c.Request.Context(), ref) + if err != nil || fruit == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "reference not found"}) + return + } + fruitID = ref + } else { + fruitID = graft.FruitID + } + } + + // Get fruit metadata + fruit, err := h.db.GetFruit(c.Request.Context(), fruitID) + if err != nil || fruit == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "fruit not found"}) + return + } + + // Track consumer if project URL is provided + projectURL := c.GetHeader("X-Orchard-Project") + if projectURL != "" { + h.db.TrackConsumer(c.Request.Context(), tree.ID, projectURL) + } + + // Stream content from S3 + reader, err := h.s3.Retrieve(c.Request.Context(), fruitID) + if err != nil { + h.logger.Error("failed to retrieve artifact", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to retrieve artifact"}) + return + } + defer reader.Close() + + h.logAudit(c, "harvest", fmt.Sprintf("%s/%s/%s", groveName, treeName, fruitID)) + + c.Header("Content-Type", fruit.ContentType) + c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%q", fruit.OriginalName)) + c.Header("X-Orchard-Fruit-ID", fruitID) + c.Header("X-Orchard-Size", fmt.Sprintf("%d", fruit.Size)) + + io.Copy(c.Writer, reader) +} + +func (h *Handler) GetFruit(c *gin.Context) { + fruitID := c.Param("fruit") + + fruit, err := h.db.GetFruit(c.Request.Context(), fruitID) + if err != nil { + h.logger.Error("failed to get fruit", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get fruit"}) + return + } + + if fruit == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "fruit not found"}) + return + } + + c.JSON(http.StatusOK, fruit) +} + +// Graft handlers (aliasing/tagging) + +func (h *Handler) CreateGraft(c *gin.Context) { + groveName := c.Param("grove") + treeName := c.Param("tree") + + grove, err := h.db.GetGrove(c.Request.Context(), groveName) + if err != nil || grove == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "grove not found"}) + return + } + + tree, err := h.db.GetTree(c.Request.Context(), grove.ID, treeName) + if err != nil || tree == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "tree not found"}) + return + } + + var graft models.Graft + if err := c.ShouldBindJSON(&graft); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + graft.TreeID = tree.ID + graft.CreatedBy = c.GetString("user_id") + + // Verify fruit exists + fruit, err := h.db.GetFruit(c.Request.Context(), graft.FruitID) + if err != nil || fruit == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "fruit not found"}) + return + } + + if err := h.db.CreateGraft(c.Request.Context(), &graft); err != nil { + h.logger.Error("failed to create graft", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create graft"}) + return + } + + h.logAudit(c, "create_graft", fmt.Sprintf("%s/%s/%s", groveName, treeName, graft.Name)) + c.JSON(http.StatusCreated, graft) +} + +func (h *Handler) ListGrafts(c *gin.Context) { + groveName := c.Param("grove") + treeName := c.Param("tree") + + grove, err := h.db.GetGrove(c.Request.Context(), groveName) + if err != nil || grove == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "grove not found"}) + return + } + + tree, err := h.db.GetTree(c.Request.Context(), grove.ID, treeName) + if err != nil || tree == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "tree not found"}) + return + } + + grafts, err := h.db.ListGrafts(c.Request.Context(), tree.ID) + if err != nil { + h.logger.Error("failed to list grafts", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list grafts"}) + return + } + + c.JSON(http.StatusOK, grafts) +} + +// Consumer tracking handlers + +func (h *Handler) GetConsumers(c *gin.Context) { + groveName := c.Param("grove") + treeName := c.Param("tree") + + grove, err := h.db.GetGrove(c.Request.Context(), groveName) + if err != nil || grove == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "grove not found"}) + return + } + + tree, err := h.db.GetTree(c.Request.Context(), grove.ID, treeName) + if err != nil || tree == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "tree not found"}) + return + } + + consumers, err := h.db.GetConsumers(c.Request.Context(), tree.ID) + if err != nil { + h.logger.Error("failed to get consumers", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get consumers"}) + return + } + + c.JSON(http.StatusOK, consumers) +} + +// Search handler + +func (h *Handler) Search(c *gin.Context) { + // TODO: Implement format-aware search + c.JSON(http.StatusOK, gin.H{"message": "search not yet implemented"}) +} + +// Helper to log audit events +func (h *Handler) logAudit(c *gin.Context, action, resource string) { + details, _ := json.Marshal(map[string]string{ + "method": c.Request.Method, + "path": c.Request.URL.Path, + }) + + log := &models.AuditLog{ + Action: action, + Resource: resource, + UserID: c.GetString("user_id"), + Details: string(details), + SourceIP: c.ClientIP(), + } + + if err := h.db.CreateAuditLog(c.Request.Context(), log); err != nil { + h.logger.Error("failed to create audit log", zap.Error(err)) + } +} diff --git a/internal/api/router.go b/internal/api/router.go new file mode 100644 index 0000000..8a2265b --- /dev/null +++ b/internal/api/router.go @@ -0,0 +1,153 @@ +package api + +import ( + "embed" + "io/fs" + + "github.com/bsf/orchard/internal/storage" + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +//go:embed static/* +var staticFiles embed.FS + +// SetupRouter configures all API routes +func SetupRouter(db *storage.Database, s3 *storage.S3Storage, logger *zap.Logger) *gin.Engine { + router := gin.New() + router.Use(gin.Recovery()) + router.Use(LoggerMiddleware(logger)) + + handler := NewHandler(db, s3, logger) + + // Serve static files from embedded FS + staticFS, _ := fs.Sub(staticFiles, "static") + + // Root - serve index.html + router.GET("/", func(c *gin.Context) { + data, err := fs.ReadFile(staticFS, "index.html") + if err != nil { + c.String(500, "Error loading page: "+err.Error()) + return + } + c.Data(200, "text/html; charset=utf-8", data) + }) + + // CSS file + router.GET("/static/style.css", func(c *gin.Context) { + data, err := fs.ReadFile(staticFS, "style.css") + if err != nil { + c.String(404, "Not found: "+err.Error()) + return + } + c.Data(200, "text/css; charset=utf-8", data) + }) + + // JS file + router.GET("/static/app.js", func(c *gin.Context) { + data, err := fs.ReadFile(staticFS, "app.js") + if err != nil { + c.String(404, "Not found: "+err.Error()) + return + } + c.Data(200, "application/javascript; charset=utf-8", data) + }) + + // Health check + router.GET("/health", handler.Health) + + // API v1 + v1 := router.Group("/api/v1") + { + // Authentication middleware + v1.Use(AuthMiddleware(db)) + + // Grove routes + groves := v1.Group("/groves") + { + groves.GET("", handler.ListGroves) + groves.POST("", handler.CreateGrove) + groves.GET("/:grove", handler.GetGrove) + } + + // Tree routes + trees := v1.Group("/grove/:grove/trees") + { + trees.GET("", handler.ListTrees) + trees.POST("", handler.CreateTree) + } + + // Fruit routes (content-addressable storage) + fruits := v1.Group("/grove/:grove/:tree") + { + // Upload artifact (cultivate) + fruits.POST("/cultivate", handler.Cultivate) + + // Download artifact (harvest) + fruits.GET("/+/:ref", handler.Harvest) + + // List grafts (tags/versions) + fruits.GET("/grafts", handler.ListGrafts) + + // Create graft (tag) + fruits.POST("/graft", handler.CreateGraft) + + // Get consumers + fruits.GET("/consumers", handler.GetConsumers) + } + + // Direct fruit access by hash + v1.GET("/fruit/:fruit", handler.GetFruit) + + // Search + v1.GET("/search", handler.Search) + } + + // Compatibility endpoint matching the URL pattern from spec + // /grove/{project}/{tree}/+/{ref} + router.GET("/grove/:grove/:tree/+/:ref", AuthMiddleware(db), handler.Harvest) + + return router +} + +// LoggerMiddleware logs requests +func LoggerMiddleware(logger *zap.Logger) gin.HandlerFunc { + return func(c *gin.Context) { + c.Next() + + logger.Info("request", + zap.String("method", c.Request.Method), + zap.String("path", c.Request.URL.Path), + zap.Int("status", c.Writer.Status()), + zap.String("client_ip", c.ClientIP()), + ) + } +} + +// AuthMiddleware handles authentication +func AuthMiddleware(db *storage.Database) gin.HandlerFunc { + return func(c *gin.Context) { + // Check for API key in header + apiKey := c.GetHeader("X-Orchard-API-Key") + if apiKey != "" { + // TODO: Validate API key against database + // For now, extract user ID from key + c.Set("user_id", "api-user") + c.Next() + return + } + + // Check for Bearer token + authHeader := c.GetHeader("Authorization") + if authHeader != "" { + // TODO: Implement OIDC/SAML validation + c.Set("user_id", "bearer-user") + c.Next() + return + } + + // Allow anonymous access for public groves (read only) + c.Set("user_id", "anonymous") + c.Next() + } +} diff --git a/internal/api/static/app.js b/internal/api/static/app.js new file mode 100644 index 0000000..d208d60 --- /dev/null +++ b/internal/api/static/app.js @@ -0,0 +1,573 @@ +// Orchard Web UI + +const API_BASE = '/api/v1'; + +// State +let currentGrove = null; +let currentTree = null; + +// Initialize +document.addEventListener('DOMContentLoaded', () => { + setupNavigation(); + loadGroves(); +}); + +// Navigation +function setupNavigation() { + document.querySelectorAll('.nav-link').forEach(link => { + link.addEventListener('click', (e) => { + e.preventDefault(); + const view = link.dataset.view; + showView(view); + + document.querySelectorAll('.nav-link').forEach(l => l.classList.remove('active')); + link.classList.add('active'); + }); + }); +} + +function showView(viewName) { + document.querySelectorAll('.view').forEach(v => v.classList.remove('active')); + document.getElementById(`${viewName}-view`).classList.add('active'); + + // Load data for view + if (viewName === 'groves') { + loadGroves(); + } else if (viewName === 'upload') { + loadGrovesForUpload(); + } +} + +// Groves +async function loadGroves() { + const container = document.getElementById('groves-list'); + container.innerHTML = '

'; + + try { + const response = await fetch(`${API_BASE}/groves`); + const groves = await response.json(); + + if (!groves || groves.length === 0) { + container.innerHTML = ` +
+

No groves yet

+

Create your first grove to get started

+
+ `; + return; + } + + container.innerHTML = groves.map(grove => ` +
+

+ 🌳 + ${escapeHtml(grove.name)} + + ${grove.is_public ? 'Public' : 'Private'} + +

+

${escapeHtml(grove.description || 'No description')}

+
+ Created ${formatDate(grove.created_at)} +
+
+ `).join(''); + } catch (error) { + container.innerHTML = `

Error loading groves: ${error.message}

`; + } +} + +async function viewGrove(groveName) { + currentGrove = groveName; + document.getElementById('grove-detail-title').textContent = groveName; + + // Load grove info + try { + const response = await fetch(`${API_BASE}/groves/${groveName}`); + const grove = await response.json(); + + document.getElementById('grove-info').innerHTML = ` +
+
+ + ${escapeHtml(grove.name)} +
+
+ + + ${grove.is_public ? 'Public' : 'Private'} + +
+
+ + ${formatDate(grove.created_at)} +
+
+ + ${escapeHtml(grove.description || 'No description')} +
+
+ `; + } catch (error) { + console.error('Error loading grove:', error); + } + + // Load trees + await loadTrees(groveName); + + // Show view + document.querySelectorAll('.view').forEach(v => v.classList.remove('active')); + document.getElementById('grove-detail-view').classList.add('active'); +} + +async function loadTrees(groveName) { + const container = document.getElementById('trees-list'); + container.innerHTML = '
Loading trees...
'; + + try { + const response = await fetch(`${API_BASE}/grove/${groveName}/trees`); + const trees = await response.json(); + + if (!trees || trees.length === 0) { + container.innerHTML = ` +
+

No trees yet

+

Create a tree to store artifacts

+
+ `; + return; + } + + container.innerHTML = trees.map(tree => ` +
+

+ 🌲 + ${escapeHtml(tree.name)} +

+

${escapeHtml(tree.description || 'No description')}

+
+ Created ${formatDate(tree.created_at)} +
+
+ `).join(''); + } catch (error) { + container.innerHTML = `

Error loading trees: ${error.message}

`; + } +} + +async function viewTree(groveName, treeName) { + currentGrove = groveName; + currentTree = treeName; + + document.getElementById('tree-detail-title').textContent = `${groveName} / ${treeName}`; + + document.getElementById('tree-info').innerHTML = ` +
+
+ + ${escapeHtml(groveName)} +
+
+ + ${escapeHtml(treeName)} +
+
+ `; + + // Load grafts + await loadGrafts(groveName, treeName); + + // Show view + document.querySelectorAll('.view').forEach(v => v.classList.remove('active')); + document.getElementById('tree-detail-view').classList.add('active'); +} + +async function loadGrafts(groveName, treeName) { + const container = document.getElementById('grafts-list'); + container.innerHTML = '
Loading versions...
'; + + try { + const response = await fetch(`${API_BASE}/grove/${groveName}/${treeName}/grafts`); + const grafts = await response.json(); + + if (!grafts || grafts.length === 0) { + container.innerHTML = ` +
+

No versions yet

+

Upload an artifact to create the first version

+
+ `; + return; + } + + container.innerHTML = ` + + + + + + + + + + + ${grafts.map(graft => ` + + + + + + + `).join('')} + +
TagFruit IDCreatedActions
${escapeHtml(graft.name)} + + ${graft.fruit_id.substring(0, 16)}... + + ${formatDate(graft.created_at)} + + Download + +
+ `; + } catch (error) { + container.innerHTML = `

Error loading versions: ${error.message}

`; + } +} + +function backToGrove() { + if (currentGrove) { + viewGrove(currentGrove); + } else { + showView('groves'); + } +} + +// Create Grove +function showCreateGroveModal() { + document.getElementById('create-grove-modal').classList.remove('hidden'); + document.getElementById('grove-name').focus(); +} + +async function createGrove(e) { + e.preventDefault(); + + const name = document.getElementById('grove-name').value; + const description = document.getElementById('grove-description').value; + const isPublic = document.getElementById('grove-public').checked; + + try { + const response = await fetch(`${API_BASE}/groves`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, description, is_public: isPublic }) + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.error || 'Failed to create grove'); + } + + showToast('Grove created successfully!', 'success'); + closeModals(); + loadGroves(); + + // Reset form + document.getElementById('grove-name').value = ''; + document.getElementById('grove-description').value = ''; + document.getElementById('grove-public').checked = true; + } catch (error) { + showToast(error.message, 'error'); + } +} + +// Create Tree +function showCreateTreeModal() { + document.getElementById('create-tree-modal').classList.remove('hidden'); + document.getElementById('tree-name').focus(); +} + +async function createTree(e) { + e.preventDefault(); + + const name = document.getElementById('tree-name').value; + const description = document.getElementById('tree-description').value; + + try { + const response = await fetch(`${API_BASE}/grove/${currentGrove}/trees`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, description }) + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.error || 'Failed to create tree'); + } + + showToast('Tree created successfully!', 'success'); + closeModals(); + loadTrees(currentGrove); + + // Reset form + document.getElementById('tree-name').value = ''; + document.getElementById('tree-description').value = ''; + } catch (error) { + showToast(error.message, 'error'); + } +} + +// Upload +async function loadGrovesForUpload() { + const select = document.getElementById('upload-grove'); + select.innerHTML = ''; + + try { + const response = await fetch(`${API_BASE}/groves`); + const groves = await response.json(); + + select.innerHTML = '' + + (groves || []).map(g => ``).join(''); + } catch (error) { + select.innerHTML = ''; + } +} + +async function loadTreesForUpload() { + const groveName = document.getElementById('upload-grove').value; + const select = document.getElementById('upload-tree'); + + if (!groveName) { + select.innerHTML = ''; + return; + } + + select.innerHTML = ''; + + try { + const response = await fetch(`${API_BASE}/grove/${groveName}/trees`); + const trees = await response.json(); + + select.innerHTML = '' + + (trees || []).map(t => ``).join(''); + } catch (error) { + select.innerHTML = ''; + } +} + +function updateFileName() { + const input = document.getElementById('upload-file'); + const display = document.getElementById('file-name'); + display.textContent = input.files[0]?.name || ''; +} + +async function uploadArtifact(e) { + e.preventDefault(); + + const grove = document.getElementById('upload-grove').value; + const tree = document.getElementById('upload-tree').value; + const file = document.getElementById('upload-file').files[0]; + const tag = document.getElementById('upload-tag').value; + + const formData = new FormData(); + formData.append('file', file); + if (tag) formData.append('tag', tag); + + const resultDiv = document.getElementById('upload-result'); + resultDiv.innerHTML = '
Uploading...
'; + resultDiv.classList.remove('hidden', 'success', 'error'); + + try { + const response = await fetch(`${API_BASE}/grove/${grove}/${tree}/cultivate`, { + method: 'POST', + body: formData + }); + + const result = await response.json(); + + if (!response.ok) { + throw new Error(result.error || 'Upload failed'); + } + + resultDiv.classList.add('success'); + resultDiv.innerHTML = ` +

Upload Successful!

+
+
Fruit ID
+
${result.fruit_id}
+
Size
+
${formatBytes(result.size)}
+
Grove
+
${escapeHtml(result.grove)}
+
Tree
+
${escapeHtml(result.tree)}
+ ${result.tag ? `
Tag
${escapeHtml(result.tag)}
` : ''} +
+
+ `; + + showToast('Artifact uploaded successfully!', 'success'); + } catch (error) { + resultDiv.classList.add('error'); + resultDiv.innerHTML = `

Upload Failed

${escapeHtml(error.message)}

`; + showToast(error.message, 'error'); + } +} + +async function uploadToTree(e) { + e.preventDefault(); + + const file = document.getElementById('tree-upload-file').files[0]; + const tag = document.getElementById('tree-upload-tag').value; + + const formData = new FormData(); + formData.append('file', file); + if (tag) formData.append('tag', tag); + + try { + const response = await fetch(`${API_BASE}/grove/${currentGrove}/${currentTree}/cultivate`, { + method: 'POST', + body: formData + }); + + const result = await response.json(); + + if (!response.ok) { + throw new Error(result.error || 'Upload failed'); + } + + showToast('Artifact uploaded successfully!', 'success'); + + // Reload grafts + loadGrafts(currentGrove, currentTree); + + // Reset form + document.getElementById('tree-upload-file').value = ''; + document.getElementById('tree-upload-tag').value = ''; + } catch (error) { + showToast(error.message, 'error'); + } +} + +// Search +function handleSearchKeyup(e) { + if (e.key === 'Enter') { + searchFruit(); + } +} + +async function searchFruit() { + const fruitId = document.getElementById('search-input').value.trim(); + const resultDiv = document.getElementById('search-result'); + + if (!fruitId) { + showToast('Please enter a fruit ID', 'error'); + return; + } + + resultDiv.innerHTML = '
Searching...
'; + resultDiv.classList.remove('hidden', 'success', 'error'); + + try { + const response = await fetch(`${API_BASE}/fruit/${fruitId}`); + const result = await response.json(); + + if (!response.ok) { + throw new Error(result.error || 'Fruit not found'); + } + + resultDiv.classList.add('success'); + resultDiv.innerHTML = ` +

Fruit Found

+
+
Fruit ID
+
${result.id}
+
Original Name
+
${escapeHtml(result.original_name || 'Unknown')}
+
Size
+
${formatBytes(result.size)}
+
Content Type
+
${escapeHtml(result.content_type || 'Unknown')}
+
Created
+
${formatDate(result.created_at)}
+
Reference Count
+
${result.ref_count}
+
+ `; + } catch (error) { + resultDiv.classList.add('error'); + resultDiv.innerHTML = `

Not Found

${escapeHtml(error.message)}

`; + } +} + +// Modals +function closeModals() { + document.querySelectorAll('.modal').forEach(m => m.classList.add('hidden')); +} + +// Close modal on outside click +document.addEventListener('click', (e) => { + if (e.target.classList.contains('modal')) { + closeModals(); + } +}); + +// Close modal on Escape +document.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + closeModals(); + } +}); + +// Toast notifications +function showToast(message, type = 'info') { + const container = document.getElementById('toast-container'); + const toast = document.createElement('div'); + toast.className = `toast ${type}`; + toast.textContent = message; + container.appendChild(toast); + + setTimeout(() => { + toast.remove(); + }, 3000); +} + +// Utilities +function escapeHtml(str) { + if (!str) return ''; + const div = document.createElement('div'); + div.textContent = str; + return div.innerHTML; +} + +function formatDate(dateStr) { + if (!dateStr) return 'Unknown'; + const date = new Date(dateStr); + return date.toLocaleDateString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }); +} + +function formatBytes(bytes) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; +} + +function copyToClipboard(text) { + navigator.clipboard.writeText(text).then(() => { + showToast('Copied to clipboard!', 'success'); + }); +} diff --git a/internal/api/static/index.html b/internal/api/static/index.html new file mode 100644 index 0000000..6c3ab5b --- /dev/null +++ b/internal/api/static/index.html @@ -0,0 +1,183 @@ + + + + + + Orchard - Content Addressable Storage + + + + + +
+ +
+
+

Groves

+ +
+
+
Loading groves...
+
+
+ + +
+
+ +

Grove

+
+
+
+
+

Trees

+ +
+
+
+
+ + +
+
+ +

Tree

+
+
+
+
+

Versions (Grafts)

+
+
+
+
+

Upload Artifact

+
+
+ + +
+
+ + +
+ +
+
+
+ + +
+

Upload Artifact

+
+
+
+ + +
+
+ + +
+
+
+ +
+ +

Drop file here or click to browse

+ +
+
+
+ + +
+ +
+ +
+ + +
+

Search Artifacts

+ + +
+
+ + + + + + + + +
+ + + + diff --git a/internal/api/static/style.css b/internal/api/static/style.css new file mode 100644 index 0000000..21889de --- /dev/null +++ b/internal/api/static/style.css @@ -0,0 +1,603 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + --primary: #059669; + --primary-dark: #047857; + --primary-light: #10b981; + --secondary: #6b7280; + --background: #f3f4f6; + --surface: #ffffff; + --text: #1f2937; + --text-light: #6b7280; + --border: #e5e7eb; + --success: #10b981; + --error: #ef4444; + --warning: #f59e0b; + --radius: 8px; + --shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06); + --shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05); +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; + background: var(--background); + color: var(--text); + line-height: 1.6; +} + +/* Navbar */ +.navbar { + background: var(--surface); + border-bottom: 1px solid var(--border); + padding: 0 2rem; + height: 60px; + display: flex; + align-items: center; + justify-content: space-between; + position: sticky; + top: 0; + z-index: 100; +} + +.nav-brand { + font-size: 1.5rem; + font-weight: 700; + color: var(--primary); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.logo { + font-size: 1.75rem; +} + +.nav-links { + display: flex; + gap: 0.5rem; +} + +.nav-link { + padding: 0.5rem 1rem; + text-decoration: none; + color: var(--text-light); + border-radius: var(--radius); + transition: all 0.2s; +} + +.nav-link:hover { + background: var(--background); + color: var(--text); +} + +.nav-link.active { + background: var(--primary); + color: white; +} + +/* Container */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 2rem; +} + +/* Views */ +.view { + display: none; +} + +.view.active { + display: block; +} + +.view-header { + display: flex; + align-items: center; + gap: 1rem; + margin-bottom: 1.5rem; +} + +.view-header h1 { + flex: 1; +} + +/* Cards */ +.card { + background: var(--surface); + border-radius: var(--radius); + border: 1px solid var(--border); + padding: 1.5rem; + box-shadow: var(--shadow); +} + +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 1rem; +} + +.grove-card, .tree-card { + background: var(--surface); + border-radius: var(--radius); + border: 1px solid var(--border); + padding: 1.25rem; + cursor: pointer; + transition: all 0.2s; +} + +.grove-card:hover, .tree-card:hover { + border-color: var(--primary); + box-shadow: var(--shadow-lg); + transform: translateY(-2px); +} + +.grove-card h3, .tree-card h3 { + color: var(--primary); + margin-bottom: 0.5rem; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.grove-card p, .tree-card p { + color: var(--text-light); + font-size: 0.9rem; +} + +.grove-card .meta, .tree-card .meta { + margin-top: 1rem; + padding-top: 1rem; + border-top: 1px solid var(--border); + font-size: 0.8rem; + color: var(--text-light); +} + +.badge { + display: inline-block; + padding: 0.2rem 0.5rem; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 500; +} + +.badge-public { + background: #d1fae5; + color: #065f46; +} + +.badge-private { + background: #fef3c7; + color: #92400e; +} + +/* Sections */ +.section { + margin-top: 2rem; +} + +.section-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 1rem; +} + +.section-header h2 { + font-size: 1.25rem; +} + +/* Buttons */ +.btn { + padding: 0.5rem 1rem; + border-radius: var(--radius); + border: none; + font-size: 0.9rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; + display: inline-flex; + align-items: center; + gap: 0.5rem; +} + +.btn-primary { + background: var(--primary); + color: white; +} + +.btn-primary:hover { + background: var(--primary-dark); +} + +.btn-secondary { + background: var(--background); + color: var(--text); + border: 1px solid var(--border); +} + +.btn-secondary:hover { + background: var(--border); +} + +.btn-lg { + padding: 0.75rem 1.5rem; + font-size: 1rem; +} + +/* Forms */ +.form-group { + margin-bottom: 1rem; +} + +.form-group label { + display: block; + margin-bottom: 0.5rem; + font-weight: 500; + color: var(--text); +} + +.form-group input[type="text"], +.form-group input[type="email"], +.form-group textarea, +.form-group select { + width: 100%; + padding: 0.75rem; + border: 1px solid var(--border); + border-radius: var(--radius); + font-size: 1rem; + transition: border-color 0.2s; +} + +.form-group input:focus, +.form-group textarea:focus, +.form-group select:focus { + outline: none; + border-color: var(--primary); +} + +.form-group textarea { + min-height: 100px; + resize: vertical; +} + +.form-group.checkbox label { + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; +} + +/* File Drop */ +.file-drop { + border: 2px dashed var(--border); + border-radius: var(--radius); + padding: 2rem; + text-align: center; + cursor: pointer; + transition: all 0.2s; + position: relative; +} + +.file-drop:hover { + border-color: var(--primary); + background: #f0fdf4; +} + +.file-drop input[type="file"] { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; +} + +.file-drop p { + color: var(--text-light); + margin-bottom: 0.5rem; +} + +#file-name { + color: var(--primary); + font-weight: 500; +} + +/* Upload Form */ +.upload-form { + max-width: 600px; +} + +.upload-form.card { + padding: 2rem; +} + +/* Tables */ +.table-container { + overflow-x: auto; +} + +table { + width: 100%; + border-collapse: collapse; + background: var(--surface); + border-radius: var(--radius); + overflow: hidden; +} + +th, td { + padding: 0.75rem 1rem; + text-align: left; + border-bottom: 1px solid var(--border); +} + +th { + background: var(--background); + font-weight: 600; + color: var(--text-light); + font-size: 0.85rem; + text-transform: uppercase; +} + +tr:hover { + background: #f9fafb; +} + +.hash { + font-family: 'Monaco', 'Menlo', monospace; + font-size: 0.85rem; + color: var(--text-light); +} + +.hash-short { + cursor: pointer; +} + +.hash-short:hover { + color: var(--primary); +} + +/* Search */ +.search-box { + display: flex; + gap: 1rem; + max-width: 600px; + margin-bottom: 2rem; +} + +.search-box input { + flex: 1; + padding: 0.75rem 1rem; + border: 1px solid var(--border); + border-radius: var(--radius); + font-size: 1rem; +} + +.search-box input:focus { + outline: none; + border-color: var(--primary); +} + +/* Result Card */ +.result-card { + background: var(--surface); + border-radius: var(--radius); + border: 1px solid var(--border); + padding: 1.5rem; + margin-top: 1.5rem; + max-width: 600px; +} + +.result-card.success { + border-color: var(--success); + background: #f0fdf4; +} + +.result-card.error { + border-color: var(--error); + background: #fef2f2; +} + +.result-card h3 { + margin-bottom: 1rem; +} + +.result-card dl { + display: grid; + grid-template-columns: 150px 1fr; + gap: 0.5rem; +} + +.result-card dt { + font-weight: 500; + color: var(--text-light); +} + +.result-card dd { + word-break: break-all; +} + +.result-card .actions { + margin-top: 1rem; + padding-top: 1rem; + border-top: 1px solid var(--border); +} + +/* Modal */ +.modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.modal.hidden { + display: none; +} + +.modal-content { + background: var(--surface); + border-radius: var(--radius); + width: 100%; + max-width: 500px; + max-height: 90vh; + overflow-y: auto; +} + +.modal-header { + padding: 1rem 1.5rem; + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + justify-content: space-between; +} + +.modal-header h2 { + font-size: 1.25rem; +} + +.modal-close { + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: var(--text-light); +} + +.modal-close:hover { + color: var(--text); +} + +.modal-content form { + padding: 1.5rem; +} + +.modal-actions { + display: flex; + justify-content: flex-end; + gap: 0.5rem; + margin-top: 1.5rem; +} + +/* Info boxes */ +.grove-info, .tree-info { + background: var(--surface); + border-radius: var(--radius); + border: 1px solid var(--border); + padding: 1rem 1.5rem; + margin-bottom: 1rem; +} + +.info-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1rem; +} + +.info-item label { + display: block; + font-size: 0.8rem; + color: var(--text-light); + margin-bottom: 0.25rem; +} + +.info-item span { + font-weight: 500; +} + +/* Toast */ +#toast-container { + position: fixed; + bottom: 2rem; + right: 2rem; + z-index: 2000; +} + +.toast { + background: var(--text); + color: white; + padding: 1rem 1.5rem; + border-radius: var(--radius); + margin-top: 0.5rem; + box-shadow: var(--shadow-lg); + animation: slideIn 0.3s ease; +} + +.toast.success { + background: var(--success); +} + +.toast.error { + background: var(--error); +} + +@keyframes slideIn { + from { + transform: translateX(100%); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } +} + +/* Loading */ +.loading { + text-align: center; + padding: 2rem; + color: var(--text-light); +} + +/* Hidden */ +.hidden { + display: none !important; +} + +/* Empty State */ +.empty-state { + text-align: center; + padding: 3rem; + color: var(--text-light); +} + +.empty-state h3 { + margin-bottom: 0.5rem; + color: var(--text); +} + +/* Responsive */ +@media (max-width: 768px) { + .navbar { + padding: 0 1rem; + } + + .container { + padding: 1rem; + } + + .form-row { + grid-template-columns: 1fr; + } + + .card-grid { + grid-template-columns: 1fr; + } +} diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..83cd0d0 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,104 @@ +package config + +import ( + "strings" + + "github.com/spf13/viper" +) + +type Config struct { + Server ServerConfig `mapstructure:"server"` + Database DatabaseConfig `mapstructure:"database"` + S3 S3Config `mapstructure:"s3"` + Redis RedisConfig `mapstructure:"redis"` +} + +type ServerConfig struct { + Host string `mapstructure:"host"` + Port int `mapstructure:"port"` +} + +type DatabaseConfig struct { + Host string `mapstructure:"host"` + Port int `mapstructure:"port"` + User string `mapstructure:"user"` + Password string `mapstructure:"password"` + DBName string `mapstructure:"dbname"` + SSLMode string `mapstructure:"sslmode"` +} + +type S3Config struct { + Endpoint string `mapstructure:"endpoint"` + Region string `mapstructure:"region"` + Bucket string `mapstructure:"bucket"` + AccessKeyID string `mapstructure:"access_key_id"` + SecretAccessKey string `mapstructure:"secret_access_key"` + UsePathStyle bool `mapstructure:"use_path_style"` +} + +type RedisConfig struct { + Host string `mapstructure:"host"` + Port int `mapstructure:"port"` + Password string `mapstructure:"password"` + DB int `mapstructure:"db"` +} + +func Load() (*Config, error) { + viper.SetConfigName("config") + viper.SetConfigType("yaml") + viper.AddConfigPath(".") + viper.AddConfigPath("/etc/orchard") + + // Environment variable overrides + viper.SetEnvPrefix("ORCHARD") + viper.AutomaticEnv() + viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + + // Bind environment variables explicitly for nested config + viper.BindEnv("server.host", "ORCHARD_SERVER_HOST") + viper.BindEnv("server.port", "ORCHARD_SERVER_PORT") + viper.BindEnv("database.host", "ORCHARD_DATABASE_HOST") + viper.BindEnv("database.port", "ORCHARD_DATABASE_PORT") + viper.BindEnv("database.user", "ORCHARD_DATABASE_USER") + viper.BindEnv("database.password", "ORCHARD_DATABASE_PASSWORD") + viper.BindEnv("database.dbname", "ORCHARD_DATABASE_DBNAME") + viper.BindEnv("database.sslmode", "ORCHARD_DATABASE_SSLMODE") + viper.BindEnv("s3.endpoint", "ORCHARD_S3_ENDPOINT") + viper.BindEnv("s3.region", "ORCHARD_S3_REGION") + viper.BindEnv("s3.bucket", "ORCHARD_S3_BUCKET") + viper.BindEnv("s3.access_key_id", "ORCHARD_S3_ACCESS_KEY_ID") + viper.BindEnv("s3.secret_access_key", "ORCHARD_S3_SECRET_ACCESS_KEY") + viper.BindEnv("s3.use_path_style", "ORCHARD_S3_USE_PATH_STYLE") + viper.BindEnv("redis.host", "ORCHARD_REDIS_HOST") + viper.BindEnv("redis.port", "ORCHARD_REDIS_PORT") + viper.BindEnv("redis.password", "ORCHARD_REDIS_PASSWORD") + viper.BindEnv("redis.db", "ORCHARD_REDIS_DB") + + // Defaults + viper.SetDefault("server.host", "0.0.0.0") + viper.SetDefault("server.port", 8080) + viper.SetDefault("database.host", "localhost") + viper.SetDefault("database.port", 5432) + viper.SetDefault("database.user", "orchard") + viper.SetDefault("database.dbname", "orchard") + viper.SetDefault("database.sslmode", "disable") + viper.SetDefault("s3.region", "us-east-1") + viper.SetDefault("s3.bucket", "orchard-artifacts") + viper.SetDefault("s3.use_path_style", true) + viper.SetDefault("redis.host", "localhost") + viper.SetDefault("redis.port", 6379) + viper.SetDefault("redis.db", 0) + + if err := viper.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); !ok { + return nil, err + } + } + + var cfg Config + if err := viper.Unmarshal(&cfg); err != nil { + return nil, err + } + + return &cfg, nil +} diff --git a/internal/models/models.go b/internal/models/models.go new file mode 100644 index 0000000..4305762 --- /dev/null +++ b/internal/models/models.go @@ -0,0 +1,110 @@ +package models + +import ( + "time" +) + +// Fruit represents a content-addressable artifact identified by SHA256 hash +type Fruit struct { + ID string `json:"id" db:"id"` // SHA256 hash + Size int64 `json:"size" db:"size"` // Size in bytes + ContentType string `json:"content_type" db:"content_type"` // MIME type + OriginalName string `json:"original_name" db:"original_name"` // Original filename + CreatedAt time.Time `json:"created_at" db:"created_at"` + CreatedBy string `json:"created_by" db:"created_by"` // Harvester ID + RefCount int `json:"ref_count" db:"ref_count"` // Reference count + S3Key string `json:"-" db:"s3_key"` // S3 object key +} + +// Tree represents a named package within a grove +type Tree struct { + ID string `json:"id" db:"id"` + GroveID string `json:"grove_id" db:"grove_id"` + Name string `json:"name" db:"name"` + Description string `json:"description" db:"description"` + CreatedAt time.Time `json:"created_at" db:"created_at"` + UpdatedAt time.Time `json:"updated_at" db:"updated_at"` +} + +// Grove represents a top-level project +type Grove struct { + ID string `json:"id" db:"id"` + Name string `json:"name" db:"name"` + Description string `json:"description" db:"description"` + IsPublic bool `json:"is_public" db:"is_public"` + CreatedAt time.Time `json:"created_at" db:"created_at"` + UpdatedAt time.Time `json:"updated_at" db:"updated_at"` + CreatedBy string `json:"created_by" db:"created_by"` +} + +// Graft represents an alias/tag pointing to a specific fruit +type Graft struct { + ID string `json:"id" db:"id"` + TreeID string `json:"tree_id" db:"tree_id"` + Name string `json:"name" db:"name"` // e.g., "latest", "v1.2.3", "stable" + FruitID string `json:"fruit_id" db:"fruit_id"` // SHA256 of the fruit + CreatedAt time.Time `json:"created_at" db:"created_at"` + CreatedBy string `json:"created_by" db:"created_by"` +} + +// GraftHistory tracks changes to grafts for rollback capability +type GraftHistory struct { + ID string `json:"id" db:"id"` + GraftID string `json:"graft_id" db:"graft_id"` + OldFruitID string `json:"old_fruit_id" db:"old_fruit_id"` + NewFruitID string `json:"new_fruit_id" db:"new_fruit_id"` + ChangedAt time.Time `json:"changed_at" db:"changed_at"` + ChangedBy string `json:"changed_by" db:"changed_by"` +} + +// Harvest represents metadata about an upload event +type Harvest struct { + ID string `json:"id" db:"id"` + FruitID string `json:"fruit_id" db:"fruit_id"` + TreeID string `json:"tree_id" db:"tree_id"` + OriginalName string `json:"original_name" db:"original_name"` + HarvestedAt time.Time `json:"harvested_at" db:"harvested_at"` + HarvestedBy string `json:"harvested_by" db:"harvested_by"` + SourceIP string `json:"source_ip" db:"source_ip"` +} + +// Consumer tracks which projects consume specific packages +type Consumer struct { + ID string `json:"id" db:"id"` + TreeID string `json:"tree_id" db:"tree_id"` + ProjectURL string `json:"project_url" db:"project_url"` + LastAccess time.Time `json:"last_access" db:"last_access"` + CreatedAt time.Time `json:"created_at" db:"created_at"` +} + +// AccessPermission defines grove-level access control +type AccessPermission struct { + ID string `json:"id" db:"id"` + GroveID string `json:"grove_id" db:"grove_id"` + UserID string `json:"user_id" db:"user_id"` + Level string `json:"level" db:"level"` // read, write, admin + CreatedAt time.Time `json:"created_at" db:"created_at"` + ExpiresAt *time.Time `json:"expires_at,omitempty" db:"expires_at"` +} + +// AuditLog tracks all operations for compliance +type AuditLog struct { + ID string `json:"id" db:"id"` + Action string `json:"action" db:"action"` + Resource string `json:"resource" db:"resource"` + UserID string `json:"user_id" db:"user_id"` + Details string `json:"details" db:"details"` // JSON blob + Timestamp time.Time `json:"timestamp" db:"timestamp"` + SourceIP string `json:"source_ip" db:"source_ip"` +} + +// APIKey for programmatic access +type APIKey struct { + ID string `json:"id" db:"id"` + KeyHash string `json:"-" db:"key_hash"` // Hashed API key + Name string `json:"name" db:"name"` + UserID string `json:"user_id" db:"user_id"` + CreatedAt time.Time `json:"created_at" db:"created_at"` + ExpiresAt *time.Time `json:"expires_at,omitempty" db:"expires_at"` + LastUsed *time.Time `json:"last_used,omitempty" db:"last_used"` +} diff --git a/internal/storage/database.go b/internal/storage/database.go new file mode 100644 index 0000000..1ee0424 --- /dev/null +++ b/internal/storage/database.go @@ -0,0 +1,346 @@ +package storage + +import ( + "context" + "database/sql" + "fmt" + "time" + + "github.com/bsf/orchard/internal/config" + "github.com/bsf/orchard/internal/models" + "github.com/google/uuid" + _ "github.com/lib/pq" +) + +// Database handles all database operations +type Database struct { + db *sql.DB +} + +// NewDatabase creates a new database connection +func NewDatabase(cfg *config.DatabaseConfig) (*Database, error) { + dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", + cfg.Host, cfg.Port, cfg.User, cfg.Password, cfg.DBName, cfg.SSLMode) + + db, err := sql.Open("postgres", dsn) + if err != nil { + return nil, fmt.Errorf("failed to connect to database: %w", err) + } + + if err := db.Ping(); err != nil { + return nil, fmt.Errorf("failed to ping database: %w", err) + } + + return &Database{db: db}, nil +} + +// Close closes the database connection +func (d *Database) Close() error { + return d.db.Close() +} + +// Grove operations + +func (d *Database) CreateGrove(ctx context.Context, grove *models.Grove) error { + grove.ID = uuid.New().String() + grove.CreatedAt = time.Now() + grove.UpdatedAt = grove.CreatedAt + + _, err := d.db.ExecContext(ctx, ` + INSERT INTO groves (id, name, description, is_public, created_at, updated_at, created_by) + VALUES ($1, $2, $3, $4, $5, $6, $7) + `, grove.ID, grove.Name, grove.Description, grove.IsPublic, grove.CreatedAt, grove.UpdatedAt, grove.CreatedBy) + + return err +} + +func (d *Database) GetGrove(ctx context.Context, name string) (*models.Grove, error) { + var grove models.Grove + err := d.db.QueryRowContext(ctx, ` + SELECT id, name, description, is_public, created_at, updated_at, created_by + FROM groves WHERE name = $1 + `, name).Scan(&grove.ID, &grove.Name, &grove.Description, &grove.IsPublic, + &grove.CreatedAt, &grove.UpdatedAt, &grove.CreatedBy) + + if err == sql.ErrNoRows { + return nil, nil + } + return &grove, err +} + +func (d *Database) ListGroves(ctx context.Context, userID string) ([]*models.Grove, error) { + rows, err := d.db.QueryContext(ctx, ` + SELECT g.id, g.name, g.description, g.is_public, g.created_at, g.updated_at, g.created_by + FROM groves g + LEFT JOIN access_permissions ap ON g.id = ap.grove_id AND ap.user_id = $1 + WHERE g.is_public = true OR ap.user_id IS NOT NULL + ORDER BY g.name + `, userID) + if err != nil { + return nil, err + } + defer rows.Close() + + var groves []*models.Grove + for rows.Next() { + var grove models.Grove + if err := rows.Scan(&grove.ID, &grove.Name, &grove.Description, &grove.IsPublic, + &grove.CreatedAt, &grove.UpdatedAt, &grove.CreatedBy); err != nil { + return nil, err + } + groves = append(groves, &grove) + } + return groves, nil +} + +// Tree operations + +func (d *Database) CreateTree(ctx context.Context, tree *models.Tree) error { + tree.ID = uuid.New().String() + tree.CreatedAt = time.Now() + tree.UpdatedAt = tree.CreatedAt + + _, err := d.db.ExecContext(ctx, ` + INSERT INTO trees (id, grove_id, name, description, created_at, updated_at) + VALUES ($1, $2, $3, $4, $5, $6) + `, tree.ID, tree.GroveID, tree.Name, tree.Description, tree.CreatedAt, tree.UpdatedAt) + + return err +} + +func (d *Database) GetTree(ctx context.Context, groveID, name string) (*models.Tree, error) { + var tree models.Tree + err := d.db.QueryRowContext(ctx, ` + SELECT id, grove_id, name, description, created_at, updated_at + FROM trees WHERE grove_id = $1 AND name = $2 + `, groveID, name).Scan(&tree.ID, &tree.GroveID, &tree.Name, &tree.Description, + &tree.CreatedAt, &tree.UpdatedAt) + + if err == sql.ErrNoRows { + return nil, nil + } + return &tree, err +} + +func (d *Database) ListTrees(ctx context.Context, groveID string) ([]*models.Tree, error) { + rows, err := d.db.QueryContext(ctx, ` + SELECT id, grove_id, name, description, created_at, updated_at + FROM trees WHERE grove_id = $1 + ORDER BY name + `, groveID) + if err != nil { + return nil, err + } + defer rows.Close() + + var trees []*models.Tree + for rows.Next() { + var tree models.Tree + if err := rows.Scan(&tree.ID, &tree.GroveID, &tree.Name, &tree.Description, + &tree.CreatedAt, &tree.UpdatedAt); err != nil { + return nil, err + } + trees = append(trees, &tree) + } + return trees, nil +} + +// Fruit operations + +func (d *Database) CreateFruit(ctx context.Context, fruit *models.Fruit) error { + fruit.CreatedAt = time.Now() + fruit.RefCount = 1 + + _, err := d.db.ExecContext(ctx, ` + INSERT INTO fruits (id, size, content_type, original_name, created_at, created_by, ref_count, s3_key) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (id) DO UPDATE SET ref_count = fruits.ref_count + 1 + `, fruit.ID, fruit.Size, fruit.ContentType, fruit.OriginalName, + fruit.CreatedAt, fruit.CreatedBy, fruit.RefCount, fruit.S3Key) + + return err +} + +func (d *Database) GetFruit(ctx context.Context, id string) (*models.Fruit, error) { + var fruit models.Fruit + err := d.db.QueryRowContext(ctx, ` + SELECT id, size, content_type, original_name, created_at, created_by, ref_count, s3_key + FROM fruits WHERE id = $1 + `, id).Scan(&fruit.ID, &fruit.Size, &fruit.ContentType, &fruit.OriginalName, + &fruit.CreatedAt, &fruit.CreatedBy, &fruit.RefCount, &fruit.S3Key) + + if err == sql.ErrNoRows { + return nil, nil + } + return &fruit, err +} + +// Graft operations + +func (d *Database) CreateGraft(ctx context.Context, graft *models.Graft) error { + graft.ID = uuid.New().String() + graft.CreatedAt = time.Now() + + _, err := d.db.ExecContext(ctx, ` + INSERT INTO grafts (id, tree_id, name, fruit_id, created_at, created_by) + VALUES ($1, $2, $3, $4, $5, $6) + ON CONFLICT (tree_id, name) DO UPDATE SET fruit_id = $4, created_at = $5, created_by = $6 + `, graft.ID, graft.TreeID, graft.Name, graft.FruitID, graft.CreatedAt, graft.CreatedBy) + + return err +} + +func (d *Database) GetGraft(ctx context.Context, treeID, name string) (*models.Graft, error) { + var graft models.Graft + err := d.db.QueryRowContext(ctx, ` + SELECT id, tree_id, name, fruit_id, created_at, created_by + FROM grafts WHERE tree_id = $1 AND name = $2 + `, treeID, name).Scan(&graft.ID, &graft.TreeID, &graft.Name, &graft.FruitID, + &graft.CreatedAt, &graft.CreatedBy) + + if err == sql.ErrNoRows { + return nil, nil + } + return &graft, err +} + +func (d *Database) ListGrafts(ctx context.Context, treeID string) ([]*models.Graft, error) { + rows, err := d.db.QueryContext(ctx, ` + SELECT id, tree_id, name, fruit_id, created_at, created_by + FROM grafts WHERE tree_id = $1 + ORDER BY name + `, treeID) + if err != nil { + return nil, err + } + defer rows.Close() + + var grafts []*models.Graft + for rows.Next() { + var graft models.Graft + if err := rows.Scan(&graft.ID, &graft.TreeID, &graft.Name, &graft.FruitID, + &graft.CreatedAt, &graft.CreatedBy); err != nil { + return nil, err + } + grafts = append(grafts, &graft) + } + return grafts, nil +} + +// Harvest operations + +func (d *Database) CreateHarvest(ctx context.Context, harvest *models.Harvest) error { + harvest.ID = uuid.New().String() + harvest.HarvestedAt = time.Now() + + _, err := d.db.ExecContext(ctx, ` + INSERT INTO harvests (id, fruit_id, tree_id, original_name, harvested_at, harvested_by, source_ip) + VALUES ($1, $2, $3, $4, $5, $6, $7) + `, harvest.ID, harvest.FruitID, harvest.TreeID, harvest.OriginalName, + harvest.HarvestedAt, harvest.HarvestedBy, harvest.SourceIP) + + return err +} + +// Audit operations + +func (d *Database) CreateAuditLog(ctx context.Context, log *models.AuditLog) error { + log.ID = uuid.New().String() + log.Timestamp = time.Now() + + _, err := d.db.ExecContext(ctx, ` + INSERT INTO audit_logs (id, action, resource, user_id, details, timestamp, source_ip) + VALUES ($1, $2, $3, $4, $5, $6, $7) + `, log.ID, log.Action, log.Resource, log.UserID, log.Details, log.Timestamp, log.SourceIP) + + return err +} + +// Access control operations + +func (d *Database) CheckAccess(ctx context.Context, groveID, userID, requiredLevel string) (bool, error) { + // Check if grove is public (read access for everyone) + var isPublic bool + err := d.db.QueryRowContext(ctx, `SELECT is_public FROM groves WHERE id = $1`, groveID).Scan(&isPublic) + if err != nil { + return false, err + } + + if isPublic && requiredLevel == "read" { + return true, nil + } + + // Check user-specific permissions + var level string + err = d.db.QueryRowContext(ctx, ` + SELECT level FROM access_permissions + WHERE grove_id = $1 AND user_id = $2 AND (expires_at IS NULL OR expires_at > NOW()) + `, groveID, userID).Scan(&level) + + if err == sql.ErrNoRows { + return false, nil + } + if err != nil { + return false, err + } + + // Check permission hierarchy: admin > write > read + switch requiredLevel { + case "read": + return true, nil + case "write": + return level == "write" || level == "admin", nil + case "admin": + return level == "admin", nil + } + + return false, nil +} + +func (d *Database) GrantAccess(ctx context.Context, perm *models.AccessPermission) error { + perm.ID = uuid.New().String() + perm.CreatedAt = time.Now() + + _, err := d.db.ExecContext(ctx, ` + INSERT INTO access_permissions (id, grove_id, user_id, level, created_at, expires_at) + VALUES ($1, $2, $3, $4, $5, $6) + ON CONFLICT (grove_id, user_id) DO UPDATE SET level = $4, expires_at = $6 + `, perm.ID, perm.GroveID, perm.UserID, perm.Level, perm.CreatedAt, perm.ExpiresAt) + + return err +} + +// Consumer tracking + +func (d *Database) TrackConsumer(ctx context.Context, treeID, projectURL string) error { + _, err := d.db.ExecContext(ctx, ` + INSERT INTO consumers (id, tree_id, project_url, last_access, created_at) + VALUES ($1, $2, $3, NOW(), NOW()) + ON CONFLICT (tree_id, project_url) DO UPDATE SET last_access = NOW() + `, uuid.New().String(), treeID, projectURL) + + return err +} + +func (d *Database) GetConsumers(ctx context.Context, treeID string) ([]*models.Consumer, error) { + rows, err := d.db.QueryContext(ctx, ` + SELECT id, tree_id, project_url, last_access, created_at + FROM consumers WHERE tree_id = $1 + ORDER BY last_access DESC + `, treeID) + if err != nil { + return nil, err + } + defer rows.Close() + + var consumers []*models.Consumer + for rows.Next() { + var consumer models.Consumer + if err := rows.Scan(&consumer.ID, &consumer.TreeID, &consumer.ProjectURL, + &consumer.LastAccess, &consumer.CreatedAt); err != nil { + return nil, err + } + consumers = append(consumers, &consumer) + } + return consumers, nil +} diff --git a/internal/storage/s3.go b/internal/storage/s3.go new file mode 100644 index 0000000..b13042b --- /dev/null +++ b/internal/storage/s3.go @@ -0,0 +1,158 @@ +package storage + +import ( + "bytes" + "context" + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/s3" + orchardconfig "github.com/bsf/orchard/internal/config" +) + +// S3Storage implements content-addressable storage using S3 +type S3Storage struct { + client *s3.Client + bucket string +} + +// NewS3Storage creates a new S3 storage backend +func NewS3Storage(cfg *orchardconfig.S3Config) (*S3Storage, error) { + customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) { + if cfg.Endpoint != "" { + return aws.Endpoint{ + URL: cfg.Endpoint, + HostnameImmutable: true, + }, nil + } + return aws.Endpoint{}, &aws.EndpointNotFoundError{} + }) + + awsCfg, err := config.LoadDefaultConfig(context.Background(), + config.WithRegion(cfg.Region), + config.WithEndpointResolverWithOptions(customResolver), + config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider( + cfg.AccessKeyID, + cfg.SecretAccessKey, + "", + )), + ) + if err != nil { + return nil, fmt.Errorf("failed to load AWS config: %w", err) + } + + client := s3.NewFromConfig(awsCfg, func(o *s3.Options) { + o.UsePathStyle = cfg.UsePathStyle + }) + + return &S3Storage{ + client: client, + bucket: cfg.Bucket, + }, nil +} + +// hashToKey converts a SHA256 hash to an S3 object key +// Uses directory structure: ab/cd/abcdef123... +func hashToKey(hash string) string { + if len(hash) < 4 { + return hash + } + return fmt.Sprintf("%s/%s/%s", hash[:2], hash[2:4], hash) +} + +// Store uploads content to S3 and returns the SHA256 hash +func (s *S3Storage) Store(ctx context.Context, reader io.Reader) (string, int64, error) { + // Read all content into memory to compute hash and enable seeking + data, err := io.ReadAll(reader) + if err != nil { + return "", 0, fmt.Errorf("failed to read content: %w", err) + } + + size := int64(len(data)) + + // Compute SHA256 hash + hasher := sha256.New() + hasher.Write(data) + hash := hex.EncodeToString(hasher.Sum(nil)) + finalKey := hashToKey(hash) + + // Check if object already exists (deduplication) + _, err = s.client.HeadObject(ctx, &s3.HeadObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(finalKey), + }) + if err == nil { + // Object already exists, return existing hash (deduplication) + return hash, size, nil + } + + // Upload to final location + _, err = s.client.PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(finalKey), + Body: bytes.NewReader(data), + ContentLength: aws.Int64(size), + }) + if err != nil { + return "", 0, fmt.Errorf("failed to upload to S3: %w", err) + } + + return hash, size, nil +} + +// Retrieve downloads content by SHA256 hash +func (s *S3Storage) Retrieve(ctx context.Context, hash string) (io.ReadCloser, error) { + key := hashToKey(hash) + + result, err := s.client.GetObject(ctx, &s3.GetObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(key), + }) + if err != nil { + return nil, fmt.Errorf("failed to retrieve object: %w", err) + } + + return result.Body, nil +} + +// Exists checks if a fruit exists by hash +func (s *S3Storage) Exists(ctx context.Context, hash string) (bool, error) { + key := hashToKey(hash) + + _, err := s.client.HeadObject(ctx, &s3.HeadObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(key), + }) + if err != nil { + return false, nil + } + return true, nil +} + +// GetSize returns the size of a stored object +func (s *S3Storage) GetSize(ctx context.Context, hash string) (int64, error) { + key := hashToKey(hash) + + result, err := s.client.HeadObject(ctx, &s3.HeadObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(key), + }) + if err != nil { + return 0, fmt.Errorf("failed to get object metadata: %w", err) + } + + return *result.ContentLength, nil +} + +// generateTempID creates a unique temporary ID +func generateTempID() string { + b := make([]byte, 16) + rand.Read(b) + return hex.EncodeToString(b) +} diff --git a/migrations/001_initial.sql b/migrations/001_initial.sql new file mode 100644 index 0000000..1505a4f --- /dev/null +++ b/migrations/001_initial.sql @@ -0,0 +1,160 @@ +-- Orchard Database Schema +-- Content-Addressable Storage System + +-- Groves (Projects) +CREATE TABLE IF NOT EXISTS groves ( + id UUID PRIMARY KEY, + name VARCHAR(255) UNIQUE NOT NULL, + description TEXT, + is_public BOOLEAN DEFAULT true, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + created_by VARCHAR(255) NOT NULL +); + +CREATE INDEX idx_groves_name ON groves(name); +CREATE INDEX idx_groves_created_by ON groves(created_by); + +-- Trees (Packages) +CREATE TABLE IF NOT EXISTS trees ( + id UUID PRIMARY KEY, + grove_id UUID NOT NULL REFERENCES groves(id) ON DELETE CASCADE, + name VARCHAR(255) NOT NULL, + description TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + UNIQUE(grove_id, name) +); + +CREATE INDEX idx_trees_grove_id ON trees(grove_id); +CREATE INDEX idx_trees_name ON trees(name); + +-- Fruits (Content-Addressable Artifacts) +CREATE TABLE IF NOT EXISTS fruits ( + id VARCHAR(64) PRIMARY KEY, -- SHA256 hash + size BIGINT NOT NULL, + content_type VARCHAR(255), + original_name VARCHAR(1024), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + created_by VARCHAR(255) NOT NULL, + ref_count INTEGER DEFAULT 1, + s3_key VARCHAR(1024) NOT NULL +); + +CREATE INDEX idx_fruits_created_at ON fruits(created_at); +CREATE INDEX idx_fruits_created_by ON fruits(created_by); + +-- Grafts (Aliases/Tags) +CREATE TABLE IF NOT EXISTS grafts ( + id UUID PRIMARY KEY, + tree_id UUID NOT NULL REFERENCES trees(id) ON DELETE CASCADE, + name VARCHAR(255) NOT NULL, + fruit_id VARCHAR(64) NOT NULL REFERENCES fruits(id), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + created_by VARCHAR(255) NOT NULL, + UNIQUE(tree_id, name) +); + +CREATE INDEX idx_grafts_tree_id ON grafts(tree_id); +CREATE INDEX idx_grafts_fruit_id ON grafts(fruit_id); + +-- Graft History (for rollback capability) +CREATE TABLE IF NOT EXISTS graft_history ( + id UUID PRIMARY KEY, + graft_id UUID NOT NULL REFERENCES grafts(id) ON DELETE CASCADE, + old_fruit_id VARCHAR(64) REFERENCES fruits(id), + new_fruit_id VARCHAR(64) NOT NULL REFERENCES fruits(id), + changed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + changed_by VARCHAR(255) NOT NULL +); + +CREATE INDEX idx_graft_history_graft_id ON graft_history(graft_id); + +-- Harvests (Upload events) +CREATE TABLE IF NOT EXISTS harvests ( + id UUID PRIMARY KEY, + fruit_id VARCHAR(64) NOT NULL REFERENCES fruits(id), + tree_id UUID NOT NULL REFERENCES trees(id), + original_name VARCHAR(1024), + harvested_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + harvested_by VARCHAR(255) NOT NULL, + source_ip VARCHAR(45) +); + +CREATE INDEX idx_harvests_fruit_id ON harvests(fruit_id); +CREATE INDEX idx_harvests_tree_id ON harvests(tree_id); +CREATE INDEX idx_harvests_harvested_at ON harvests(harvested_at); + +-- Consumers (Dependency tracking) +CREATE TABLE IF NOT EXISTS consumers ( + id UUID PRIMARY KEY, + tree_id UUID NOT NULL REFERENCES trees(id) ON DELETE CASCADE, + project_url VARCHAR(2048) NOT NULL, + last_access TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + UNIQUE(tree_id, project_url) +); + +CREATE INDEX idx_consumers_tree_id ON consumers(tree_id); +CREATE INDEX idx_consumers_last_access ON consumers(last_access); + +-- Access Permissions +CREATE TABLE IF NOT EXISTS access_permissions ( + id UUID PRIMARY KEY, + grove_id UUID NOT NULL REFERENCES groves(id) ON DELETE CASCADE, + user_id VARCHAR(255) NOT NULL, + level VARCHAR(20) NOT NULL CHECK (level IN ('read', 'write', 'admin')), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + expires_at TIMESTAMP WITH TIME ZONE, + UNIQUE(grove_id, user_id) +); + +CREATE INDEX idx_access_permissions_grove_id ON access_permissions(grove_id); +CREATE INDEX idx_access_permissions_user_id ON access_permissions(user_id); + +-- API Keys +CREATE TABLE IF NOT EXISTS api_keys ( + id UUID PRIMARY KEY, + key_hash VARCHAR(64) NOT NULL UNIQUE, + name VARCHAR(255) NOT NULL, + user_id VARCHAR(255) NOT NULL, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + expires_at TIMESTAMP WITH TIME ZONE, + last_used TIMESTAMP WITH TIME ZONE +); + +CREATE INDEX idx_api_keys_user_id ON api_keys(user_id); +CREATE INDEX idx_api_keys_key_hash ON api_keys(key_hash); + +-- Audit Logs (Immutable) +CREATE TABLE IF NOT EXISTS audit_logs ( + id UUID PRIMARY KEY, + action VARCHAR(100) NOT NULL, + resource VARCHAR(1024) NOT NULL, + user_id VARCHAR(255) NOT NULL, + details JSONB, + timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + source_ip VARCHAR(45) +); + +CREATE INDEX idx_audit_logs_action ON audit_logs(action); +CREATE INDEX idx_audit_logs_resource ON audit_logs(resource); +CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id); +CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp); + +-- Trigger to update graft history on changes +CREATE OR REPLACE FUNCTION track_graft_changes() +RETURNS TRIGGER AS $$ +BEGIN + IF TG_OP = 'UPDATE' AND OLD.fruit_id != NEW.fruit_id THEN + INSERT INTO graft_history (id, graft_id, old_fruit_id, new_fruit_id, changed_at, changed_by) + VALUES (gen_random_uuid(), NEW.id, OLD.fruit_id, NEW.fruit_id, NOW(), NEW.created_by); + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER graft_changes_trigger + AFTER UPDATE ON grafts + FOR EACH ROW + EXECUTE FUNCTION track_graft_changes();