From 9a3bf859ddd014bf54554f73cf99fa56a0d36fc3 Mon Sep 17 00:00:00 2001 From: Stavros Kois <47820033+stavros-k@users.noreply.github.com> Date: Sun, 13 Feb 2022 14:46:46 +0200 Subject: [PATCH] feat(Photoview): Add photoview (#1881) * feat(Photoview): Add photoview * update app requests * whoops * update image * sync perms on UI --- charts/incubator/photoview/Chart.yaml | 31 ++ charts/incubator/photoview/questions.yaml | 339 ++++++++++++++++++ .../incubator/photoview/templates/common.yaml | 1 + charts/incubator/photoview/values.yaml | 42 +++ docs/_static/img/appicons/photoview-icon.png | Bin 0 -> 18285 bytes docs/apps/app-requests.md | 3 +- docs/manual/default-ports.md | 1 + 7 files changed, 416 insertions(+), 1 deletion(-) create mode 100644 charts/incubator/photoview/Chart.yaml create mode 100644 charts/incubator/photoview/questions.yaml create mode 100644 charts/incubator/photoview/templates/common.yaml create mode 100644 charts/incubator/photoview/values.yaml create mode 100644 docs/_static/img/appicons/photoview-icon.png diff --git a/charts/incubator/photoview/Chart.yaml b/charts/incubator/photoview/Chart.yaml new file mode 100644 index 00000000000..3b4e77a7434 --- /dev/null +++ b/charts/incubator/photoview/Chart.yaml @@ -0,0 +1,31 @@ +apiVersion: v2 +appVersion: "2.3.12" +dependencies: +- name: common + repository: https://truecharts.org + version: 8.15.2 +- condition: postgresql.enabled + name: postgresql + repository: https://truecharts.org/ + version: 6.0.66 +description: Photoview is a simple and user-friendly photo gallery. +home: https://github.com/truecharts/apps/tree/master/charts/stable/photoview +icon: https://truecharts.org/_static/img/appicons/photoview-icon.png +keywords: +- photo +- gallery +kubeVersion: '>=1.16.0-0' +maintainers: +- email: info@truecharts.org + name: TrueCharts + url: https://truecharts.org +name: photoview +sources: +- https://github.com/photoview/photoview +- https://hub.docker.com/r/viktorstrate/photoview +version: 0.0.1 +annotations: + truecharts.org/catagories: | + - media + truecharts.org/SCALE-support: "true" + truecharts.org/grade: U diff --git a/charts/incubator/photoview/questions.yaml b/charts/incubator/photoview/questions.yaml new file mode 100644 index 00000000000..869fc669f3f --- /dev/null +++ b/charts/incubator/photoview/questions.yaml @@ -0,0 +1,339 @@ +# Include{groups} +portals: + web_portal: + protocols: + - "$kubernetes-resource_configmap_portal_protocol" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" +questions: + - variable: portal + group: "Container Image" + label: "Configure Portal Button" + schema: + type: dict + hidden: true + attrs: + - variable: enabled + label: "Enable" + description: "enable the portal button" + schema: + hidden: true + editable: false + type: boolean + default: true +# Include{global} + - variable: controller + group: "Controller" + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: advanced + label: "Show Advanced Controller Settings" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: type + description: "Please specify type of workload to deploy" + label: "(Advanced) Controller Type" + schema: + type: string + default: "deployment" + required: true + enum: + - value: "deployment" + description: "Deployment" + - value: "statefulset" + description: "Statefulset" + - value: "daemonset" + description: "Daemonset" + - variable: replicas + description: "Number of desired pod replicas" + label: "Desired Replicas" + schema: + type: int + default: 1 + required: true + - variable: strategy + description: "Please specify type of workload to deploy" + label: "(Advanced) Update Strategy" + schema: + type: string + default: "Recreate" + required: true + enum: + - value: "Recreate" + description: "Recreate: Kill existing pods before creating new ones" + - value: "RollingUpdate" + description: "RollingUpdate: Create new pods and then kill old ones" + - value: "OnDelete" + description: "(Legacy) OnDelete: ignore .spec.template changes" +# Include{controllerExpert} + # Docker specific env + - variable: env + group: "Container Configuration" + label: "Image Environment" + schema: + additional_attrs: true + type: dict + attrs: +# Include{fixedEnv} + - variable: MAPBOX_TOKEN + label: "Mapbox Token" + description: "Enable map related features, you need to create a mapbox token. A token can be generated for free at https://account.mapbox.com/access-tokens/" + schema: + type: string + default: "" + - variable: PHOTOVIEW_DISABLE_FACE_RECOGNITION + label: "Disable Face Recognition" + description: "Completely disable face recognition and hide the icon from the side menu." + schema: + type: boolean + default: false + - variable: PHOTOVIEW_DISABLE_VIDEO_ENCODING + label: "Disable Video Encoding" + description: "Disable ffmpeg encoding, but still show web compatible videos that doesn't need encoding." + schema: + type: boolean + default: false + - variable: PHOTOVIEW_DISABLE_RAW_PROCESSING + label: "Disable Raw Processing" + description: "Disable processing of RAW photos using darktable-cli." + schema: + type: boolean + default: false + +# Include{containerConfig} + + - variable: service + group: "Networking and Services" + label: "Configure Service(s)" + schema: + additional_attrs: true + type: dict + attrs: + - variable: main + label: "Main Service" + description: "The Primary service on which the healthcheck runs, often the webUI" + schema: + additional_attrs: true + type: dict + attrs: +# Include{serviceSelector} + - variable: main + label: "Main Service Port Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: port + label: "Port" + description: "This port exposes the container port on the service" + schema: + type: int + default: 10159 + required: true + - variable: advanced + label: "Show Advanced settings" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: protocol + label: "Port Type" + schema: + type: string + default: "HTTP" + enum: + - value: HTTP + description: "HTTP" + - value: "HTTPS" + description: "HTTPS" + - value: TCP + description: "TCP" + - value: "UDP" + description: "UDP" + - variable: nodePort + label: "Node Port (Optional)" + description: "This port gets exposed to the node. Only considered when service type is NodePort, Simple or LoadBalancer" + schema: + type: int + min: 9000 + max: 65535 + - variable: targetPort + label: "Target Port" + description: "The internal(!) port on the container the Application runs on" + schema: + type: int + default: 10159 + + - variable: serviceexpert + group: "Networking and Services" + label: "Show Expert Config" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: hostNetwork + group: "Networking and Services" + label: "Host-Networking (Complicated)" + schema: + type: boolean + default: false + +# Include{serviceExpert} + +# Include{serviceList} + + - variable: persistence + label: "Integrated Persistent Storage" + description: "Integrated Persistent Storage" + group: "Storage and Persistence" + schema: + additional_attrs: true + type: dict + attrs: + - variable: photos + label: "Photos Storage" + description: "Stores the Application Photos." + schema: + additional_attrs: true + type: dict + attrs: + - variable: type + label: "Type of Storage" + description: "Sets the persistence type, Anything other than PVC could break rollback!" + schema: + type: string + default: "simplePVC" + enum: + - value: "simplePVC" + description: "PVC (simple)" + - value: "simpleHP" + description: "HostPath (simple)" + - value: "emptyDir" + description: "emptyDir" + - value: "pvc" + description: "pvc" + - value: "hostPath" + description: "hostPath" +# Include{persistenceBasic} + - variable: hostPath + label: "hostPath" + description: "Path inside the container the storage is mounted" + schema: + show_if: [["type", "=", "hostPath"]] + type: hostpath + - variable: medium + label: "EmptyDir Medium" + schema: + show_if: [["type", "=", "emptyDir"]] + type: string + default: "" + enum: + - value: "" + description: "Default" + - value: "Memory" + description: "Memory" +# Include{persistenceAdvanced} + +# Include{persistenceList} + + - variable: ingress + label: "" + group: "Ingress" + schema: + additional_attrs: true + type: dict + attrs: + - variable: main + label: "Main Ingress" + schema: + additional_attrs: true + type: dict + attrs: +# Include{ingressDefault} + +# Include{ingressTLS} + +# Include{ingressTraefik} + +# Include{ingressExpert} + +# Include{ingressList} + + - variable: advancedSecurity + label: "Show Advanced Security Settings" + group: "Security and Permissions" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: securityContext + label: "Security Context" + schema: + additional_attrs: true + type: dict + attrs: + - variable: privileged + label: "Privileged mode" + schema: + type: boolean + default: false + - variable: readOnlyRootFilesystem + label: "ReadOnly Root Filesystem" + schema: + type: boolean + default: true + - variable: allowPrivilegeEscalation + label: "Allow Privilege Escalation" + schema: + type: boolean + default: false + - variable: runAsNonRoot + label: "runAsNonRoot" + schema: + type: boolean + default: true +# Include{securityContextAdvanced} + + - variable: podSecurityContext + group: "Security and Permissions" + label: "Pod Security Context" + schema: + additional_attrs: true + type: dict + attrs: + - variable: runAsUser + label: "runAsUser" + description: "The UserID of the user running the application" + schema: + type: int + default: 568 + - variable: runAsGroup + label: "runAsGroup" + description: The groupID this App of the user running the application" + schema: + type: int + default: 568 + - variable: fsGroup + label: "fsGroup" + description: "The group that should own ALL storage." + schema: + type: int + default: 568 +# Include{podSecurityContextAdvanced} + +# Include{resources} + +# Include{advanced} + +# Include{addons} diff --git a/charts/incubator/photoview/templates/common.yaml b/charts/incubator/photoview/templates/common.yaml new file mode 100644 index 00000000000..a6613c2ce21 --- /dev/null +++ b/charts/incubator/photoview/templates/common.yaml @@ -0,0 +1 @@ +{{ include "common.all" . }} diff --git a/charts/incubator/photoview/values.yaml b/charts/incubator/photoview/values.yaml new file mode 100644 index 00000000000..2072f6a1c91 --- /dev/null +++ b/charts/incubator/photoview/values.yaml @@ -0,0 +1,42 @@ +image: + repository: tccr.io/truecharts/photoview + tag: 2.3.12@sha256:84a2a71f6efdf659bbe127dc017cc4ef5fab34a20ba1d5c9c75321c2a75b9531 + pullPolicy: IfNotPresent + +env: + TZ: UTC + PHOTOVIEW_DATABASE_DRIVER: "postgres" + PHOTOVIEW_LISTEN_PORT: "{{ .Values.service.main.ports.main.targetPort }}" + PHOTOVIEW_MEDIA_CACHE: "/cache" + MAPBOX_TOKEN: "" + PHOTOVIEW_DISABLE_FACE_RECOGNITION: false + PHOTOVIEW_DISABLE_VIDEO_ENCODING: false + PHOTOVIEW_DISABLE_RAW_PROCESSING: false + +envValueFrom: + PHOTOVIEW_POSTGRES_URL: + secretKeyRef: + name: dbcreds + key: url + +service: + main: + ports: + main: + port: 10159 + targetPort: 10159 + +persistence: +# Don't use emptyDir, it stores, thumbnails and optimized media + cache: + enabled: true + mountPath: "/cache" + photos: + enabled: true + mountPath: "/photos" + +postgresql: + enabled: true + existingSecret: "dbcreds" + postgresqlUsername: photoview + postgresqlDatabase: photoview diff --git a/docs/_static/img/appicons/photoview-icon.png b/docs/_static/img/appicons/photoview-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9a7bbfe9f56cbb87fb3b9f6c89e91796bfb9922b GIT binary patch literal 18285 zcmX6^bzD>58@>x*BSuTZ=u$#JnvG6rC8QJ;5RvZK=nyGUQ0Y**L{ShJ4Jy(hC?F`E z(y{F~zrWA^*gl_oKj*&ZdEe(b&w1}zqN%Yi4JA7z001=ldRpcH03!Va0WfmXmz_`9 zebN{C9Yb9$fcWoI(E8>n0O<1RYpGiX&1{9^EB$A0%*jlut^6Qo0N)m-k*8yaovsns z@b7+%{^g!ExCKQe;gNI|wTa~`G-CQR>Kws`Gqxp{)~fIH*ore~X=!!O@Hx=a-->$H zsCYB#W81N6XszN|7vZJ*H|btZ-|BZm-&b-zI?W&dXjMDvn{ocS65Pu&{9dHD z+V&{CWMr-PTp3!EbiY$gTPUKJ;;0U#1ES^>0bQvt(jog7OEf8#2yggnVTx!TTm*IA zd_lAh89N#2LL?#V=n{@%BEPuBMCF2+lhD?y^hu{yUTl~SJ-fYg>08qsAC)j$Z;n=o^NtT;xM&ino64G3saA&t+gH;Bzn0V#j82QE1>WHMu#}D<5{whRi4j zCQ0K{4!?go_w8nI=MZB1*o+A)IBfz1>Sxe#l>z@kCp|#8<*fa*#*nW4#r!?B-LRDH zkiOH}NWSs35eUHa|Jez{@hls+J5563HUH*hLIrfdL3(7(H;Tbez>Qmt+rLAycb`_C zx}8ck=m7;e@*n0H3e6(pNReq&5?dtH50-)EH-UjX#8eS=VNTt~NXlqOofrTy}FY@h<*Q4@jy2}@I?P(7+paGJ9$Yp#7S+_q8zYa+T4^2!EgOPJwJo7Na2fw-CV>Z z&kof{JMU|9QLcpiCBd7Oq#MAlv$@|1CT+LO@Qf$i{D6Vg#VYFzA>R5m1A~}TTZu3U z4vOLTv+)Gg4LEA;QUF|y@?d_c!-IkD?F}9}_3;&!@gYWg!*^dF_QwW1G(;hau8v5q{16no9 zx4uEUI-r&og6FRVr73|+uWJreh?{ymRN>t?iCYLaa0P&e++nwCO+c5zJFzYKn)gWtf_|bqRw2>O!3D?jnL+|ke8W7lIVVI z3z1860|U=+$pp;q(852fF*MgHBZAH8l{}e{;g8_U|IcI4DzVM5E^Wi{Q}pZ!W+>`| zu8th?-qns}pW6w*?@Xsy?qR|3rK$fvd15$!h-P)@=;v%H5s|F;nLJY#n<52c>qTG< z^wr6kSBJ~c#ehfUKCsd$I}iJ-Sp*%i%m);uVR{UaNYT?5wbI3a4Oi#FM?nn^=}8jN zFWwXRcUquN&6dCXQEtBZGNe}=1s~!sg6!@8Sb^aT$*$oRGYIO%;6YGhH8p;U#h^2F z<&n;Xqnfh)XnPvZ9jeB@vPzMANScECrIZw3f%#Z%dNNTY1Mn1%#(`3TgeL$5@+p&^M&s7Vj zF0c27tnW|9YSnTCiK_$cO8(;3V$pv~1#*-IB*X0#~Tr-icY3ntSGcjO# zPMw_q=oD<@9~pw~&hoL|YfGUppKjF#diI?9`5&_##GCrog{Sn&QeQ9AeTmc}VGiA$ zEO2~X>;UDalvAIP8vlSa^~ zmCY&BSD=RcC_FU?IkrSeYJklZlG)x{kjo0e+qT7>=6s>I zD^|ulY5POGMp8i>WG1BlBcWVoS8dT3{6z+^{0wNW2?wX3ug|s99LA3WYY~?_{*&Dx zbS2RR)u?~+i$8oT9GGN1I_Ej~D|}l5_&$LRrDYHV_4M-|%sNDxmH}a+9cM(x(I$NR zfB6B1G1oO$hh*CIa)8W^0BRW`_LK7NoU|)D+D8Qh`!y_BrbSl4sV?ggcqwZ zJVe|fI^1auf#BvJqKe{xZOH?dPd2g#q6t_~)#wQ(2`b{~A=u-%PRV4Ez{D2gZ|`5A z%lS36wZxNTF%+@qFuZ4xTifO*=6BzaUZbGwt=&95kU}Al8FL^K2-Wk)!e3x*Wcdi3 zeoyvm%p&w+>zobG1QzoCz-`*yoE zMn?sPwSGf3{x7-59VfL8_KQ`a?qf5zWCC6$68D8b2}SN1r68}!4XShUaUl3^q2nJN zNi$Frzv%&}Q|{(Z_k+EEWv}pO>tX%iVf@u=j}Kz)cAd08U!=;Ih^Q7V zQxMGl-CGEI)wobE+EFTko(xZrSj&%i_it4+raKFCiM1or8?=}5R%M)Fq<>N9FkzYb zr#>e0%iUbM8uo>ry2k$r`X4#G?#wQ3rtR`~-WJ0}RPLwlCVUBRHNzgvcf8|U zDS1x&rk3B76P8c0s|`|V1gwkPEem+D7SV)r1nRSx=L9I39vrGB0Qj?$(cRom2G=1k zy|#}LVSy}d#2nrZ* zypA!|e45LIS;wz6TcZ1kmYa0VWrctc^F%3XTfjDov^r@5fgjH>3TwO09YpD2M|}ZG z>K_N4pN&7S8-_&S)a{4Lp&8HA9Pr1L`$y~>6T@Gg7{dc7qvP{pvi@c9CFBFu>d;C^ zXDSE5qLsW3!9ls;10eeI2dM?98({CA-`?{-zagv2%KtJtga$PmNJE;b4rm)V6|04e%0)uSC*{dEt!|z&fOog~n@dtL zrT^ef@wni*#rNak4GjOA{3|CrQUP+Hgvcy)`Jf`Zdrj*XrBY6p$nx0|NpP}Q$kg3%VW|5z({h<{;E>9| z#F&xXnLFa^)0(N?yG~fR9;yVsvB_`j5D#=RfU2WSH33~aJPMy~==5s0m@R_&g2#;c z1LXh|*&vF2L5q~5(wtm`J;Dleu&=vgR46~>SAS?q{0(>N?skDecmWZ>EqPARLq{iPc`llVZJEf#Pk5t z_#Kk66j$11c;GSPr3v_IVtVVkXvL-4uZi{xLPtS_+9;LgFSg%hD3Jmb`b@l&uzv3_ z3a8e&60*>j(J2Fvv~}=R*}7_G(so1 z9WRg}$6EV>MyEFT`WVihFz!-Qvn|1rjCt3Qev_nqkO+>n-9pWCw3EFp6d2RfS065D z2laGxt+n!bm=aJPAK;NuKo>hU&5y#Mg`($>Y;V3%VHh}6-hB@0I&R7lXzZ@|w~)QA zBIIB63yKUJ2AW|Lck^Rs8BT_Q#>R#$5ghu5W}#@=a|)cni`{Fy2{txc#k3A%0^N_v zN84XWt||Z9l{ir!I9AWI!!X*E$Uo$n$#dToKcsSCUuW&=fJRf)HJH%Rgf&;GcN5b$ zDHh&6JaN!z^(z`NNBl)yzo5(fN7{c1PMulBc>klWKwkBE|r)LSn_ zuP2!4Qg4mn)5@rP{4wz`En9w3JUo`cQL~atPc$Xyfsu@2Qn7I^&xcS>Y~(Tt^lO3<8;q^9-AfERBQ17VLKvT z06i6?pcjT!Pt}gR`L~6@%{)3=30;~BnQ`%Q3{HtfphP+_>ODKr;10oQLmxlhQYpPT zL%k5f8yRx6;sxUKAq4cZ^E>DGh=`w8-kyA;v#TcAx1s+`KY;%jI@Z3*5inD2AHLQzsj9KAf^nO>~1cr z_`zbC+er(YR(PaY#4L8h`p&-;YXZ^-#8tuU`OGI=e~2h{hJx#BJJ)M#kEnSE`t(71 z>>@7%C=H5%v{%U`D|FXjPE*2l*$gVTDC@Eq>_!9S#CBJ?0L-GZq1}Ne*B!#MUeq;1 z)2m^k+XSER1){W<`10AU5pcDI*C>+fgP`3DjGK~Ixsp@_VY%nEgp<(^%tL$h^}7X2y4T6Lt04;}VGk4c3Dx25 zJGM(r4MCC#|?`^wj!|i+3ME>kjtSv>M#LUoa zOaadSkSJ(d&=Ka_zD8H0?vk29siH>dmG}EBn#pX){lZ-B6O&+>E8piv>Fmoqs6xgy z%}sELA2k?09MZ&kXZnwB1!P*Cn0XbMD1^sj<)*+;^}Qa{3dXON;fj5L zi(H;o=xSo~OlY!WwM$lz+UZ;9*kzoWh^A(l3aykjn{7TeEezp`fPY*D^((>ncaWd* zITXwxUj8tNcL*83$S%UvX(;NV#0*P8h3~5CN)=kS>D^f->huqXL^SR6tV@AJTJ5!x z5T@lIKaD}G5{>mL{V?-ucwl;-_dZ{6?K4ZKlqjSji^6b%yI*QNr3yFHYfd*D&s?L{ zbK=erYoLeRT?UaIx$CPL?< zB*HC`uxA>n8ws2!qe9>_6@-da-Pq@jX#Z;5v`|r{+Giq*&&5O-)_8l(lQMc>J)bWb zBxX7j?`|I}@^Y;y0)DW;#tBk+doIP0bSQLTe}?fPJL zR_DKg4})$0n)tKQ8ORq{{xNw#W=_E?2#-A!;#3f1G>y4nbi-~d)YMz61c~kLisDY+ ze`QHC40_it1L3j}v7FV)^kyZz=)5N?iDF#t4-z@2sEripb9^O??pkUn17!#mKMpPe ze42P7Z@S51a~6@$SI;R-$haFxl%cFZ6?BEVy{o+%kwI)1GL&NC)Q$rvb7M=3gxuPY z)G3m2tWQ?4vMOYaBVZjDu*Mo_!4L6p73`+KWM;YWy^B;))|6?&7nud^w|5^c#qSWW zP}WhtVpsre3cr|oJIYp8!dCVUDESJeLq>$P$v#hx*~GoFrpT6NG@XEJJ!?0nLbmmO z?GGho*`C$z#}a!s$R^cS=X7 z&rXwaXqoqx;JuC{utA@~efx=TPLwkEB+Vd6-{gD4`+6(P$VZES@_O+R=;DRa&Zj38 zDQIVEj8nfuypvh9hvmYjP%q1cUuIaV#pS#-?Z!LvYP#V#R)XULzL2pM(dP2~1m(RF zgVymO$7ol7 z;WYMx(WLvmO$MybJoHL~X6*eSI)sD!UHJBCdqJ;eB2151t4&p6HgB4fG4avbr_7tz z>`b+1{&>-7O%)wclWOpXXEz4#*XQ*ikXAx$*GUA|R*PDKXm9Tnf!;M^BQI$YBx80Q zesKOJ2GZp*TIYNF-P6;npl}^j<=s8bTzb6gFbWenR&;B`LU#Y=M!(5^30HW{oE?(l z9cCx)wdYla>rw|=+6Z^PTw%B=Acn>;kw+R!MU=-}!7S;soaqT4 zp#ov@qH@#Rx?Bx=u5%?k;z|oObd3+ddclvd(C5~B(S=~zPS8W0kY9yxAe1-C6Wwe^blxc?U&JgM(`ZoxTsG~cg^_}sWX?5N&)YynStYG%iDb&ffRmoUW4#e(-viccparCMi8>q(^@ zXVSTz-}%T`1S|VJOF#QC%i-~+2+7j37Wp^{s${=szExcm40^Utw37vvIwRZ;kf9Q4 z&ui}ZAYCl)gq;vzdXr_JVwN3(?s$E2@zJ#thj|C{<9H{8{ zglhPZRPQay_frX+Rql8D=0e51JVkNjXSMT6CFe>iP1=y|3G{hr)t)$$(}d?=qT=3{ z=u^y|SDHlpd9(oX^BRcK4BJTVM7+jSf&50MSKC@y&B74-=nKm9@%LZ4NDMe54WFcX|jq-<#alhH#w2F zlaNHF?u%OzT zzrAs82hW=0VBySGfI$h{9XBzNqiIi!e32g`c*7+h$C^OUqT<72lt!9CcZCV#ijkqZ zWZN`k3zex?>K#0kE-bxOzO;1JFzxHmAafumf63<}TsXkVj1dg=SHdNj3162BGUt8V zs80wPBfebUN1`qt=l^bcen^vW2Kf|p%aouxh!)gyEPy)nI95P*NhrjeYm#l#f<-il znerBFf_3lCEEN5%84<0$^ZU!UCt3CKwaY&DO?D8^kkP=Yt}iY!LiU*4HPeZU z>E11=D%oP==s9!wc}qqo^+Q?#KOUXDrF?Vn-XSxM#%Jr2x6MZAEA2eYw^1h9b(8S! zW7P1*MftfpnQAKA28CCnGxQ+2S2q8D*(<7hg_yw$oB^< zBFA)rU(3PIx3c7$pYpagS5U>-+u;Qxhes@#lJ+R(EP<%x3Kb?Fpg&~@63}U)H=_RQ z#3(jPi81|((Cb>w(E}%1Fjn(VARn+1WO-Sn>pV!Z45zOQw6TNmS9EV1kI3D{A^_IH>jal=+49 zQ^q>e71aW;Uvn>UogvIy@5DRS?SWh5lC4~N6gzv}x;!J6m$hB(ljo|QUIMtAFK_Zx zcav2>Ws1%6wiHO=I<>)E#2YP8z)#L%?k^4icP%mbuwdCkRA06 z%-AiaqxwiDgQ>;ODj)?ptiP!bbtB=7+*ZA!!9v>-O^-{fg+#48HbIU zq&|n6rQqNCQnNnL=zT`@Bn9@oV5}4@yat@CcV#(66lLYvUgWQHs$XNT6f!qul3;z0)z)>|An^jr7=`E}P$&lbr97b*2v&$Kv~^PF<)s zhq|I(*+w#!g8f4Np`bw8TaSm_ZfXk1i;lwme!@SefNt@UjpjfD7~0x zv>$%3^*A@AijJStKFZ9MPfVdKnGYt*Ptt?^LfASRIO;`LgmVry>(b`uIFn?`9BPst zSY@q#^IJtR|4n_unr#U>%#8&@Jlj=%6J5yj8yAfG!t}?HHx9>m^Gaj#Kg?kTZa6CQ z1dB@PJ9mqC(!JE7(P&R3_sT{?7IIH2hrpNB&&|QZ1lDH^IZVt7T+lj&{Yt{{O^=3H zjVq^pNkXp7vE_i9Hq9M=S_5Yj@4UzuXd|V%U}3+8+MN`PpD{L4!r)tG+!So>SW*BQ z+=m7I@mpX3o2K%lo7q0BS33!W=OCCB;1sz0)7`pSlrnW2^wjVG?aO+K&icE-%Se}=l%cI?#}-zDosTjj%@pq8cmrNt z*Hyhy8Yfq}(FK}cZ%d6UlxsPm262!p_n^jpU^%`5)(6{p`@*QdRvci3Tbw@lcg*uG z6{#sOrWg&;(rKSd4`CsdYP8?$)4)|v7NZ&(^v$BsA^EC$r{}*pM1@KTy|v6ty7Vz& zv8*0Bxyt5PuEJ^QJ3K#+pUhsmJK2jky`aQ{T zbYjDB<_6Y*jx}bcj^04AL#kmvinQcwvUllp;SD>1^;ZxTHiy4B_qHN88MW_^D?lD9 z!G20Je|RebU+TLSC%Ap;yT_4J98KLcAO=z zJI@Df8t|#Ewo8s~`?8o(&ja2 z7sZS;`s=Y;qsLr&CJ78ycc$+Rox2X7c2BpzE&EdS_tn#L4!)x}iJzj(9~eo+fltfW z)jW(tz2Gb0v(du_E!HPlP*%00CJzu-Ys8-ovVT0enOMWbHeG%sB}Dfoj%A7sTKrW3 zJxM{%-?hw6rZx)CEQ2J!KbX_+n!d(}AJ@%Sp(Krq@rU=ac&_y5C`8S;zhI8_zQD{9 zZdHx@HZr_DX&a|S+9!gPRi~cnTPK4B@MOrGH;NUiWb1rfKx|!!NN*UHo;EPd{m+ ziilagk054U!<{+6B_G1l68SqopMS&}KeP-MSXW~>Y`0K?l~!PMeU?lSxG5s3e=o}c zUtYU#)&i{?hU4iYN2R&uA6PCN(V=l#tC&6|b!i*DB8HYBZUh)vrpA~S>uz}7$UMJ( zt-D{lsi;joxPd;E*_-crDiqDpPw7QF>LX2VsE~LqbyVCN&v0#6J{R^(>MvK=Xr+ogTN@e+?nmc z?c=;V>7T0i4L7japv1oe3LatgLc|W;GE9M^kqnf1p9qyx6-ZmckLn%-v4?YvO~Y^RJ}~c z$JLp+AZy7MQ=z^NTxRm;{Valx zONR2({j;YTsis%0_d+=$8H`jHPAnHl{p{y4Jb4>~IPTZMM!Go8>%`bO>KGaY*XpZS zha<}Vt!4{W?hJNfqqr0mrtcX>JzGEf0j*7f=^7Qz3pCm*ok?mK|Opl7yq==8LQmqXrnfF{5o4#SjEeSO? zHIzzw67ZzQM!Q+^AWcd~4FB}z3Apcg6?lb7H6Tk_1Wu@Um>42hg+IP{OVP_0wW?cZ zOO=Eg@aQq%dqKIv`+J4TSm+y++ADzeX2U6P?-T3qZOuD<$kp1&YC0IjZ;I~_2Sa0k z`Fpsp_XWFwmzJ1R3uz5*Z-(x%c=I&X%c?62$6Pn3GUc|tbE@xdmpvT@HK4&Bup8t9 zQ&>}xcR;6H6yLCo>8r&?r~Yq)r6-WXRzmOVvq^T<9QxQL)5ueLoDGq4fl=?|g|&@> z?u}m|_Wf)~m(J8!2IPK-83%T*T{2BgLDv3{y8l>|BEuQ@*#>m6o#pXfHLh17vcfB$ zaXHi~>=grNEag`c|KsN{@I~Rn+rfE{y88SWZiJ}&ZKe=?w;t49R1Q)=H@lG%yN~>z zBg1&D(r2Ga_d}2BQco^=VjUQ$$9wi$>v-h873c`WbeXYEDTA4_Nqt$4S_$>^bxebA zyi1ahbrfg7X9W(8JO-NnZmlKV?vi0ZjI}fk?)rzK#Gt(~i2|mHepkfTuL?@HqiWQr zO8F9PCJODeP*V{+LOD_rES2MSkYW3Y^+*9vt%9WUVuoB))v+@c6gU@`)ERo`j(dCqUdi zKaAn=>BOIx(0(988{(%{(d878P&Vdi$#?tDi(u;6=o~Y6xpe$Bw(P&Q0Nnn-?b7X0 z`=G$N$4E^~}9|2wnAslvpkqxi)rdiTu)B{iUU!0Np%Vw#jswmEiO`I?EUN`|;)xe?0zC zI;D{=uwfMjNBOlJ1-bO!;UVta!|^9Qiu+s3ELx6I7^oZliZ0A5@Eb&;!$dAndMoJ} zr|~}A=&%SCNu0ZYg<*K5Gf^fUZ>futWX}E#oaoN2A4}zvmnzbAEq+LuRmjF1!8JMRlG6nYeRMj^Zkv&z_+~TJQ8=>!qVM{!A~C9b z(M0i%o;W+iV>ULFnMhfR`C-Z9GEjSO+PNIP_*M8hO{y*s7J(&LUcHkylvdt(`^U4V z)`tYhiM{s_{;KN5ddfq>LUAn!{cvD<Hqd;n%D_jyLB)Z5+Y{ zaF3aFt|$j0itK~eAC`eSidT~d4CA)xj|(-nl#Rr}1N2)7M`lel6iU=Ii0v)8(TWr` zFHRXoX1!Xu49anS>~>Yo22Y^T6+%*QSPk$q>Q_rHq-Y!U(9Zob1F~2$fAZlN`>?vf zn#ATKl=luc&FdrxW16Ee19J6h8`<$3&gm{ZDF%MJ3~U$k$KffNq*$Q3W|3kPI22)S zshse343u~O!nx^&SLP+<96*5JupjYkQ*~oz{qB6plaI13b*`oZioCHngD-Ctq*pIG zQBE(rc+SY|gD7HI@DR39R<}oFYC@Kof zD^hfQ7U|7s=KTnnVzqwDV!(=NFQ-s-WLWhhh*i#G`VVl@H{Y_gD>HJEavi=s1HZe~ zE|!McpFtG9SDjYh2)9Ol}bPAM_C zM?2fQB6F`@qzk`Q00`yBmq!$pF4BDe)I^>-i-106eGTSSjS%XW9FoM-{go!#;)d6C7^nrGCdJi8+w@(BfGA?t+&f?^ER#JzQWKD~=7(6tgV z1#y9(5s1G67fjS)lX@MTnFZ!NyLlUbh#f?1=Ht6(2J%s0y;t|9R~qE}EX6EJidjJq4=&-3iLJqz zJ9M3%Hb(N?cYAbiDo+d&c*itwJ0_rV+P7#dz(WPsj`nDz_krvSXRZC&&z-fz()fXy z>-&G`3)?c%Z?J!mU-B{%T+A^pxPN%e{!!5cEq(E|zgkq?K*2Nz=blN$@&?A6Dg>=w zH&u32i10Sc0%Dx|E~?A0V*{>t>THs4jxrV@G%_tBAALA$cP~Cmy|!S$+}4X*Nnsj> zQ9Ya6C_5oaGkpQ)O6g{cvPVt7(`A$AHg%Omlf%#N)llb?+a z2T)HtqvD)`rnAfjR!R1P964~IU-5|9ql@>_Eq(U^S&j5wgO{VN!u}j)ABH?VCGlP7ful9 zL~~(#=#|fthe5J2QbNoh;>5-k(?QIu0CqlXN)Tr9l{q~}W5Kd;_^G*FDX#)QnR5YUnZouC-osSnq8U^1`EsUpsoeVV^D-G7PR#^zM6 z9^MJit}WNek}TG8p^hDjz`4SbbRzfeE$wy2{SV`F;RXSYa59{(;Cssj>XpipuUYaG z8As>&ZkUU<4^E%HzGt@hFz8N{MP69 zWtHQ(Yu9tAxnBQL<@O4lTNuwJAJ%r9`A&xO)Ln6Re6;2`q*#~F|I60y137$1`U{HM zAaAVZdKD)NMhlEHyu7PJ5ktIB87x@nxgL>fx;n`_?c&8<`FGj}<$Hmt=?7VKh-PYO zW(+ZNq=-RuqM6}(vnf;u;PerSUvhOGOwAjN3C@{koo{-J-)Gbogzqx-w1deG4(63Z zeD)Qw`IA(^eRC*tk*Z0yPqHyjCV1Zbg8mptiCeG|n+E+}N7IIkkQ#3WbeY>)<AMjj#+z_WVgn8S@(8FIQ;0=&**m`KG5ezB!fm|nr>+xY}>D%6(D4tVY-64P5}B>K{wKtx8BmuQeQJ0g!riblwMVN z;`&Q*Bzs6=BO!r9Z+v^K-uN0zY-x~CvE&-~KG>xBuMSc2I?cC;ptP=tdJ8?Ple8nE zNte~ygK4-1GR$i}W~Yqy`vlIf;KxMYW3Z8I{ToxOgVVyj#|Wn#XuwOX8}iw?j4p18 zlkB>*lS@^5iRM>cAVb$m@wLu^9Q70OwCxoEW|a-8oP_96S~VD$SLz{8K!lpJFRcPq zxan%#CU)&@5upD2Cni2j+wr8!W%Q>NN7S%<83+BvJr<7W z&;Z*dQFgxwNeiVQ&j^Ly$Ae-Lac-1#GdC~4V3E2(!8-QA!soR_4~Ci&>%(>U)^3FM zbFZfowv`d7B6sSW=y>aV;3MW5uUCm__Bu5$^*J$1Yx(>)rybYhlE2Oj5jmMF0(bA^ zH>|%Yax{e+2o)&59gA`&_em-LE&c%fj5Fe)1NzA3Bq?H-HqWN1eVRFlwBm~0b|sBS zUPuQ#ntUGf$njNXKcoY}I7*!o>rUM=Y^t@CTl7nxIZEdzW(J|6rH2#|Upy6O=ES5J zw6XVKDB~rmy(YR6tqy7*E(I!LlM%z|zgpj6BzWsYm@aW@rxS-*xfCkY&}~ca#&2IK zOvp_=h*#|gVv?bwqw_!8T~=iLxAtIB&yt9oA_Y3)PNYc_2{J=N9jfff1cGB2BGVOI z!LOjBF`TSX@McxlSL^F582T{jGBVbp7-rtI5b6E&GWqKp;kySE=s7NhTfZ#4O{E%s zMkvjX0+z4;C}{?4Z??TKMVnceItULls~)pqo)t3% z6#*RIl+D03tGbvSo59?j3XB+WSMu6RoHaK}e8^>&1%RH2z%*b2f>sqPbN$cIpshp;*zH}TJ3Y0P6&la(z+<-coseWIv zomJV$w`9?=W8~*ri(n>lyS<2~Ql2pKj{#^CdnFueE;gkMLf7je@fz$DmRoV7jZT%- zt}-(u{IRS$6F##>@r7A>0T+xOByE6PrCgh8lBB+>vRM{KGEvyi-8uRqk$(^7F#9b- zy>kIxHV@tZvQR1cZ-E8Uc~AY z@|S4=`zy1c(brUuFrn4)sJ;+XL+|w2g`F{@((o%=DnkiraOJrZVPz5t5~vbhSJf2z zfhAy3GD4TD&wW0%HIAC7VyGMPlUTDi6F}|>NPDuexFR?otR#?}+lb-XI6mBVH#6W? zpTXA`-Y8P(FJe?)J!pT*1pveHm_akN>}!byYbA8ytGW*;Kwf;lQ?Jz7APtlBAdn*+ zQtY;dOUMNAW{}hEhf33nDv=KxCIq^5$k`EBMV#XBT|+XD_lA~%BV+8znrrsfBs_>a zx8PDa^x-H*b!nvZ*h==1pb0wWbndgkwTCyapVW@Y4yqUTw@|#XkFgOsy~j{Q#{SUw zX8-oXS^nYT-(A+NeFfMgeA$oo`97W2(%Jt{tXNLX?>cTUU#HJR48Ib?>X3^_#6z>luqaf0^JKt13N3 ztFI)Lfw%Dl!NS4J!Z#Rw#H&Y(SF!u}$l6uZSI-OGe`^DAbx7V19kVABf4)3SZ=lq1 zomSasAg*~x^HH84vCia&5$dt~yD3vDzwrV$O1T6Lcf{3UFjO0bMvy&_fs8%UF7UXw z@Re8INM*i+@il9Z>=KG}_)8hIxaZd88-M;oPaxQF!;}u75uBTiQjz;+#+i?=R2D@P z-elZOpj@lS+hUxFiT=%;9qay@J|V~f=MnQeiC0l+n1|>QmR!_4 zqZs$k5r(-bSLlapo4@DhQg@7=wHbEVxaWY}jn(Ohr1Jc`q76#9yTrK)WOFwx)$_J6 z{ID8UUl2e0J|7mq@jh4_;j{!LJhaxpj1mVzvX4 zi8r}Os)g3Oq(qiotC&rPfS@h?I_~j{t&us0!b}C*1KW*zKK}k>_nao-(>6*WJ7L@= zh(&tZK6OKW$WX zbq6E9W}Wu=X`?VLy%=G{!UDADZehJt{{5)aOAH^qcQK=@k0A~%%$UjGkaS}44{?k0 zHh~ob_>FYvw~VLBzQkxOCAqi?oGY$uIQ1R}qUz78+!OhgVz|`-RXbr*;^Ce#C$1MB zc4&&WH1AZkiN5r;c7km&+zmu0$Z0RjC$Z~UX_4-v_0ktfwq~mTNj%&!<8|66$t@MR zKJ@~D=olB&Tcj(9xs-I}Qw*tx z%1Z;}6gP{xMU}GPN4XI)}TNT zctJkY6-NG8%r#Tpr{7I2G6tapaPe@@tgpGL@iFuDc=}E8I8|9&m4H}vA=$O7SrJ>` z?Puq6m9ZcO1vz#)W#BK)t7lmCL5uj$$wb+H4feSENH)(nzUh^;cbz3CBck~)r>axGU+`TZhcLYq z!7Wa1VxCy%4>!(pW9 zy%-+^0IV`PrpKq2#Yszx>J@{+YpJkn6=gnm#PO3-5%4M7?_mOPOx2WFS-!sQVW~3} zTgskXGi*IDozbR52^y!T-l!&q1pOkG&nkejUOVAVY_s#{JH^kQja?-?^#ekMrTQ7A zx|6*z)r$xyW5+{Ccg5vi2=yeTuq3@K=+^cYfBpc0Q=)CzoNzC0#Rx zoip=8!6ru!XkQeH%W8+tyOp4;?lYxXU)Zs<#!u647K4(6)Fr+&rFTm3;Hn`;)A<`v zs{{8pZWqE^|JZzL_1+>ex4gx7Bqm~tIE0=4-Cwsa@YVI3;4ORRK6DgNw&y=0%0}lH z>hV|yEpDfwaeexOZuVR%lEB{5^ID-SZpGwh`>W}FcgK)`&({J*{}VGmMy_mzu{Q>~ z^_9doceN?RdmoJNJbiZB*ARgIEcTemO+@@&xrOO6E@nuNL4`#lDfAH!*A%>wPy5#Q z_0$VTlb#~YVuXf9&t;iAOvDD7;&pRnRlC>=WS(sxYX^6)++k$N$bPRLY z30S>S=_Ws;l+q@=3{ke z`q3b|8r6ku@*7D{92p=>-N?0Y@LylK**nskw5Gq0Ezv9$8o}D_dtZjOAKU-r_?I^G zRP~oH**UjpTP}$7{%57KKg@G}j9wC`H}(raNSkS0wf#%Gxm11At(;XvTf8~@s#af5 z0vi8S4pAV(iG{@IJ8G!W?j=R+6Ih9@z5s;)+N5ug*~?F8u7`Nr>%x!hxevJEH%DT$ zFL)$<-$$fUWt3W3zi~{7QoRO3C(b5l*%5q)blAdNw?W>AS_ab6J*?dS5}l-X*|vn> z)l5TKMw-*Miys!>erPzf{Yv$xG6et}*kc-=AkgI{9Q4f7EC89H>@|(jONCO&%rpNB z+XW>00j0fYLTaN+ikL|X-I1#HsDuI}IwVCCjFxAeaGlN&H@!$8&IfR}HYyYb?O^{s zH2!<*0QOFRgp5J2*r)A(xq=w)P9dyDGfKSxrT3b0e9dV{oqx1^145z9m~&l1)d3Q; zFj(>9m7a5ym3|i;8@huOZGe#FfkU_?mg$B>AxH=Z4l)J{+~3>t zV6oUd=5qp9^gF-!>^|Gjy>)Q@WE%yH3MHnI0>1ag{~#Oy0MMuY zWLru+QVgW+DLejO9KxY22~(PeYOTN|6kw%Arw&9MsZ&a2wh$1EbZ6xp5=1-+AppMo z17hEb4~qt{&)A{B{{M0RjsL+ofQ=LQ^5@XeQh8eM`IfT+_C3(Y^0&((3>A*f5E1j@=!ik@N#muHK* zaA3Y&(eM7kvxj0g55@uPoq*J6)RQ?FqW*ub;+@ih!3tkDc&nxth=@Ze@)5&)1{JZK zh-h>yI0ndh44vS}kO+wJchxBxM5j<72s8l3_Y54$gGcdyeo)5$;2Zz|(5Jt=jSdtN ze$xFtZw7$C5X~g$PC~q1o#LbLS4|<$jIdDTV^!_NcUwdvTC$GRH&Ad8opR1#MMuv6 zyC^ddN!K6}-d6|ZI}{L0stXV{2|~Cy@zG|57Ghboj|v%9pFMpFb@C0$=$V7 zU=$i;IJ5*QKVMV3OXb&Vl)0)Vq$fsh9v6$WXr-=a?v*DrWk*YH>Vy?G z(>s#)+aX6T5)$YVr;>91tV}pA6oSxK5ar}5Rg~q*d;q?p-+!3K|DYWJ0MPe*dE0Hc z5EAUe=241`mr7L0;OeF5z!*i_d{2(~0ir0%Ih`N{Nuv}wvns^tp(oL(U2$QD*`%Zz?R7LrO@+JwQZfQN zO_%!#4g$;Q;nd zfP*lBX#4M~_dr2;m4pK|Xe%`pw18A;@1)mLavnq;&t-IiLe^gVnv&y7;d>{+ca}v< zDGDGB6|usz);)-~S1xq)#JHkA__=3~!8RU+0{{T}%r-=rCI$uG#{c2Su+s!AwpD+% z+7EVKK&r|Qj8)0GFV!N5=)j@oTj{)=f^0fgat1KW2#j+Hq7dI@TUM)CK$ zI6t%tA71;4{_t@a|D$pM8z=C;^0eW=n||`1Njt?A+=v8#bx58Hcxw4EJ2USb!ejP+ zwRUHaD*vR>m6isl<QH$U>hB{=?yjAnm4Ev>7c;H;bdum`gc;3rW-f?qMzhZWlCaWwS^tjG!l8}}#|yfEwY{=047#E}dVI$JXdM6m z(D!bgz{|BP>X8DQO+(VM<`mUF?va+e5p y1J(&0g2?FzsUl-Ajo7^M%GUUQ_Ss{#gZ~ew$U)g`;}(Vh0000