From ff57c95aab54373b1d7eff3443ae85beba99c124 Mon Sep 17 00:00:00 2001 From: Quickbeard Date: Mon, 10 Aug 2026 15:04:13 +0700 Subject: [PATCH] feat(ui): repoint the favicon set at the brand-red C MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #10 pinned the favicon to what was then the TUI banner accent, moving the mark and the default-theme secondary together from #EE0033 to the banner cyan #00cdcd. The banner has since moved to the navy/red wordmark and the cyan accent is gone, leaving the favicon as the only #00cdcd in the tree. On desktop the mismatch was visible: the dock icon is the red C on white while the window and (since #172) notification icons were the cyan C on near-black. The set is now generated from the same geometry as the app icon by generate-icons.ts, so the dock icon, the tab, notifications, the `codev --mini` badge and the landing page icon are one mark in one red. favicon-v3.svg is the hand-written 512-unit source of that geometry. The tab and .ico icons keep the rounded tile so they read as an app icon. apple-touch-icon and the two maskable manifest icons are square and full-bleed: iOS and PWA launchers apply their own mask, and a pre-rounded icon leaves transparent corners that render black. Known cost: on a dark tile cyan was ~9.4:1 at 16px against red's ~4.2:1, so the tab icon is less punchy than it was. Accepted so the brand reads consistently. site.webmanifest is untouched — its theme_color and background_color describe the PWA's chrome and splash, not the icon. generate-icons.ts also skips iconutil off macOS now, leaving the committed .icns alone, so the rest of the assets regenerate anywhere. Co-Authored-By: Claude Opus 5 (1M context) --- DIVERGENCES.md | 2 +- packages/desktop/icons/README.md | 13 ++++- packages/desktop/scripts/generate-icons.ts | 55 ++++++++++++++---- .../assets/favicon/apple-touch-icon-v3.png | Bin 2149 -> 634 bytes .../src/assets/favicon/favicon-96x96-v3.png | Bin 1396 -> 627 bytes packages/ui/src/assets/favicon/favicon-v3.ico | Bin 15086 -> 4165 bytes packages/ui/src/assets/favicon/favicon-v3.svg | 22 +++++-- .../favicon/web-app-manifest-192x192.png | Bin 2245 -> 664 bytes .../favicon/web-app-manifest-512x512.png | Bin 6244 -> 2697 bytes 9 files changed, 73 insertions(+), 19 deletions(-) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 9594066b33..1bbc1c3e7a 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -158,7 +158,7 @@ from the squash message first, or use a plain merge. | `packages/desktop/src/main/index.ts`, `packages/desktop/src/main/windows.ts` | APP_NAMES + window title → "CoDev Code" (Dev/Beta variants too) | Desktop app display name. | Keep our names. | | `packages/desktop/electron-builder.config.ts` | `productName` ×3 → "CoDev Code…"; artifactName → `codev-code-desktop-…`; protocol display name. Auto-update `publish` targets repointed to the fork: beta `anomalyco/opencode-beta` and prod `anomalyco/opencode` both → `quickbeard/codev-code` (upstream has no fork-side beta repo, so the two channels share one). | Installer/product branding, and a packaged build must not offer upstream OpenCode releases as CoDev updates. appId (`ai.opencode.desktop`) and the `opencode://` deep-link scheme stay upstream — identity plumbing wired into main/index.ts and app deep-links; do not rename casually. `rpm.packageName` (`opencode`/`opencode-beta`/`opencode-dev`) also stays — it names the installed Linux package, not a publish target. | Keep our names and publish targets; take upstream's other config. Two known follow-ups, both moot while the fork ships no desktop build: beta and prod now write the same `latest.yml` in one repo (splitting them needs `publish.channel` plus the hardcoded `autoUpdater.channel = "latest"` in `src/main/updater.ts`), and `codev-code` is private, which electron-updater cannot read without a token. | | `packages/desktop/src/renderer/index.tsx` | Desktop notification icon `https://opencode.ai/favicon-96x96-v3.png` → the relative `./favicon-96x96-v3.png`. The renderer's `publicDir` is `packages/app/public`, whose `favicon-96x96-v3.png` symlinks to the rebranded `packages/ui/src/assets/favicon/` mark, so the file is emitted next to `index.html` and resolves against the renderer origin (`oc://renderer/` packaged, the vite dev server otherwise) — the same asset and the same relative form `src/renderer/index.html` already uses for ``. | A desktop app should not reach out to a remote host to draw its own notification icon (it fails offline and leaks a request per notification), and the remote file is upstream-branded while the bundled one is the codev mark. | Keep our relative path. If upstream changes the URL, re-point it at the bundled asset rather than taking a new remote host. `packages/app/src/entry.tsx` and `pages/layout/helpers.ts` keep their remote `opencode.ai/favicon*` sources — same bug class, not yet fixed. | -| `packages/ui/src/assets/favicon/` (favicon-v3.svg, site.webmanifest, favicon-96x96-v3.png, apple-touch-icon-v3.png, web-app-manifest-192/512.png) | New codev mark: blocky "C" in #00cdcd on dark; manifest name "CoDev Code"/"codev" | Web/desktop favicon + PWA branding (served via packages/app/public symlinks). | Keep our assets (binary: take ours wholesale). | +| `packages/ui/src/assets/favicon/` (favicon-v3.svg, favicon-v3.ico, site.webmanifest, favicon-96x96-v3.png, apple-touch-icon-v3.png, web-app-manifest-192/512.png) | New codev mark: the blocky "C" in brand red `#ee0033` on a white tile, generated from the same geometry as the app icon by `packages/desktop/scripts/generate-icons.ts` (4x5 grid, one-unit stroke, unit = 120/1024, corner radius 229/1024); `favicon-v3.svg` is the hand-written 512-unit source of that geometry. The tab and `.ico` icons keep the rounded tile so they read as an app icon; `apple-touch-icon-v3.png` and the two maskable `web-app-manifest-*` icons are square and full-bleed, because iOS and PWA launchers apply their own mask and a pre-rounded icon leaves transparent corners that render black. Manifest name "CoDev Code"/"codev"; its `theme_color`/`background_color` stay `#080808` — those describe the PWA's chrome and splash, not the icon. **Was `#00cdcd` on a dark tile** until this row was rewritten: PR #10 pinned the favicon to the then-cyan TUI banner accent, that banner later moved to the navy/red wordmark, and the favicon was left behind as the only cyan in the tree — visibly so on desktop, where the dock icon was red while the window and notification icons were cyan. | Every surface that draws the mark should draw the same mark: the dock icon, the tab, notifications, the `codev --mini` badge and the landing page icon are now one geometry in one red. Cyan on `#131010` was the higher-contrast tile at 16px (~9.4:1 versus red's ~4.2:1) — a real cost, accepted so the brand reads consistently. | Keep our assets (binary: take ours wholesale). Regenerate with the script rather than hand-editing, and edit `icons/icon.svg` + `favicon-v3.svg` together if the geometry ever changes. | | `AGENTS.md` | Default-branch note: `dev` → `main` (single merged line; upstream has two lines saying local `main` may not exist); added fork bullets requiring every upstream-file change to get a `DIVERGENCES.md` row (and matching en + es doc updates) in the same PR, and pointing agents at this file's Divergence policy (prefer config/plugins, then `packages/codev-*`, upstream edits last) and Syncing with upstream sections | The fork's default branch is `main` (see the workflow-triggers row); agents kept basing diffs on a nonexistent `dev`. Agents edit upstream files without recording the divergence — and don't apply the placement policy or sync runbook — unless the instructions file says to. | Keep our lines; take upstream's other guidance. | | `README.md` | Replaced with fork README | Fork identity, sync + divergence policy. | Keep ours entirely. | | `CONTRIBUTING.md`, `SECURITY.md` | Product-brand prose "OpenCode" → "CoDev Code"; built-CLI command examples `opencode …` → `codev …` | Docs people actually read should name the fork's product. Upstream issue/advisory links, `packages/opencode` paths, and build-output paths stay upstream; env-var mentions follow the env-var rename row. | Keep our strings; take upstream's structural changes. | diff --git a/packages/desktop/icons/README.md b/packages/desktop/icons/README.md index a11c05fe3b..69f09e4aee 100644 --- a/packages/desktop/icons/README.md +++ b/packages/desktop/icons/README.md @@ -12,9 +12,18 @@ The three channels are currently identical — the same red C on white ships as dev, beta and prod icon. `generate-icons.ts` still writes each channel separately, so giving a channel its own treatment later is a change to that script alone. +The same run also regenerates the web and PWA favicon set in +`packages/ui/src/assets/favicon/`, whose `favicon-v3.svg` is the hand-written 512-unit +copy of this geometry. One generator for both sets is deliberate: the dock icon and the +favicon drew different marks in different colors for a while, which is the drift a +shared source prevents. The tab and `.ico` icons keep the rounded tile; the +apple-touch and maskable manifest icons are square, because those platforms apply +their own mask and a pre-rounded icon leaves transparent corners that render black. + The generator rasterizes, encodes the PNGs and builds the `.ico` itself, so the only -external tool it needs is `iconutil` for `.icns` — which means it has to run on macOS. -This replaces the old Tauri-CLI + [Image2Icon](https://img2icnsapp.com/) workflow; +external tool it needs is `iconutil` for `.icns`. That one is macOS-only, so off macOS +the script skips `.icns` (leaving the committed file alone) and regenerates everything +else. This replaces the old Tauri-CLI + [Image2Icon](https://img2icnsapp.com/) workflow; the Big Sur inset and drop shadow that step used to add are now applied directly to the `.icns` members and to `dock.png` (824/1024 rounded square), while the Windows, Linux and Store assets stay full-bleed. diff --git a/packages/desktop/scripts/generate-icons.ts b/packages/desktop/scripts/generate-icons.ts index ba4183b7a8..0752c3ba8c 100644 --- a/packages/desktop/scripts/generate-icons.ts +++ b/packages/desktop/scripts/generate-icons.ts @@ -1,5 +1,10 @@ -// Fork: regenerates every app icon in icons/{dev,beta,prod}/ from the geometry -// in icons/icon.svg — the brand-red CoDev "C" on a white tile. +// Fork: regenerates every app icon in icons/{dev,beta,prod}/ — and the web/PWA +// favicon set in packages/ui/src/assets/favicon/ — from the geometry in +// icons/icon.svg: the brand-red CoDev "C" on a white tile. +// +// Both sets come from this one script on purpose. They drew different marks in +// different colors for a while (dock icon red, favicon cyan), which is exactly +// the drift a shared generator prevents. // // Replaces the manual Tauri-CLI + Image2Icon workflow the old icons/README.md // described. Everything here is self-contained (raw rasterizer, PNG encoder, ICO @@ -21,14 +26,17 @@ const CORNER = 229 / 1024 // shadow; anything full-bleed reads as oversized next to native icons. const MACOS_TILE = 824 / 1024 -type Style = "flat" | "macos" +// "square" is full-bleed with no corner radius: iOS rounds apple-touch-icon +// itself and a pre-rounded one leaves transparent corners that render black, +// and maskable PWA icons are cropped by the launcher for the same reason. +type Style = "flat" | "macos" | "square" // Coverage of the rounded rect and of the "C" for one pixel, supersampled. function coverage(size: number, style: Style) { const samples = size <= 256 ? 8 : 4 const tile = size * (style === "macos" ? MACOS_TILE : 1) const origin = (size - tile) / 2 - const radius = tile * CORNER + const radius = style === "square" ? 0 : tile * CORNER const unit = tile * UNIT const mark = { x: origin + (tile - unit * 4) / 2, @@ -227,6 +235,19 @@ const FLAT_PNGS = [ const ICO_SIZES = [16, 24, 32, 48, 64, 128, 256] +// The web + PWA favicon set, served out of packages/app/public through symlinks. +// favicon-v3.svg next to these is the hand-written source of the same geometry. +// The tab/`.ico` icons keep the rounded tile so they read as an app icon; the +// apple-touch and maskable manifest icons are square, since their platforms +// apply their own mask. +const FAVICON_DIR = "../ui/src/assets/favicon" +const FAVICON_PNGS: ReadonlyArray = [ + ["favicon-96x96-v3.png", 96, "flat"], + ["apple-touch-icon-v3.png", 180, "square"], + ["web-app-manifest-192x192.png", 192, "square"], + ["web-app-manifest-512x512.png", 512, "square"], +] + // Apple's required iconset members: {logical size, @2x?}. const ICONSET = [16, 32, 128, 256, 512].flatMap((n) => [ { name: `icon_${n}x${n}.png`, size: n }, @@ -250,12 +271,24 @@ for (const channel of ["dev", "beta", "prod"]) { await Bun.write(`${dir}/icon.ico`, ico(ICO_SIZES.map((size) => ({ size, data: flat.get(size)! })))) await Bun.write(`${dir}/dock.png`, macos.get(256)!) - const iconset = `${dir}/icon.iconset` - await rm(iconset, { recursive: true, force: true }) - await mkdir(iconset, { recursive: true }) - await Promise.all(ICONSET.map((entry) => Bun.write(`${iconset}/${entry.name}`, macos.get(entry.size)!))) - await $`iconutil -c icns -o ${dir}/icon.icns ${iconset}` - await rm(iconset, { recursive: true, force: true }) + // iconutil ships with macOS only, so everything else regenerates on any + // platform and the committed .icns is left as is. + if (process.platform === "darwin") { + const iconset = `${dir}/icon.iconset` + await rm(iconset, { recursive: true, force: true }) + await mkdir(iconset, { recursive: true }) + await Promise.all(ICONSET.map((entry) => Bun.write(`${iconset}/${entry.name}`, macos.get(entry.size)!))) + await $`iconutil -c icns -o ${dir}/icon.icns ${iconset}` + await rm(iconset, { recursive: true, force: true }) + } - console.log(`Generated ${channel} icons in ${dir}`) + console.log( + `Generated ${channel} icons in ${dir}${process.platform === "darwin" ? "" : " (icon.icns skipped, needs macOS)"}`, + ) } + +await Promise.all( + FAVICON_PNGS.map(([name, size, style]) => Bun.write(`${FAVICON_DIR}/${name}`, png(render(size, style), size))), +) +await Bun.write(`${FAVICON_DIR}/favicon-v3.ico`, ico(ICO_SIZES.map((size) => ({ size, data: flat.get(size)! })))) +console.log(`Generated favicons in ${FAVICON_DIR}`) diff --git a/packages/ui/src/assets/favicon/apple-touch-icon-v3.png b/packages/ui/src/assets/favicon/apple-touch-icon-v3.png index 0d398245ac43931b913da0a0857c1986b306e934..107c4126c63e56e3dc27f064236f6a2e4f36fe0f 100644 GIT binary patch literal 634 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD4M^IaWiw)6U~=?yaSW-r_4d+6-lhNs*TA*} zhVlYNp{(l(y6p)J;szU+Eowg2(HJ1`x5j;gz~aW@$=eT{_FS}Ok&rk?1}7LY>cZdx zRVZZL!UBa2)1Xl7f)ErkMZuthw?qB%=S#b4!)`QjzZHEE|J7pdW8Is#o48AvO)fYv z^Fj$WWDZbx3nNShswNkq)`1zw$#uwQDw+PQ&}!Q3yEZ)z>p8#FmUl2oWiaw?X<&;2 zD<+*Mm9e0a4aE$QQ^4lwf@OdN&}<-E4CHpW44FLpSQHOj6Mw}9aR9_FUStl)UCdDT z!JKld0Vs&Xxz+G*_q^#^-y##a^|pkQ98uoD$l`{^IA;bd#`nHw71cR$anj24%fK|n N;OXk;vd$@?2>|=I(z*Zu literal 2149 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD4M^IaWitX&Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBDB+SC;hE;^%b*2hb1*Qr zXELw=S&Tp|1;h*t%nKM9n1M7SNNfQUTz1O>W&|6gFzo8IN}#g2nIRD+5xzcF$@#f@ zi7EL>sd^Q;1t0|sHWgMtW^QUpqC!P(PF}H9g{=};g%ywu64qBz04piUwpEJo4N!2- zFG^J~(=*UBP_pAvP*AWbN=dT{a&d!d2l8x{GD=Dctn~HE%ggo3jrH=2()A53EiLs8 zjP#9+bb%^#i!1X=5-W7`ij^UTz|3(;Elw`VEGWs$&r<-Io0ybeT4JlD1hNPYAnr`9 z$VAwbR}A$Q(1ZFQ8GS=N1AVyJK&>_)QLBK=iqxD4m(1MMykejocBY0#HemG_G6)-y zbVlOTi6jHnX`>JF0Fs9wp#>HN2A3U|jXpf+?YMU6dxSGEuzvS+aSW+oe0%3&mWa1V z>%&={;Z26GoL}|6UwnQ=f{W+6Idk59WZ_!K?bPP8*7p8^309Uw+p0t=*kF zHYWNkT>>}6Pb#u8xiht>IcYMr=!GsfXnE!^Xjto)ITl!K`SxJNtIS^&rxbR_X8*Q) z*IUf7_khKo`un%Ij%oKFC{n(4|K7H3_okftW3~T6{Xd!1e?PxwS6BSK75nRqlg-b^ z(`R3J_io+Zzdts<-Cvvi_SLJC(=DFz&xwCwdX_15>dXtv*L-VT_w`5g*N?BcYu{Wu zen#<&)!koz{`|N%>)QVFo(YTo|333k#XjA48JCK~ivyQ>_V_kjxSjKcMM$9}A=B-i zn!}4+voa=50jmur%K5?yU(BSf8(BDHBW6w9&M8neyLYYwQwyKY*%P-}IQE`B=BL2u z#6B(UNiI{%y|iTY2@DIFy^TMaF*@aM-YD$RaG`OjWaVszh1+l5;3UDiXO`0+FMa4+ zBzD{TxZTg^YuV5E9QkC_8h1YF_s7TYBXcIt`B7YSG44at?%%&P&uxuXj-Pko^xc%H zKi@9*&;9;;JF}9%%D<|8cXyuOy4z>r^(&`ktG>U!{?YdG`qRQYOXr>T`E;YOvi!yI zUDui9?)U$HmTkjW|FmO$K*KzSh1F8mJ_7w4zmUO}(doO%n#aJP*yqGp#nkdHGvc_g zLPcJ{St>yLlW z)Y|)E^_zF^qN*z_teZ~@SMAi6U$_4DdHwi*_ZEh)+&j-Tp}hY7I{W&(-|z27@7`5) zZR@<>ho`H5@yeO_qPs<%&YjK!3 zO-l`DPXBgfHuz{MD@e!s(eA$1j&(^HR5v*S);P*mp07?dhFm z+KqSHXV3mTf5Ube<(@kWF`0I`MW ze%*NZX4(G*^I1;V2mdtdY1m)XBARx`kkP6C=M7$EhZh?T^;iRQtD*evL|}Rin^Ab2 zg~Rq)vUv}~!oys~?`AM8JYMsrO;DjEBJr3kFeA_CziR-@y4q)UBr~bP0l+XkK DJ&tZN diff --git a/packages/ui/src/assets/favicon/favicon-96x96-v3.png b/packages/ui/src/assets/favicon/favicon-96x96-v3.png index 2af0e7f87f8ff6e8aa5c8eaf213070cbcf317a86..ca3a5d76fd4b67a70c9b4f7089bd9973551b476d 100644 GIT binary patch literal 627 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 N;%#j4*B - - - - + + + + + + + + + diff --git a/packages/ui/src/assets/favicon/web-app-manifest-192x192.png b/packages/ui/src/assets/favicon/web-app-manifest-192x192.png index d88c83f86f74f44285e67792799a3379981548d9..0b19a6c5fe847106446fcbad37429367de59485c 100644 GIT binary patch literal 664 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zf+;V2by2aSW-r_4dw2-UbB`*TAwO zMfXJB<%x`G8`OUCL2$Kr}g19W{{Jp z2@Kd9Ho3nK*y9>0en7N;*)u~i1||juMur9k1_uTP1qKEI1_llW1{Pot&{~+Fw}^Dd zA0daE$*VPQ8#9P8C;TO7Dv1j2Jx%T0uHnr*fdLZ=FbI(aFNxp%#hNP>5FIH2a*d~} KpUXO@geCwUF!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBDB+SC;hE;^%b*2hb1*Qr zXELw=S&Tp|1;h*t%nKM9n1M7SNNfQUT=u{MW&|6g(AV1X6j0gR%#etZ2wxwoh+i#(Mch>H3D2mX`Vk zM*2oZx=P7{9O-#x!EwNQn0$BtH5O=0l zWFlN(lGS%TLato7BWWrW-f-k^;4E*2h3t%^t!HZ!+59h5(`JbuDXYu5BR32IW%1Q%I(ikzQBZ$ zY0A3z3Z@;*G%-?Ux%dA+Hg_k=yl7+jR=oH5In@JCKmGsw(7C$m^Rlg%U$$Mz{rZTd z?|4~7MMizipBuMagwCiQSi1D>r}_8x<-Yy>UHttS#ypP)@7}e|zMHrDCCiVG=k~|e zG2L1BG_q{ghuyzo>?fQJno>MP(V@X8l>3&lLxY@Xb}EO!0-vi*-++|+(I`n^umo>i zV9UhvB5-3^8w2C15Z#P^2F9w8HB;%V&EWpzhjCng^S%eg?>u(>?hn5cGZ?PF-fr9V zv1Z@DbI+rNZ`|e@g-pk1^uQK{lro)sY zqW9kK_EYSAC@!uWme$JWK@SoKyeq)0mBa=(XnM=UL@T-fp zheJSNQS!8T42+k;brM_}7zAZEe_`R6urG;GnTe(2#f+uu4h>&Kxg`V@99)j;*fKIL zSs!trgMm@WD(xkwfI{t2CN~xifs2OT{tXN-wZ#mS92z?MBCD8KJVvczI-U`c_3g`* zTi+gpzMGAow*Fs8}6>N-Cy@t_-+d8-=z7U|9#|seD`tk?fTzlS0yNo0a=}>vajH^76Moeir|JeRub@Z=e4>@omVyJH2TSo6rqNGC8;Rcf4oM&pjXK zPWWhZzx!Cic5Nm_My8eup3T4r{?_)C8yHDPl4s0iVBBP`6YtT$peT3v4KRZDCjN9{ zV&V8Gkp_(5H@v6Cg%lh*jvH7rGNt54?3=*A=w#D&6R5ZP@TXQ_1V1u7T4p?#yVCY|7^&3y_E4I_*DL4Vf20G|iS^S6R(d{0+Dmvv4FO#q#vON;;j diff --git a/packages/ui/src/assets/favicon/web-app-manifest-512x512.png b/packages/ui/src/assets/favicon/web-app-manifest-512x512.png index 20559c86049c7f2adc87cee0d6e794e095691202..c174dfb8c4984bf0f8aec6dc80992ab91d6a7f79 100644 GIT binary patch literal 2697 zcmds3ze~eV5Wb`jNejh-n^SS9YoQ=+rV`OYDMcI{J5}^AC{9l|L2z(s!L_S{F5=>k zxr$(MaOxkR;NaBB@AA?nrD>a_)xqU8$-DdRyYJoI>q)t^nM^Duh$vauvbKqIJnCf3 z;pe;7?h+-+1uMT(d;fgPC&@Ho4~LI;&1+h@$)2}q{%W5(7poc>M5gUYDI$p{L6pXi zMiaI|nw!7`MR)~5cg-an6(_%MlX=3+g$QKs@MJHoBc|osZMHsMk05eAj_eJ}X#mzL z8N8&aB@j%jRIy0P@)qnGSg=*ZlAr0X*PaFA#yNa;6*MUOouy$ z&Vu5NP+-bQ*r^LA^%>{q@PMMwuOAs%dn5Y`R;#l%X|68a(fAuu<*LAnLzQF z_{R9C-C+mLi@V5oGc?*L2NN_>T*slfjY1oljB;?2nV5P+cqJ}ZKa?M%>{RgFLEO50 zb}Sy$3wf|19Js6gO){zv)X4;Gf)HAH+w9K@O;rLafX^u+Syi@NSFPg95>PO-)r8{- zf#KepaHNKN^qDCH;5YQv$`|<;`eV5*3iB|c-$KFWj*n&@+((Z7=3w~ zU^s#i4x{%^L*hx$;FjMvB!KheDKTX3*$RU0F?Rz8LU+vvQb>bSq`)Q|BL$Xl^dqyo WM=@HXv)j{WSWsc3WL>UTj(-3m1o*H3 literal 6244 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4Yzkn2Dage(c!@6@aFM%A3)CkWs zUtb0-Ae)1Mu|1Q41*8OsrGOZybpaDhgo$ARGlC70)G(O7pMgRAmZytjNCo5D8wY)3 z0tH+GlLZ+rwU`tN3mGQdRIIod{7CNGi~UwtyD#mrwX@q-|5Mqafq{{UC5UN%aAvD2 zg!7M6f`P9QB+S9W%F~eWQb||=B*T1wR{+FlT+qNMpc9({lowD)VAugtD4-x9V!+U} zwA%-49uI>##H=PJHir!*6FET|8yFw30TntlI0PJE;FzXo1lDN4a0hIa00)-@!@*0g zYG93Q4bmX17?~UynH3^-odDV3aDbtJ8O%`7NMK;`7M}^$D8Y~iwsX|6qaiz*W+}>G z4`dH!v+lFAkN?dOukO%rpqoYR{PXU8Z#LJn{$YB+N0Hg1nU{%Wv{)Q1!+}KPw0a01q?){OfZ?nM3;0@sZ*1PvI{R(%ivSFi=@38ONjVW2RY4g^NS z09X}|ri0Ni0QH7O)4{M0gNpf;o$UfY_#4-sKmY%S{(q;215F1W|BR_{`^HFr14U^FXLEqePPflL`ek#LF@OYO)-~oMxqt{YFBU+7n z8W<;T|MS=ZXr;E}RQ;P6&Ga7++5y0ri}s3j6T9XzP@iHXhO9}5F`uq^NZ zgT^*JV^9u%0?grmI2k}AV~vX%7z1)*(?DH=6WkIEKZO~9qKr(gjLZve>^cLoXM(r^ z!zXnH@ZeY%(7=tQGePcB&`)4^;?DpcI}-sKnDp8R97u7%B4a*qlo6;^12_~n>hRGJ gA5AKQCUZXEw~FRvlCnB04;t