From ac6f5d1f78fd2a47b52d29e62ebbdf08d14127ff Mon Sep 17 00:00:00 2001 From: null Date: Sat, 1 Aug 2026 01:45:52 -0500 Subject: [PATCH] feat(seo): publish privacy policy, remove street address, prerender all routes (batch 0.9.3) Client directive (Levi Halford, 2026-08-01) ahead of Google/Meta lead forms. Privacy policy: - Publish approved policy verbatim at /privacy-policy (src/data/privacyPolicy.js is the single source of truth; 292/292 source lines verified present) - Privacy Policy link in the footer of every page - Effective/Last Updated 2026-07-31, privacy@queuenorth.com as mailto Remove St. Petersburg street address from every surface named in the brief: footer, contact page, schema markup, SEO metadata, Google Maps links. Collapse ProfessionalService + Organization schema into a single Organization with areaServed: United States; drop geo coordinates, priceRange, openingHours. Add the approved US-coverage sentence to About. No replacement address. Crawler visibility (the site previously served 0 bytes of body HTML without JS): - Prerender all 19 routes at build time via src/entry-server.jsx + scripts/prerender.js - Hoist title/meta/canonical/JSON-LD into ; renderToString does not do this and react-helmet-async's context is empty under React 19 - Serve prerendered HTML; return a real 404 for unknown paths instead of 200 - Hydrate instead of discarding the prerendered markup SEO/perf: - Titles <=60 and descriptions <=160 chars across all pages - Add BreadcrumbList to interior pages, WebSite to home - Generate sitemap.xml from the route list with git-derived lastmod - 301 duplicate URL forms (trailing slash, //, /index.html), preserving query - Immutable caching for content-hashed assets; no-cache for HTML - Split the 522 KB bundle into app/react-vendor/router/icons - loading/decoding/fetchpriority + per-route hero preload; drop unused asset Co-Authored-By: Claude Opus 5 (1M context) --- .gitignore | 1 + index.html | 5 + package.json | 3 +- public/assets/cabling.webp | Bin 96816 -> 0 bytes public/sitemap.xml | 88 ----- scripts/prerender.js | 201 +++++++++++ server/index.js | 84 ++++- src/components/SEO.jsx | 3 +- src/components/layout/Footer.jsx | 26 +- src/components/layout/Header.jsx | 11 +- src/components/layout/MobileNav.jsx | 6 +- src/data/privacyPolicy.js | 527 ++++++++++++++++++++++++++++ src/entry-server.jsx | 30 ++ src/lib/seo.js | 45 +++ src/main.jsx | 13 +- src/pages/About.jsx | 14 +- src/pages/Contact.jsx | 26 +- src/pages/Home.jsx | 66 ++-- src/pages/Industries.jsx | 7 +- src/pages/IndustryDetail.jsx | 21 +- src/pages/NotFound.jsx | 3 + src/pages/PrivacyPolicy.jsx | 164 +++++++++ src/pages/ServiceDetail.jsx | 22 +- src/pages/Services.jsx | 10 +- src/pages/Support.jsx | 5 + src/router.jsx | 31 +- src/routes.jsx | 34 ++ vite.config.js | 16 +- 28 files changed, 1248 insertions(+), 214 deletions(-) delete mode 100644 public/assets/cabling.webp delete mode 100644 public/sitemap.xml create mode 100644 scripts/prerender.js create mode 100644 src/data/privacyPolicy.js create mode 100644 src/entry-server.jsx create mode 100644 src/lib/seo.js create mode 100644 src/pages/PrivacyPolicy.jsx create mode 100644 src/routes.jsx diff --git a/.gitignore b/.gitignore index 24fa201..174fd64 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ node_modules/ # Build output dist/ +dist-ssr/ # Runtime/database artifacts db/*.db diff --git a/index.html b/index.html index f452469..208ed65 100644 --- a/index.html +++ b/index.html @@ -29,8 +29,13 @@ + + diff --git a/package.json b/package.json index 8b77e43..2c9c1a9 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "type": "module", "scripts": { "dev": "concurrently \"vite\" \"node server/index.js\"", - "build": "vite build", + "build": "vite build && vite build --ssr src/entry-server.jsx --outDir dist-ssr && node scripts/prerender.js", + "build:client": "vite build", "preview": "vite preview", "start": "node server/index.js", "server": "node server/index.js", diff --git a/public/assets/cabling.webp b/public/assets/cabling.webp deleted file mode 100644 index 5243ddf65e462fd2b52c569619a12dc1c8a06fe2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96816 zcmV(*K;FMnNk&E}dI11eMM6+kP&gnQdI11%s|TF{DgXum1U`{OoJ%F6tS=*TioxI# z31x0jYc$#rKEeL4@6VkTclr-EPwf2xKCkNO7=44Hvq*o#bElEGx7Md};MzG=so{QgXQhyFh_?{e>p|4-J3^so2c z!avu&6o140&iDcT3;uVi59^=v|8~9OzxICbd+q-f>O=jv{)eYev={F$u@CO2tiS&c z-rtB1?H~JnGr#};^7jD$|LwKWkK@1jzv=pL`G@wu^L$DC>)pTJPmJH>Gw1Q2?Rl&B zsrr7if6M>j{^!cy)&H>n)&7^*ciUg?eOCWN|1bM*^d4jUFZ}P@FJfd&9I!Sh&q40`n*_A zi4`28R(8hi3K#6oo>{(kJ!>^;b?@w&U9yAu!--)Fib%^Z>&P0FD`Wsp-EukmU1T(? zF$ws=oRK=Bp%bv7nDBGu5@{V^Uq2+D&CY<|f_WAq5yS;QzJ+rDNgXhkuYO$44^1;r z*wTsV0$CVX#oUBcDq8>*7zXimY|E7Wr7oSW$s=ahyN;M)hn^-r^^^oM9K+N z!7Ot2YjC9cRM7y~+7zySa{2hQjGINz%Pdyh@Mo{PI!1q9;F2)HJK)cL3LmE4tk|3M z3wK@jo+%fiX$7N#@F*iHDD1!|6kOgUf`3u@^Q2GZfO@FGWWD3Uk;uk#-FRk!cumVd z961KR1)bQdTYW?^jz25i<2OITwxp)8U+w9=t-yoHUvDe)cm)sO!*g3;cH2^nrWNs< z3R5^-xq$BE%*$6E;;foe-o?OLk}ucu71-NyJ|%FaR)+GJiW7pThf+8~=zlWP`6A^z z@1Le(u3`?GSTj=Xio&P#EmwS@I^*Z0yJ6mQH)_G2+gE0;`t=7)1B3!2Y-(&zULmn4 z=`su4k_jnFX@zJ~OXxJ60+~TL$7rhrHCQLgU`q*sOUE8Jj*njV!-`8P-

i5IQ&N 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

g>3Fn}mh0uM>jm|eDkDMk5>Gkk3>jR{q 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

rHSP*XK!2$% z4a*9Pp=nz4?q0%bYuXD9$ zc63O4F3kmg-(D5UidGOlUme$p|4EB@_aA1fs)TAq)5?DaK1e^Yv=8CIWsExJCGPJ> zmJ7uQKoaXFUR2OC^>4*2@Y(}`$JQ4g3A6(fikTFL?S%z8N)RzB($?OIFJ_poI@X%bV{Y>mNyPF#;OqeVv8OhjB`pYwI3Ix@J}I(v12nrFX@6EcZTz-CtAVsDm3ThV);Cw5y!A{1|gcUlF`~Q6s%4`;A5n!TeIGq~JVLTC3UGbz#stb6h z7^w@zq`qFCTwkbJLSNI_Ka@$a$sYSObL1+rJIy(5RDUlV%W+q7&Z@2>o7do=Fx6LsZ_8p3tDIHr-Eh$X7LjQVJqx!}jY{I$no#TLDBkh~L-lLUO62ah&&0MUD z5(&t|CrbmUcLCXf&uy#KDb6e{V00wF=Z)}`UsTC`6a`U2F8(jn{b(9!o~e9PWOs`n z|CSR{QXMEy&yEILLTMVs1vk-j>$&EG0f0qLOy~kwuH3c z5{nsB>tffS_06rb%E&IN0i7c8a-L&v)1`M$q1FP2Nb*{oEQwWubbYzpvf!Z_+}(2; zTnJEU^X_b%q{L?>OuM|AmG2)eJRGrM3^7; z=!Vk4#wpN15|PH%k=LqthRS2>^*a<3?5F}vliw~ChQUB{YXyI52M9E&_Z=FQL2XGD z!p~(WiT~YYSp4N2u5!)I2?DGL0_w>d>OicKQ`ek78xO8BpN7CQjmCz_gN?_gnSBcaftTLz>VNxS#PR-qQ@@3URx_G-SzGAz(eVU* z3-0g2nQ@Uy%>hB`axo8(@q+^dcJFIUZdoB{_jY;c?Y-a}RXFG0t~>Tl?Fu=Xub=<$ zbb>4YnM|T&+dr& z+i@f6)`8(S!Ix%Si~VEpPPgb535c|r1yw>D%7W-GKU4IW9E;(CEpg_!4| z?jz#|aPxcWEUH)dn)c=$Bav|gQ+p{|$`!N=XMdu9Of`eXR(4-caO^*z=4Hq=7A5Lh zBZ!vbF8xBZJi{Ze=VOF!;f{10u*c^|llrB0M?H6AKJ{C3_K5RqWY$^bSNIu@i{_i; ztkv<=Hg>rwmr~2^>_h#(OyQwh_CkzGH97lHkSNTFQmxFj^&XqZNPA~)mO@&Zh=|3v z3uAnd?@nEgHwe%TJ5A5O7brk5hUSuofi$9 z=b$W@56ruhXvlFS;!b*#WJCN@z|9o@A)!_mx2Q^_Zp-5|KYOEzm2ReAdt5h=K@!arO#QmMRE~IKIx)^y9gT*V%+EN0&f3tOwkXQj zV&`xB0q7r4+NrCr%AA^O<8@!U|5u-xMqcj`7)a!MK7<5K4d^d-HhySBx~ z;L8@Ue^Ym3@_k6EeOKPJhFLghUNdC}ttyCZ>B-UU4j-ds!iG&DW|9t0dXys*@oY1= zFkZJ^BgY(?Di3T{UbGiy=;&$zYO61srly%XF4L1AcHIR5!+@npjq4id7>y`4e(BLIvM;PK^oWo@O6cSv+Fm95d3po&0VN$oRP99|UAtPCJNlW(wpLoZ9g4s{C@T zJFFsO2k1E6DQ7P70OPee7hgZm0a8;%I$*LXxIQ_;_PLdr$*BV==5pxDjPyJw*uqZ8 zcY^r(SidlQ7RjirP{{s{H@u!NYz0bw9{Y8GjxOvMNy!7o;1RClN~IYSq+=<-G*=TT z?{YV6_8ht(aWs}Ng4^1S-8PQTY4wUU&sQ_O9CHV$fZZ#zf6Bzn2wMd&!-v{E&B2Py z?VWDQ+po&9I zQm60DCdU!z{CN(BXxL6Bve8KK)P^!U^4RsaGq`X=Es%v&0E?Ta3i;)l}IQwPLE0Wr^puH}EMY;tSFCC!-u zZ(W*0qs$ee)7yE{3q{LyyCbT&6!{%_dVy=Zq+#|OVZFRYHp9}@>D6wp@px>05PV%^ zI)v6G$+(qNgu~jNfsaRBzTOM4u47*)?eIE-XDwU3afMJDBX9=YmBB)u$va0s{*};! z(GZ&l)%N_VGIuCLXyouAQV@A#fDEcmCIkyHm z=1t-sPA>9sP=r_1S9U06^m``S*TApnf-NX0JPiAbzO>x`8QFfL;|w~-E?{UV65>YC zAC8q6l{X!6d`cpoc>UO_y<*_d-kX~2n*NvrfIDL7;OP4TgS-s{k+gaN`cEVEC1gik_yAEWqyx&q^#Shj{oGi0|-}x zM%b5GNu{ONFZ7756e^^c|9;Sh?ORvyE(9tUToE$=66g&7)UneK{7RLFnEF+35ae!) z+54W>pL_Y|Yq2J)egKU_uLs6WNQiN5xR}VXPV)*MT7E&4LU@!+Y9)B=ybounqfll| zT1-o9w10YNn!s@_@^#owgCLsE01|4gn$+<#$JTVsfqi@{D9E7`(v{@`)t?nvh9Zw# zASV@Xq8A&9YE)5B*H2PTw@@H~Thxs(YKop#&XONs<2PTu4SK%*d!g2fp{YOvSz7qX z{2ywx-{Z9e)SHdugZ)>{W@5!KWz8;oLSB=S+H}vVAampwUT*HlK?mh~C|Hoo(IEl- z`4DHAnF}qSBdJUSp4k+2nAG*4t?TjmiIQe^H`xn9>0n{rb62qe(!rzG73hjaD1eno z8B2^y^GO7F8HAE4xSkR{!uKU=2j!CWXojJkCSJXHr`RyIl$}UKOScK3GIKG3%oa0V ztb{{6bz6ur*c-Bw-;I1BE3k&1XR1VPWlDSa4cv;B=EaG=r_FJET)Lv&^|75?d3@y% zd%V1B#|YS5exFlKTNUSEGN;6M$)iD>PL`v{zvmo+{@HAC-5PXbfnBN}V)JmH&2Iaw z_gcAPS>uTrebh2tzA?tEG@wr((0ltxnMKGsfr|TcIhG*z5A1iwUA;EM0Y8axjQa)0 zd8)t_H6n+;UL~)So1q8e574xHkstuMsie3zbW;z5*PZedrcYNQ(AQ6<@qN`dY<||X z10bZC#N??e2v&Q)DjKy}b$k_wZ0zR!3%>5xIm&mAvDm}nS20?xH_yfqh1=_`se4JP zv?7?-`C8DEA<-Iwk=lC79P)e!P1h2)S=lAzc5UVxXgC&SADkyTGXv6nXsxkg$9ljB z!ovNJj))n7PwQCpV8`?GGN&Tl67PZBUziwvfaW>hxcSFZGiOfERsY*?^I0SOX&C33 zyFljmmIuAkTjg(>HKsmf1H&HPH-*N2?Kw5i4Z~BSwe>5_m7KEP{w4ZnW3vpz8RD?$ zRzJ%vG%~(pd98IJfqCXng9v4-yW1)m#7WSaXgvX4A3<*noR15!hI z!M(GqS?e9`DBv&jDY5sjj5kB$;HWnn#hm{s!x(@@b9g zC9RFS+lB14aynEQshk2{xqBjUpl{|aA z?QYv`?{fL@g$ug3=8Rck`8kWk|E3cx5h{~?OZQQozK9EV`fb9lKq>-0;;=Ywdwq$e zju&ILv-b2V7>`a`sXqJ*ssb@1KIBx72J?&Y`Rd+mUS_?j-pAf+JgTXMB`-{K+)@ff zpyLVxE)U=XgWGXm=4}!~G=@HX{i|qz+x87?6V3}v7VKJy6F!*Y`W9pnve36Nwa%P; zdMymlX=>Lu+qvET7!+AyCa!cwS2}k~w)od?NZbZ36t=-fA+uGfzMi&AJ*5oZncIc4 zGeyW1=X#COct;}URX32nB@qfuo5vBnOs!28rWu#NU{jmQF%8X7zq6%|cW?vR!`&%q zbdFO$C`sSWL7t1X87Zo}=!3%-iU&83BA@GDiIWsD4uTlt^p_M*Eu>rgAw@<9-FwCv z9GF(P4@q=nHlulTyEXcnfMjc=!VMK-zk?T~@PQ7J*L_3YFeHB8VIWf-7edh~7(rhg z@FHC{?J#CNkXf4k-?-PRu^W>I9Q89mBVQ1(wpHjhxG*8vYdQW6BEoeb=?mQ9K`2>t4xY}?6Xp-DPrtEUYLRp?$UQ|049$wGi($$_;!XH+S|7|LMEF3u*!rJq!Y`}~#UqHJ=!@l`-zVy*a^Pb+Y@ zBau0#OEbYj$yl}FQ?X+4){z;**ML$Sxw}65T<~x7TH5uoxMh?nGH392&BF%NOdMo1 z++a8FwDoTrd5sjZv2Vlzo&<*SiKmSS1UiZ%y_t7BsoX^XC!fKp2rMX{^FQ^UzC+ea zlVsL`-g3e3PDurV|G-h}^$M*ZxDF=5RfsZhl*bOl+Op3IkBW##${>y`!d;a_zLAz9JGPAl7cWSD@tvKjpDdRF76X@8PAEt zq_*+`oeAg%SOvGEt1XZ9m1$S-&W@%YZF4%{E~yn@S1`IH}v1E@BW*0RBz z`5#nnY5!-i`Np|NZuA;oGCCoLE74m`LQ}Ok0EP=>7}c8hhX)kyf%r3Yh>N!w#?I~~ zh1xu$vV7dng)HO|*b)(xhs*RJwDafje}t{LYbQ}Ca6hKvTqs9NbK zMB6r`2$P&@MJVv^>)-)*b8zztv_ImAABa&y({`ViPU+)}f zk#WrhW2B^d053q$zr5WOLw=2kXv4d?SSP*CN$gl70}cMGcfU6Z2iZgWrc7?@pU|EKQjKFq-hJLm*qA% zvz)CIQ8(Hc9U|Cy(iT1-BkqoOKtr00G)HsR>L_rCET6)AH>liPJ=TrL?JR_I3O5UU z0{?q)c1t<{D&4hrH`&$Qlob*dz=G>;Ry#WB2rT zeHu4|W)69|v|S1wpx7SS%DFM`rW|h)^D+6gji;#73TMW$K7Z|SnZQ2n^EUY_;`;xn zwI+0glI#_B^J-W?Mp%8Q?X|IeCY5X~*V$ikX^AdaJQd78s{Zp1o(<-%ipn@?vc`O#`z6I-E1d-nH}lx9`oj>h^@ zV<1cG22Pk5g!(nf-&t+P6byQgm{n)N-z2ZXKHH7z(PCf*+fofC_l%IP-P>IH)4Bwz zANR5AyvBD)6(NWc(qDW{O3y93gu+%9+MAoE+!vQ3k?V;!u`(0`^~|V4zz0*(yRS5U zfgM^d^F>90>9w1jS!Q_2#WW(egoc&g=g;Ir-&i;iU4h@OAq?x>ci`9p>#$&xAQM4C zXr}7czm|LW1v+IFLNVOc^;br@r2`nfQ&hs^S zOn`DmnqQN2Lp!7Sm47>k87e9t>UqD?fr&*JoZ4Q~M7&(2WeraU7e>j+FUtl! z#-(yL_^8!%ZD?0Orf1wU2*t>Oq^T>|u3cFyqP&p}Jis;_r8`0?6`ckyJ~4AS5j=Y6 zrYMcTW9)>bL;b}#pGs+gqAYoX<8G)b8cQVAYn)@15l6a;(M`ucLn#MCUI3Yl>&rbd zBt*uau6+a-%0DvFI!^~QBtW^C$^@Uw(^noD^IU{!4ijH^;@L`opTYf{|e;sNQba@VaRG!H0TSiTI6DqSLB_^KcvV$Ti8W1#qWx zpUokH{4r%WtqRVMu`$U`i#eyz{P9GUK=vPX3s$W(?e#~CE*5q16C68R^1ZliAPh(4 z9YN)b;4oNP(&u_AU4iL)n-{V4=U=&;cXo3p1II=?eatW+tuc6pQnQ2Jm}Hdh_p_43 z)ZLXi{yUAuDur$kc`!CXOEAfiKW@T?mI_F+olS5R4Qf5V7cmTD9j_SE@cj4IBhJP< zenqmo(sL|TE%WCX?puCZAa>9V8}k2-fRGQUlnitxAU(K3X}^*9$Da|7))n=fnRIQX;Vex9hhwvFbpLfiIP#mH@Y~yhi zXSu*V{;tnWiJ}z9LL;{8&ZPX?058E_Qtn0i%VSc0Kd2kBPDJN`b}}cmUB!!%1U}oi zzuJ&y_kvF0wEgLvIKT-g8h&du>SFCY5ENR2RxLJ5OWzYZa4n}VXYO?v?g z-reV)Jjp~LTOIsQ-i0?mDb*}nXbu^3gD>K8p#G5X2(b;Z09ffBYl8Y~b>MnfgSET@ z_BNsoVeC)V>vfo=lDXsmv?|w_?T;k9x>Mq< zsM~1DR+22hB()N-?#Opvuh-GA($)>mZG*N+QF=6P(pA@Lei#uuc7M>q{+(Q)O49o^ z^`+iW$-hoKy^NobX(>pqjqS^US(3$dZ==T;lIJGG`uz%$1~m-#BbqVfmY0owXCY1} z&2mp}Wf`Mi&8e$`mig!Dm9M1{Ip{tT4i=!mNEzcx3){$DiHWhkd-EA8M<*B9RMkj*C0yeFF1+ zR%xIGvk0H(Q;b8g!T1=gAdjg#u_}M6*z{=cG4C=cpgi=w&{;-d0c+%fAyICSchD~c z60T8U!Ej}I&XD_|kn|TBi&8`v^fBa10}vW9v3-Ue9+;m$9Vvztbs`!|YDNco{y7Y= z&2@$%q)odeY_n26Vp!H<%_Q;!;6jmZV}4*bWu;LtJ<0#1M+`_B?C<(`!1h`(f9O0Lal=D=-@gMj`QQ~(dadG$3HZz zVY19qkiJJlr}T*&ZYm?HGN0TNqC!bg;*2`bOZsm)d_knXKWiQV(_G`p;U1**B zL!L=n|EG#-H)+-7I$;&FbFn#RXmrR-BmLks8i&2+%W6fl%I|HcrH(Ml!Z)ViZ!&Wf zx84b+9%ADBa}Ma5&SXO*gXes95U=NdBKc|9g3_kYr7srSA5+FD^$DDgdt@&yslE7k z5+vl41V=Py{wG95Sj^tC{3Hu6^#Blrkm-XFhjr~Q#T_Dcj*l>d%H`lpQyQ7q)=tVT zjpa|96H`*sYWBr?O27|$-QQEUdU#NaY=N2mWO7258-zChInd!wb}_th9`^Fa<9p%v z#zTJVB_e0|&<4%{!*rg=3e9I*>;L27d@fWqSE4G@A4Vx|dE>rZkmw7ykX9*M^tUL4 z;0|!e&B`>eMKnk*_iffN=pvQ`z=QwNs8x8^*rCVpVCKJ5hj7GNr5DX49ZAP0&4qK` z)^943r7|cf;Sx^=zOq;EIS&uH@2@_=FJS@xFJ$wJOm~xXymG&nR63O{i-8sB>U7vB z0Ibg2UK@LX6}*)IUsgp2aGK+yq4^e4Yex;JpV! zTinOo7qRg>hXi8uue+V6D4?zjVz{i|A_I}Vl?P=#`AqCgEOjyJq;b7D)pj)a-d}~( zF5+%_2`^SAB;^&()#jsJD`-I7mc%GsOz`I-oIrDy6m-^BxNm>yj zH?aulJM6e6K->WZ6gJbQRxK`mABUO0<8s)3_V@OGSFzdgDbvz^<;eG$pw0qIKwE6OHhKd;%KI^CIwO%k zWd~C7x!(or*CC&tc(iK3MVuK-*rz7DXU;FqljOzLTR6z{Ne>zdGaGE{^IoAslZH*W|ZL6^GvGD7bY;3OD!%BGYF zbKPX5^(-yP0&q9(&0Y-)@E3a59uAJ$pN#5UNN(Dg2cdAdHP-6kn(re7m&{k>s0{)%zV==r~P-ArnRSe?2Ma=_9jpLDrX1FEui zTJi+#zV3%nJh+F$>U=|y1_GAbyYHFD7oO0JIvLEooI@Afa!M(ZAKipiQ$ZvvPxoBb zXCMt{*!`#MH=h}AlXIOuA}>vWF-hDh&4Iv_V>sS^u+D+8Q+R7BT@Ei38Hsc&Q^cRtEU-71(2wclTP zHWvl%Iu1D1@u)f!u)M-!xX-TO=#a{H@v$XYd!|QtZMdzhH;tn=d43=%3SayA53$41 zV>CB4-vr|Crq=u1vb8g6%6c%}(Ta5D&;d*mX3Sf4jLIv3Sdg@28eVrfcCh*!TK4O% zGJP0;(Z^J_(*_-zjFqYM&9S%42B{<$t1!=e+Uwj;i-Ps6?}@vP!m=enj@WbMopPZV zw-i+!uYIFXXIk+-E>#f6F%MkAlH;y$>`<@AX#iPdUL;+rIvbV-{q~o`qq^L z1r+|mvXdzw2D&9H%Se#`g8?7nH4OhA^C^3L@#4M?PY;pyrFo$c%e7R9x2)y|fY?2< zpUGnOB1w>`4*QX=6gRGB$S{7~mS^i;HE*CEKWxMrA7c1<($juMJyI5e^h1V`ovf&P zQy^h{HR^0{EPaQSuhGllakeQv#9b=K^lU;`w#D>YClHSF_Fm?J^ur%GPd+JSXUUlZtl3;S5#B(v!%}brBOEj>R zS}L zLW@xiEoWXD7^y-{Na`ZqAfAql=+OaQ51r{8CscHGoUwOlrBFR{#rYxYq`?tNbh^)X z0V#Hw-OrX^ZatR~bt%oC9h<@rIAZh`9*`_R$KZF!ay4_I`scxo=vM#GJfzb~%Qz|+ z)5Enc6$@j_g~Udgyp{7u=%&w-5b(MvC;|1l&)8gnfAs4PeYd@G$TQRvlhm=|qC>7A z7x8H!Hi)e$d<(AKB)-1XI!b(Dp!)`5sLrPa+`hlWpVi?794SI)zX+rq2Mo8%X+Px=kChcrql@PbC zTJN>f$!+##WF)n}@9lS?tvK<>{L$eJ3sLKWJLwfg_Z|@(3Ht}*uhvWN{Eoo zSg<~DA)3ojO}D(>`pTz6cAlLE>0SUfH!OwverGbmVb=bf6U%=`pnlqqgNe zAxeQ^Pamx#>}?eMR3`^7Ljz6#&wZI)NZQ<~7{z4}??o%DWF`%)TvwE|uW0P+S2wjg z>XD%>W{3l<1*fR^oT$~08CLN)EwR^#yqT&^hs~23<>eJ{YQJBKiAN>j8VwnXTNvTo zLF_bR!9xb74>@&RLVa7MI<(@c?_`-RM{*K=S%o~&Cqc0o}{ zfJ*E&>W!P3v_ia8odDL;`Q!zR;|=(i+ytD9srlw8y9fT&o}3>>!8&lgw#UDJkI5|K zXNHTfmkLR0ibv%6OI}^ePOz!yBaD!=gege4_v<|M3K;|X%4kbXogT@_mb+#(@xriO zqc7%zUwHf$G8y1;E>0brO?r2oe?!l*{iA$ZS-?7l2K#&nFlaUxQY9eKnrt8s z^Bioa-%M%{;|6=p|FV9R{%&UeTrxAC%c+`a&HjVjS}N}3b;4+Da{FN?*5+Tc-^irj zBB@+5r3BnNCF_Pu+vnW?kkaJzG zS>U+DKuy=^gGu~TK3uf$fLxfwb#iaSC>WfPH`RTCxxD^&+nr;Ie%#~$jc7Q7GV}K>lBL}YjdAAz`aUz>_rJpIcgmq0HJo^?QL7Bph&ME$} zw+l(ZWgV(%8d}%52^=o?1X05dEwBcH*;hbo7O)Z=F;bJdggLDYLgRoWY+*JhRt_Nm z@<4uIJ+XwTm)%4eb@N*f`Q$+2Db^@Px|}(c0(lr}dzQkcMb%s=!=YxeQ(IH=k@+=+ zW5~frlxw1mwcIOmMr_ZMC-APV4Z)_@X!G#cNC{LsYl-2Cb`XEP{z%KH=6`r>;DEo5 zta7i3yE7N4MO2X_qZS^UXe6&>*F*#W%kPQ@POserkBAtp*fX7EgV6!H?S&htUmynX zmv;dTaE&vmx=k1=O(flB%%nMocok&Lx^w8BBhNKZf_V z5tO$RSKPVL=JIH%Vf+%f-Ob^XkOk1t^A6QgrC3(r3rSj1;@hwl8p@e5{mB~-mL)ON7ysC3%&*N(&>=43-O}aHfI=8P77quN`k3V)qEe|bFSdBE>;Hw9EVu== z=!*&H6Dfmpc~x zy-Sj5OeP)!k+N2S_7Q+BO8Ur#{?ub#NlR;yWdw64-bMCmf;ILwEk#tuW{%me z6H6^LTq#O&d|O`46mgAFhSr3LUfZZ|84BEu*Pq9W`19#XwX+ow+UfQ@^-hK-nr0)d z*aLmwQMA}l2Rm~j?jdUibKPedm63=%ZBS(0t# zR!$oY|KthH`3Xj2qDgx0q+HsC#%kR@rU@j-t!a%cB;x{9U?+W@S5y#LNeP3M-S};} z#-h0|4NYx9$jY~6-*_#mB6Q8Tfu{E$RTKYH88EsQrl55cc)n<+*or56T##LZ8{HFJ zG!zKaZ)r439hgORc+2AfOW)t^H-MWY{_N4e-?1Il;v_mw^y{3sn(V{4>QY@x8e_&} zugIYSvi3OWzn%c;!We6{ovX21x*}w`a z)D!^M01Ie6=UP%~vhfElLIR;H3<=bCZ6%zEg+2)Kx6Egm$HJddr$faFEfTfU zL1G0#RV3o+4WBea>LhI0Zoz_Gd2dmZaa^nJ+EGkzp_sX{72h?eC3_pQ%>Ho9?+PSu z94#@0b0GW8kqjite6^GYh=|U=@+L0+h0C^NA$I*wOg;}R)1tvbouf&6c8JB}dO2J` zT%;%VI;Pn37-xkg4Xq~ojg(g!9g8L5^eLuE8S?z#yo&m3`h5eWZ3lL5Iat%=q62Bh z-6KSvq3CY()l}V8Z#YehWPQ`r)Ew_~qV`d=LxxG5r?EJzZUSFtcML=@gJ-qi2k1hX z!KqmR^3yHN3p*6xR~pz9ECDpP!s5d!Cg8>ne&@T1@2uzVj;8Au=jETC>k}{`l=Cru z8(FY;!}dvHFTD&)0dYgKV;zNSu`5Y{-yNYa&;oZb4o%r}!G!d+s}Ddm#f)N68UyJE9(mjc!Z*$L<#+31^MAkkrv$U z;5@UC>~pO2dGix^Ht{{r7Xl5ZI0`YHE_eJg*)qSyAj%5 z``k>4aQ{b#^C*mg9Cr9@6kFy(ZFNcxi!AJ?Aa(>EVjBHz*o`&%-(L5u39wjWEW>04 zJ^K>trFR00Q}-u_HgYAYc%dbtR4}PqC0f3fDF6PW_wKUfHzR%c(ZoeVtcL7ZQ0OD& zDYMijszdW13PK+i`}L|_0VxwPK9#m(k%zfIk@;zyu&0N|uTB*H`gg~2wCOHrdY#uUeNO5u@5i9mQfy7+S4!-k@>kIb^7*Ug zPHl|TOwh4NM7_&RjQaEK8;Z9oVGad_1XqL(+VU@ zWa61Y?>99{Nv0oiFlS!5WgNnUvxgl4)+$Q|AAdh2(bEOA=Q<(?K)(f9qhuFh^+(*?>@ZwYRBDu%H zSq)LM=@{{t_@Or^kHaPV4-fD%P8+mwu>1R+{(&?uP0Yz4C)e}8W2c8<=3y&NPs{BJ z56s^DY;h$5$481kB^;kfGVC=JjJSGEhInrm7W(Z!o`!O3C|oo~RlelF4Jv&|67}iIeHcBXgkHKxm^+>FwdLphzcDQ>bAYWz7>39J79SM zw?j(^BvuMyXNTT#Rr*;j{jbTwiIZ|OY_vqiYglKB^32p?BA{6HwwBFvMZ>cA zV1^kKKK}T*+O|zFcCGL%No492ZxS}n0_8PTP=aI3|5tYRXS=)QI-&~oPbQ7>=^RHb zq4CZRC$0z*`GY{b?7WvU-f_4P4f4g26wVBAPyt(C^e2HhI7E1W62ZLn78IyzY5)R( z;5l#8;D!*~{EMz3jcL{pt@ZYpo~~^h_t6S?7-80Y?&UY0X`%a`Cu=RCCf6&tr>VVm zRC)l>)xClkC7%B$G~$dYhMc%EG^!_U^Yuz>{jw_nu zWy!?X;0rXnLLTlAe<0&CZ~5AEs+aE&P@MU65fUP+SasmzOi9E4*F7-bPRBb;9RrWu{>iJD%SPGB-S+l1RBFG z9PW&OsXOF6`=*^^70|bx5G`+o>|8bq(JNglc~NXp5zM$0rNVN@;Yz`bmPg8(Puj%c z_0nduQja655)W94*mQZ6GK;$SJg-2~vX^z-0U=~p3R)E!YI6_bc+WQNZ@(tZ)C*sj zAFiZnO8~~MtH%& z!sO^RSt}>S$t$=Q(Rl)NZv}cWK1~K;@t0yfKK)};?9#%}brM>Hs~qM8Eb_Voz*@qe87)1#wNN}{Yjal0||K71lD@I*PkVfjJHviiNc3T|2uB8*?Big zbs`J>10T#WLB7Pw6$>(SqG$jmuI{r?`QmVmUWTi-d7f<(2GScJz+7B;v9N#M_0?Ve z>|+42E|O+$@Zie9poAA)C$4eJ#-%9&Y;_<6_~NNYy8Q&Hk+ES8?v4fswdMt9F9dB6 z@=sIT3yQR|_)5*|GAWik0}PNsZ_0=Kp*8VdbJH#}`$9?8Ml605u?gpY+jla+rYxR? zr?d;?9_&Tk%jTWug|~$(cP9i3QscqPMU+psW z^_Pbw-zl|b4!R0#eAu;Ab-qIxDF6AGGPL#mk1)Rs@#IYtnbcH(*o`u8G*!p93D^cz zF-4MZ@-|yDSMcc|4h zi>SW98z3sk6Z>d8S4Sb!Fj7ze{MF1d01MB+0!*aIM2HCgvP%%uA#z(kLlJ`^Ah@2j zr3)K4LL12L>aUX^a4(5+e82VCckM^r>91>MOD$+H;?{*xNR<+}&bXXt3KL1U{@z1p ze$;|kudvDgo-IMVLV!#VJ)W0Y5eo#0lh5hLh*^!p+jEl_r3!QK+=IdVDr@_#EeLLyyT%~Z#(Mc^kM>m?RJyXRZTdH`0{_NR zqdSNMT#Q6cMZey0n;2 zcE5}*uqM4qLY9MCuos^`Pmf%i*3lXMNz<&G_5>(q_&Dz;VX!xUDAuN+(xYi4R(^<)%O$znd4+MCk-F1?#P6U~m(pP%b zT_S%EL>F5e5-5n^e28iMC97V1CN6X;d)_80*hBK=LvsIq|cG<-@H`M5i%Co&97T7eMs^9nsLagB!>@26w=vKTcJ`I zmy6r3qcz0zE5l!2T!RK#x~rQ|5Tjz$6D-y_0LuCjQ-^WL*ES$P9wJYNIS8M=QsvN& z_iJLq4VXELAD}7w3q~fZ^(-`V`3cpMhJ8qQM+zLwbE(O%(}k)9PUeSg%C{^i3(N2k zA{>iJq`{c99UwDAP=8hnk}q-Hy7XM|Zl7&=E4{I>blyIK-NH?bC@cWbLcP{+ZOBBR zO_9QyDwU&D?=85EIyk}2GhLy8ulR42ev!HN{MAns%CDL>^%ND^#$-aACczGn)#?qW zJMu%L;n^a6skK4tNw0Xd6`;2=f+Y{V z#yqZSQ*m=6wd>_fY9Ig(uTNfm+5j!lEH?8P_*O<;AVUoIX)mGZ@!6xxfn||n zuMLr6*k`<4!8|rQxHeHqO{<%hO|Yg=m@9jX6tdpj1mQH(4j5%E5Dc|Fki*n!L?F=! z{A?DZZV#`7Q~Of)m>6G$`3kqpVSW*`EL5H56FC1=$}L@fqHA)Q3+|^356ru&LN&NN zPbGTpxS={v^fhmUEnGAtmP7;q0L;6mrTMH=1{-h>$6x4t2^vhIu4Z*q`h3Zl`eqgV zi#|x%TqYCo63(1#8#;e_P2JK>iC<$l=vRTijE0uXiMzs6&U7HB!&=@!{P+)^pvF2L zZm~h{)AbUv77qf@7lFstf~)pYt*jOZlJP|Iw;R!X#^~n4&pZ?=Pr4ao<0!Zf=!U~u zQWm(?m*3%rm;lQ(kzXNJAf)6vg3M3D!|BOViXGwuU5TgekTYQe`>~qdfVISGZoL|_ z%v5YWIa<{cUt32&b+6OL&M7c? zR;aA)!en-Bsd@Xs@>H^Ai#3LT1WEZAxYT@M-G=H9SrR}7_H%)>mOr$uu_oj}d7X$E zH#}S4cnaU}F!B?LsGCzd%F-8QtQqrmaO&q(#bAE zswO1g0^=~7S0Y86Hu#4#Q#ec*_)yWmCa5Xsenx6s0Eh3mb@S^p%2ej}nI8sKs*hJ7 zh~f#->pGp7=icuJ7^yl+|$Iz?ekc^Os}Yg&Wq#mfl46o~RvfUAaed^idUrGGq$7B8nc z*t^zr_((yv$)Du64c`{ipfzh0A|doYcRy6hfm$DY7MRHZ340Qw7Qyw()M78M!?C%= zdf}H|q=RTDFDp-DZDoC!>j+m7yBx==Rxm&qx=-BL2Ed}pY3ip1{2LgWo(+(|B!H*Z zkmGI6jbkjJ0103OdoJaNkf}Q~3bUAtAZ+0;FZ{fRX!OOsjw+qC$N+x0{POMK#piybI@&zWMxlIvWB_RrJf>7c<=3%vOKX2)J{4+FX>C`&_ z>#p^I8@K_MtwCw2A$ilA>v}$P2Chw%{4NU1?H}Oo#;orUH;dRQ2QhI3m%4ycG2G8S z)DLUzK?xp94oo7X_Ag;v6tSPBm3){6`fTVs90^CXwv_nS$HrEgMv=vvDI=vj)?@JU z(;&gjTHz#q6;rqU84;DtTQn9rU*e%HG)j5~VFCSrqyy6U@VSy*_(J{(x&#Vhc*Arz zoGS{!ijnG_6N7vA0x0izZo?-TdCFgKj}Ej1AvFvC)c8q2`k#qN_6nIN@K3;^${2hEA|pSh2!F*aND5QY8re^ZM&J_un)%jwRyA zs>@YAjl{4y3%PG>&35t6cxIrpC--Vla(snDjC^2=CngNTXLuZ86a;0 zVj?-~O*M3+c~0dL55Q>x4BYtgChs!S;rFSc|IK>Q8|e0}{+m+CW7t%CKWq-SRv>KQ%ytTT9l!3Q{$By#%G<|J3GCxw^znsxk?s&U1RIJ|D-7z)9;Zw zvRnjmt-k#kS)=8__9?}{8q-jEnn|V;En>0;4@>&*tYLwprbgcl2WkYsd~_wD6}oQtoz`t~A$Y zs`*0^u~N2$Eh)f+?}rBotlDbV?3kT#znT`AuBI=k5M|W*#~zk%##d70wYV-D({iYd zoZfyua=>$e%9JGHkF~0HoJ9OUT;~b6S@uiS4v1Zhgw7h|nAU zsK4z<^dJsg_%6wN!#R1WqAB>;WFkQzLZGyp;22_npI!NP|6tY1Gz54k3fz&NEeZ`2+O?g(QYmXd^urUti4hOce@Fn9Jv=hoi8bN7m&rFEs4d%ulDPFVy z!5sX|FCb`J|M3vJx^%;vL`#tG#88y9MN+?6*NW*nffIz&%|4wVwegsijt#i~_V>#s zrenPBl2>>MZmll$`fhJ{_i?c56zNJGDBe-T2NFP_Zd+z(T~u}UZgufj&ZFvi`YQe3 zk?Q4|$Thls?=)@ZFl;vIt z6|gmb8+T+GvVA8gAIL+xFyZy{G<|~80zOq-!>kW;;^WBkP6hoxc?pkBAmzQEZ;vQ^ zjR`o))Nb_;oYfSh{m9b2=q~+vmA}0SkYm~vfOT1EszE(`*9|)M(thZIH-&}K#NH`e zgH+D@X~JB9Pmb&W0BVC!K%VUn+yGB>XRFgWg--!5lY9atQF+5>##wF#o{S@TuB2kq zj>u(ez1Ftc+m!k-uphNDy+6B5g`H(@vPF#i5kZ%h(9}VSvxJgbBmQ_pALkCl@f+$MS+gD(4MJS*IF$5ggJpTW-&a>F!ubH z5S4KqjjsVz!X|2v+Yf)*M=|Lf*I2BoTyIckaCUDsg4#5}I!)l|`@74ynaYHsnGE~l zE8zf%uIk~lYGCRR+2ZGSlxIlG_jsZreeeCFhOWJZR#H_zqf4gmhi(Y_K0C7^*q>-N zf>1somT@%H09d^4;t#%mp~l&Oc0_$XoKa~KjgSskwV$)nzPvA3o}rOgj-0|t8#HT0 zP>&SpoF2gDx%djQv^~RhWB6Kzl?HGl#PT+#8aK_@eqzG<6po%;_u^+;+ZewhR<&+t zzTv$8Gs-cHARskat#&yQcHQad+T+Dn(_f*_XG27nj$L*S8{9R68JnGQQNA{*+ah{t zSRQDy%U+G4esg2Grzpo&UPOTYJO%~qQ{*C-9A&;m+|HK8MKFeb25z_gvJ;giY6M4{Z3tn)A2Z&fVK+0sLVEqCMcYey20H!}N*G#qVI` z5U}4uvO+vI`zf$9KUiY?OL33HlWQE0&&wgVz9EO~YtEHG0}~f`Ez%gOG+T=$BIqEO zozXll==uKPJ-G4Js8V`_YZyPJQ+03Ec|9A&g|A)^9lH(G#R`ydrWllZgleqWB7Hd$Vx>kr#V*)K!v zSri|7>wX1d+Ixv-jpyX=U(oI5V)nl^GGIISSR!2DZ9pedf+;v`?Us@-ibE2pKeu!I zE-dVWU;7srC(A8!4NalN&bLD`$9WX4SxNo7Yz7;8i!we%-V~17aI$SY(O;r;hwG_s141t`Cx8t9Y%6$np%`;kg>e(>|m^V+n`GsABh<%lVlT#g-yk1oYM`a9} zJN4;CZR$uc{Dz6q42|nLeM;h?ans6pd7h8s8g3g3zeegm$?OmKX*Ch?*l3QFe=73? ze*5ivgrc=PNPW<=q(91_x?6Bn-{~@-no#vnjnsaq4Kl{)(8_Tad4>F*#}f<|VC05r z^v<6ieToOT&_sbL$CM|R8La+vRFzj87V=aKI*#)#M0jRdAj^Y@_| z@0VUVV66s?(@sNcr%gA!Jn%U4#XYmDg}QJmJRp6pxmrP$pTzw4YJ4@Z(lP`xhJ#R;7J_y0F4uUofL0 zm%0i)>hE{=dYH>(c?UPTwlW%7oggyc5Pa2-zAV@(7#Ev_-GISJd2$y&W=sHm_4o5R z1O>fJOM+Ma5NgDdN{XVPPVU{6J7$7QtFR}jTV{+jQTD7fhBsI$JmJbNC4ip-VK zkDC2!WRMa}tI$*IAG-d$=%i%0f!^FK)tGzRt|Cbih?BB#Nj z=)tz*-A2&QaTR?nJ#otyRU`wtdGPyne5s;|E6)RkB_7{MnCL`-a3+c?F-jR~Lp`R? z036u$mYfU|=m;kDj0?QPF_$#9aCGf%700IvGyQ7#&x-n%p5saX;yc(l` z&o0#5W>J`~AVpEnc0-$qFW;=7c|<2=Wi z3U5h(ENE}W^fg^!DY@mAq7qI7vMV|Z5Dju@hjAy~vODjOKcqP)EC}lSf;7h2( zmXf{9jU9e=AoGf{4KaO;bMP2fC+D=9rK~JR*(4hqir9*CN%#jj(tBmp1r{$yLAbF| z3~j}!>EnT}Rk6o0MYjO@2F?Upt7V2$4~f&WS(Nb=*He>=YgEC2A#`KtjO zu&WLOTqZ!QgPnR9dvj?n2_>@lV#wcaY>(@LJud5MtkmCZL$jWf`0k&k0x>$;rAhH8 zFqwSdp6&S4+9@i$amCkkAa;*E;__j?3gV&O*eS^$)o93UG(o~Iy8zLYuPr&`hJF@gq%tBsgR+><$B+>bWtzloGOC>V}fAP$52iCR_MMC$&mY}{7l!y*@uKkxIkJoH*?4~37F zTT&gIr~W2bZT)^r05L$$zkZ?yZ{#wvsZKs_`UkjoV~4lu4i5q2K%z_h{vAk~4ofPx zq^y6c1wG^S>uFiGbP*po!G^oF%1j*#< z-Eww4d1jbCx?mHTZt9|O0<2iQ&dvTbV5&L7bCmV`o=z7I4B!dTIFM5X`N}=6m=SqO zwO$tF_fHPa8Ny|pODgQ!2sm|~Q+imMfo#A4xBEbi&=+Fn ze9Rg6kr^SzkZs@i#axF1_+A0nVv7KI_+@0)o2Bsq0TC%;VVjO!$#V`P<;P%}9v#YQ ztpxyVWDiDpKo&Ns0!Oy+FtI-Xf1ixE4i+s%cr7~dSitUNdJ(S-u*umS*JbaK!Az*) zsLNk}+O5e!RO21&X^kA}J z*S1eMnaEj*!~ZDI?u^rzL2ybQbhG&X-f0eQrsUrxNzZg99l$^C{0H`5_@H6hMA;^Z zIPW5nt;I-vD&g~Tx>kSZhfuoG(F&EXo|`@vMVr7{Dl(bsw_)+%k9h7k>i4x}BEk`B za&g5|ag?TGXSQr-dh$B^56r5FQ-knYK5WNf8ln|4_xUN-xnhJrR92-c1Z-ldU0m!5 z0W-}tjtiim2L9cQ@4)``-4958cv|ub66b{Hl&dZbV_=52OrFFM%7e!YXbxOHm*?41 zuhLM(U~d~g@is~LRw;-63Zm4VnmVLM0#*AU%ih8(UvfIm9&b{jUKUe2xHOVMSk_2v zz3y%HmSh~Tw$0sj!!Zr~?hno<5S$FvfyL+`j1OxrqCC_LzR7C0$m3{@tHL(u^5q*O z1Y-h}f{+s~fD^81et}Nb;k*-N6Uily&me^gWkg?Y4h&WW zQ_jvbpBn2aPSk_VV}&K9I>pd@Jg(r=lMmfUQ+`>DKID1FPMWQhZ0d*S8p8Kl#^S;H znD}yKV#JQhOBRh6cc2;4y%!{m@dNIrq}%TdLB@cufisyznRuEb9k307sE2kaQn5#DQ$h>EN#URt09*ov1g9en zZcQfbd^>S^Cf~NzXCqFf&9wXdyQx`laKpR!D+D!th{iro+LyNe=AgS=dbbRN(0;$U zB0iDnS_6|Bsv6rS@$ckD<@lVh;Z?9_@Ekgcg)nS;4u|wkq?FuNjqC5Br(q$xEejlc zNH!a|kR>DGd4ksX_bNc**3F&d3S26MjQVSf7bB~`S?yNroz_(CO6e~W)Z|>5se?-& zN%AP>6fc&Ai-Dpm?>lZK8gjCh)_oRpMwQTi%*&SQ(BIGV`MmB-~I=gOAN%I079bKfxQ!z$_d;Cg74Oa$OQQ z0(eXA2l=b8JCF^ht2_$D1rGuyT}}IMI76jt_4NzjA090`C}`awsfHqU`q^n$^t^in zaJ7ETpeI<^!7Bjf^zPH5+UyXu@39PjEv|~FfBOWdb?VZHXLVYV*ygaX+6@!V4>cJ! z8<1Guu+rc)B9w;K*^UWt3v5dtRX6t^1+Vw%9@l#hmLya(&{X96E&TvQ3ckeLT8wO7 zxhk`a6XGJ1?cJ@{B&sM=`p1&1ps;)bhJ#*3%j-Daoi3*`7RJ#iv{);9E7*KWm5@<@ zDuw^wK6L2}NTPN8SUhoRjg?Q}=fOwT(Mi2dtpz}$*l33qZfRk-cysx+Q*uD5D3gV#h7MF`=?X{w~ z!UpMFl=_Gj%1WheP!ep+0RA|D4qengcKShHOGlif!qHl%2-@fv&1|PO_G*WtLTwm-{aougOACN?FoGrqHsm_e0S$b{cN5!RP?ZA5<1!coTGoHc@? zHN^sDdrcG%$cQt?S(K@*Q0R@a8Fq~gMqyl++q)5W0(dL=h?XGIH!bjsbR@xdxHY@S z+PH$X1}|nGQ8wLD|72gQ{{CR@DhrNqv4S1uJ87nXyYNqHU8n`FSwiaE&h(*{SS|BH#p#(mpYKG3-@cn1d|vKBz)~ zf`rBQ4p9*ilrsWg$?Qjs?d_29)C`!8>bJrq(D4E4?u-P!F2p2uHc~N6wRJG){VedZ zZR}p|o&VMEO74$ZXch=8gPI!S-(=vrFRj>cj@;SyO5IX%S$gaN*SPf$P1HRBngk}a z&nttCmT3z?gb{i=3e4NieUz@XyT9h;*s!Yir{Rx@Tv#r0s+ezEW5;Yun@(q;n2cerO|Y-?nnEGkPDif<$Rk>07sTAQ2uxh)J24L z3&pDy1A3OWKs)!=Nhw(sa*%3DbVB84Vl;8ZWZC&Cj^&2zJ|&vi>b7z_m4Ul-DB0ynp^k z8!{%^q+Ai|Ygprg!5K(WPf?2Qz`gj_SgK+OoMEJt>Y`fb5gi7oK&~fO>`@V^r+5Ap zY6SMXR}}bPMr#o0`jJknHB;lrU`M&?eX&&MjRzOLV5*K<%JQA_FUbo5ghyZi**Akh z$U2@#wZFf2W?rbhB#S9#p*PPe5Zx4(bFiut*zh|XkX3M!!rE?K-RzgM79EogQ#rFK z5+JIZ;N_d4-eSO=WWiK1q1F2-jcGRc#GZ_fnXIUsUQ^Qed5{B7k(tpQ3pdFuQRy{h z$I|H&0^rY-F+mK5-9sAbUtqhJrS?ojB9Q}x?Zjfq+)h{9yE*>VKL9V6^$n&l7f+V# z00XGXh%px*02S&=@&V2z@(qC45l>P@hAulQwg7i%dA1M(_#u}yEV4*oA@yeB9OS1s zn;!{BvCD=G6(JH3ORwRWYTe2e7U_&nJoPPnaBxPC&-B)V(=j=bF9BdTsUWDIm>^@z za0x}_iw)F;P8Z%f01u@<6Z2HS-(z*XuXm{%qn>C}IPT)H1(|{@ zD*DXJhYY^0^;{Y>9I8TCK5!o@kv2rwD#X$QWA3?KLUQUw9>wvq%IIQ#gUiIC*Z97yAZ>RJejTw2m=i(1!w&x2n_@dXv$`JfuEZ>-abV;G#b^7 z0PGe-hUtzI#Ba>Ag}8X|gno%DAW7rSuc9OyzOv`*6H&wPJkgbS={xeuB;9O=>GFK< z{WPHyCI4x7t^3D2|Cu=PS874Q1$d2#2I?CI#53S#uC zrx1PDVn1N#GaR1?h8ArNmY0kS?Sim*R5EC3utwWqj=ySp-{SnA?7x@LSo=nKJGePWy`z5FaU=kQ>#-k{6srw>X)vdY#E9T#ke>fwfM}MtY*^L%@1%rNB^dmOe*z{U|;%eSGi? zXP<2qj0ShWo+-?gv}Bp^KXE-(NYwxNQHr>%4`7es{kb4p_~iPGYun@siTME)4s3bf zhjJyqDYU8QFCuYfmu6*NthRhsP9< zlR#J<=)00rz$*Bt79)0%$*G?`jMa|Eb*M&8i5L!1C+E`#mL{zrtgWRTcA(#tF|}zq z3EpELMk^3icbTva2{9I-X=$tf(7?75&&qJUts5;=&I!m?7fIOiE49)_BCs(znz%Xkb9gw% zO3f{6nS#Jv)LBY3@rxD)(iT7EihvW?Cw+qExWeUaxMyrxYUbkv5F}FCudB~L3^4!i zDW1O2p%Udcr8R%h6F3)+E7v5+Aas9VZNRQmoqWHG8 zmLZex-Lbn0i}J^cOKkETXB|bBGBV92nuB7daOaH6Fl}bHaCa|6hEw?tC_*Jm9JnFHpOL|WsE9mRP83Cuy~p^99U}GCn@#(Ej-2?2hY5Ys-dPTDugvBo zArB*S!PPKiYf9l(eyc{plI4x#?`YzhgV#hp$b{@aULaux6i_dU?0mbG8eblN2^n@( z@nm-(B<-W*tpLlSqqPksrv3=MlAy(wc!d|?bzTt>dcB(VtL<6ec~o^M{dtm3#^ks71+8LPl@wm(?Ampj7?d_ZnDQ4uqK2Ia=UYUX`#&MdKw* zi+}hJVN9cFAe;lj_as8*TDe4oh<^7mlglL0gQsPNnfq)x>VIz~nt_mxZ|IWEM1t_$ zopIkrw~q^cM}@)bh?!CS<}ChV6;80lSFi)(0ftDrSHZfY(2)m_S$f zoPqTg3I$bIAuhcwVwf=KfnWy0{l6t7yT~rVG-E+1 z!tP4!k5pg|L2uWp@0# zj?)d`dA5k9a=t&qdPgjDcBQwHz@Q0&YE!-~8y1ay_OYv{tU!G)Yhoj86~&DPT_61! z$BK-Zo8O{xzivG>PD#xD62+7BBoX^NzoJwWvd`@&+%_v%COZwWEh)8HsYoTwwAN<= zU+kR_szHm&*7G1jYN$mj_zSoJHg%N7^oUHu!sRA5p1yAHdnEVXu1nS89x9HyE0+fC5~<+lLBNgTtMG6B(`Plgq7i2KLAT5)*Q3M_CRE^B)( z%#(`-mK$n}KOH!MVkJK!8kKt`e|?l>LBrdbn9;SwGui~%#;1akb|^}j|x^@EoH)Um@mkDT#dYp%T|Gi z(lCZ+e~FO^mj#XM|Kg%ySx_oAjB>3%g!~tOrTGh?Jl>i0<8)~MnZ3-GlHbUeE>(xK z2|iAAdUlkeUjJcQag;+-EnpTo#z-_+6`UDVB|)1Gc{L$~zj&!cYnT!;V4N?dH_TNC zKFq*sZWiXF8pYw`!^vx=AN$+YUO*k#@V{v7dOLbn&tN|7iKscZB>qamR>glX0tm0u zsxPfVx@Wr;o0?*dmdheq7Nrk{XNupFI%@3LNB)#?+0goxJtbEKnN{xaHWP(FScX|O z02y$Ir?je(V@IUGkn&@_*^@Mk62pA9a9dyQ<2#ZBJXcP=HXw%}u8&*5 zt;_Sv5LidSK2{cSLai#MK1Q5gL7YeayLfgqNbuLsdBq!$1*<{EQ3r@=VNh0_8;0zb zmYYd*+{T_W! zIk#qB`6NOd_;nM;tPvQ~&_>c{>g!2O3AM&v;}l_ zfIZ&CzI#vT{w)6H>v|l&o=JW_LRhJX)BDPSIb&rJj#>0<&3|#xm3@ku)ymK z-JU30mH!UZdyyM+|EX@ZZyJpUX-s?%4Hg*-E7+Xlw>*&T7h4GQ`>ka+#*xhw5r+6x z3!RfIvIL}tpSjfxaux+A4ryQ)vIX-4jj|HC1Pmmq8dnqgY5@ekBOqV>bdUz2_oGrc z>8DC?X|dcDs&GQ8yXk=n2G8)U`sY}RKfmlxJLH}T#BvZ4MM3?}syo_B0`(@OuY%Xt z<1bi4X-#q` z5L$u|SGI$&RnzX7>zjgCY5*6Rxg}WC(;W(|3$fTB4@BD%lFPDUgF9arPJli{X+J)N z<(czELvvSMU(Iif93m`n{+?NmW!Q`lc_Pp2T~;C*MA69ddC*Z-G`8`e=x`yLqtsn@ z(oo;?O``)?LchcNJBa9K&1)V4Pmbp*e@lW(*k^%ZA@$S@bZi3lVCr0laLl4^2DSM| ziNta##h9G2*ki}^2aGH8gGL6M_txxJjB#<(Q)Z+?AawNnv4xPA*y?OdTmJ5VTK*i# z*(sBUPCf)()~j=^V1F)41jHCWe{ZaXhPpc0dOewHB@W)#0OV01TS#vYkoJGf!rT(5 z5YdCDoNW)srIUd_|6+R2C1!(#=FfsTb28NI@Q!4&g+kUmL3SCVTtylMLiEIqhV5_kiV0M4sZ_QR=5`$kRtcxhWiY_ zBqy@XfNHxbzIsFJ=OB>=NWZoJWfhenEPtWi~EER6hLNM&&P$TK6X=lHDoReec zaxPDqITVPv`rHPJG2?C6%lFX63$*~5BjW<(6MIqoN>@l9AsHGboF8%Ie0W zaY2C6NZcas@f~doszm+cYQd2hmv?XiOU`%^lH7V#Lfved7-Q5K0lHj*h>E_5Ev<&N$cu;UIp`}v@(wl;80_Qx5}vTfhs$VqJ;q4eE+ zNCDO?elDsQ;a8E~kv4wRwN;oLR7(VB*+b6%=|WiN#_5od`!UmHGjR#$kzXR&=zXqa z>AZ5Vw}M5q@Y2_^TZN{gUJan+{sFXym%|yH^D}57k#w`rMLHOp6p1YGJ@9n1@{nlA zrcX_+_T+2m`CS+FU33asI*7dG<|_s7E}g&=)dJO;KY5=z$=B??6emB03cm$0EhNx_gY=vv#UJwv9hNpm3`ZqhUDI8 z%fZK^FvjpNttK5iaHpC%^xc9D)*M1wmh-5$v9*40&s9)gDDR?f7%oA@Qm$Q9#f1b~ z^@T#hxJPSNi>v3s>d~JPEN@&c73ae(kXbx3x zFZ+k7n3FBlP2B2#fV#wm67B+slL9UO(}A0L(}bF_q=A3`rQhl6ASYY3Y}S2xTVW;< z9dmto4U+dYIH%Vi$V1(4o;IIMV>~53dA`il{uJVlI)5@W?N*Mbi(@MFo6mEpNaH&q zRi*&`uae{*SN)oWoq7uP$(9=np^xb`os!SL>8$8BAJC#Z9>`uN+|BcK%E};@cQnV; zx(DLO9prmmdtq{E!-o1xF;sx-=h9fnYWueY#YX^TRw&;RHS+pH3RJg20^49_(t zbZuDGhEOJcIiCxisT7;(XQcelKc#AfN~X*vd1!}i$tZ@}6rOC8k)rD!=U?hJcl*tW z2`dz``2^M2P&59Tjl-v7;mq z1clEuFTDbf{x*?N${J?mqP5g|@4y^%lV`-Z0j=)>{S0l z-u_jy4=idILG$w$CLxwt-c+r%NO6M#Q*yzvvhx%lJfX7CACWsvH7T=no=)p3*3!^0BZ;h5_usZ zEmLX>@(Mb9D1OmjD}7=0g133{=ia(;MAK!lsI4@EATB@GSxjR{vl#;ia}P7g6Mwj^ zY9>&B@HJHDX!izLH?PUQf3_T<>}*9=7KzWZ8t?M17xj+5pjJGba);TU)y^+w<%0xo z6LujXpdgOga9+?t;aL>VG3S7tvE=OuGuaNDbN!2ms)jQ)JPnaGk+lWvuqT7cq+joK zA8A;Hgw`CY;ezb}8bI{0w|N6$Fe0!N15})-HO}Yipx{g-nl`qn<)u zi2K6uPjHE9Wj7RYt*Z}d3qI7+&T+bQ?*S9-6bU-NSk_c=Stx>NR`OBsLfnQtI66Lb z$kL)>-hoyXdw`M7qIkPtSNDkRX9X}n7lb3QylpxjX@^+<5|Z3!pe?MSlf^<$}pAMI-sGH23u< zqzT9kQZ@gvabCW43owK@?^Mi6gdqrRGFqJHCcQ4WTk-TEh2LVLP?|!stI-DTo7q`y z7Ow*$sVCj*<|;@lej{<)h+>v38~1b%b%#`-+g~)k21#epa`E6_qTMY7Az)Uo-8bzc zvcZ9qCO51a`uawXZjJ)=j8o*t-kE3j2doF0ZDId1%4MH`VMZ69T?9!jgRcY^JKt-;oD{NvPkW0|r>cSV&ptkxF9Lmb z1LS7(pKMF?2=T!i{JM36>%O!ImVAI=#_@P68LeB&8!SqRu z(HF4GdiX&F!>`ZV%Vz)d!Y%azUz27+44`d&| z&3a50QfXyCW+=rLT7nl|>`5wh#i@-2XMCiFn+MoT2O@vp1p|^j0VMH@`S=o$|x@6Y_%RC50Wy@~UF_JIot`MvN$0!2)# z?aI5QLYZms$Wnaw;Pe=?Bi)>Ek=+JIhEB3DJ1k)3)V^JV#iwgj>wJXWbOE}SmpSLn zFA`7Z@;CCLyl%mO6*zNSo2QtQkJ}1h&bp=wf%xAJ6@rcJo*lB<5i{eJOUWFBA!+>1 zq#j8?mcHxlYRy-fFS&5x@VJDET7uknM-DQCj9T|(W?q@Ospp+u!*D%ik*D$}BO8Jk zRJxAYXBb0t*fT%tx;6@xm3Tw0O~JciX61jFC2UoO-lQ=wMozhkU=nLfzzni3j$%T- z=ayc2x(?U@b{0!1q9=W~pB9>zNu?z2VAxXj;w`AoBX?xKo9MT1`!-wJ85)gsSj~ve zdtFb=Plt-o0uQIA2-#46A25&n^&N^)Hy!0Cw$ojO^)5aE(C`sw2g{I76I^Wi^Jmbm z-j4tUL}^C1B=6=4Uz`oyIHX`Nv9blz2nRPY)rh94=}c8>?wXE8^#7{>QnX(3^zFKQ z9b1&Nwc>OnnRK5Ill}aa@h)XF?2Ah$m-ubwFnJy!sg!%MrO&i`9IF6anbrW|T+L&2WW=O_M+Cm2Vku7B6_(9F2N3z%U@G_g0j%aafb3RMv+*YI4~HqA04s zE&fz+cs1R5b&quSp`GMS{xRk#B{xM{_vM2<^rB5;V&6ZJy4KfEi&Eoj4Y+wZNw}V~ zL-HHT6j;P~DMV;w!S+@hy1ORVi})MS74{EI1m!`I{%TkNsitO&K$B^Q=f=&1yU3-W zBsmLA-&v@>kaYdAc)>BC*Vj;E!P_QKKc7^&LqAyOX>XXPiW!Lh8kA8_mYHv6tB#@9 z5=nbC+{f9>XT2l;)q6d;OQ#3=<$!w`I^it<0K?t_4-ylmd}XSiq+?0A5V;{l#F4*( zJ#B)B9H{zka%z~N3lbGQWb$h^Tpf|?1c{9yyIpiQ(=1H2V>|HoileI(_Emx#wNvX)T-HvV-%Cq` z@qqx9fQFRyQ%{j(Wc^wjnSY^L^FoFUW`gFxg1<9QNcEZ>}c)tv66xx08`wxbe`MW@9Av5iJoqdhZlfN(A!n% zO(s@3B(oRN*UNfBdpdgPG%;*0AqvwXgiq0_dfPw@izpcUmGU;K%|fo;wYK*yPaWF8 zeuq`F0&tMP(JQ9XQp{p6E|Gt`O%0#)ETa45pb)7C*B|?+05+v0M$J)BXG>3<`H#(^ zY&D|6cX4>CS8$|J-vD4ntm^}qp#Z!skr7+c{E6lJJR?ZWOa`!E?El>^J90ZV^I^D$ z4YRt0IN3sOWoAzTH@o+=H8P*}=>^0th+ZHbOeSO%!zJ)@?i`^F#f!;*#(wN$Sm$4{ zIujWW|Gl&>ntgoA_6bHgCS3aOJJ~Bvnt76d@H82{i*BZ9>6Q{2z^~(jrE*FqP1M^b zA&U+K*LG_>=&dCy$Qm)4$vunrny=oS=p82ch{E_tmdIfBVjM0{8!lO%@Zf zWx$GxO?P%jYBkuuFYOEGNChh$O{@6TV;2k~H9B7Wq1^$i*_FS?p=r-@D%5{*r+_^# zk4)?GurA%+_GW?JxHRae_rE^gWDql;xc>aX$w*!o(_HIAJ>!aM{~6S!{sXYh|M9NQ zv1_&vsq#Q3!BDAxvYB!2ncmC@taip{w8s0W6(3lPLc@I-VcPQ{^H95#xS1P1HQzyn zLKX}aQta_yAuJS?1{uP#IH`jzKjO6RIQeRh!2WPA&$3aWUtVNfmaebuo#b!U1W6RE zn@I_MH_I5||I0TiXGJCRjN&F-Q$ODT=QEjVfwny-al3E)bCnAf_B-kiQXaG9@$Lyq zvW_4^>-pcqDSz>0+C8a4*T^k&~-%1^pc^eDw*3)1N-Wqx|EsOTyR>wBmkt zb>lYXL0W~dA1cet@7PJSl!t%4R>04%8yf74{uY3m@XIktJt~ApS4mVk0mFGLLecJX@csr+IWDX??Yrxtg`E#_ z)bls4e`LQkMCgl2M27YahUOK~? zi%z)y2)T1!6R6FNRd#vJ!0xLWwQ{-*I}#V^6LgCO5ee+przK>i_D zvfgxHgf>Ei3-SUBmM!ti8@=g|N;1I~7pSmwt-Xqh)dk*|)y~7BF(%f7g-WC5tJAo5 zF#1Uq*)WcDEz7*)=zRZ$hGahE*{c_ccCb+m*gHQ0TIEfw)j=P$aB@w%Jk?O#XNi1G zCQ6n1OJt#k&tN)>didGg9->Zs$0=MM%3h(b6Bw&Qyqz`*-pZH(8h!Y#pjt4(c2Th9 z;Km=T2&FUiO0mqi4*&uwRmf}yfvgOqnN!5-ep}gJtPtH%Sde~&Q=*81$(Hzmm+5y) zNPsNdF)1f6V7jyo*Qd!FB#lpm$w;9%%L&;d<1ja;GG|n12eTR-@Dac0>x%@{XYx$M zTBK57{_~5j57|N*DRI1_5Bz{0`34wuFM1g|cI+`y%40VR6E5C6g2hK%I!wRu%#KxABl^8&1}6ST;#2?8j2%)b3&&=5UUGGY5XrejcT;zgINdl}XPstJ ze0yoB97f$WRh@qSft+a+rj8f0Hj1jsb`9NWA(004`qBgAr3ZGj zM|fyC9^u@!Q10K$kNT^8KmupSj;%}5d~<2l(2l{o)sLL%)rLBg@{P{8N?UisS@MW>>f(>odOU`po^&CG zyRMvBwZERt$u1@>&t@#-c*Y#}mbu*6o&vGYBxaX^svbQWf8k1+MTxU$dXc~@aNl>`FF z-Ym|E5Q1XJv`|zJH4z5}a~SFX4u65JK$GJ(>9rc5%PFTsEr2Dp5r7(_6K|1`@ee0P7#z4B2c_pVr&=Yil<>T4^jix z^VR^-e@huON8#T?Y}hT<)Ytss@r;xoIHU7I8FyHkTw{VY&VUY)N1COHLLaJKzC!k?zz->3UVa;Q`|>8z50B;PBCbd+o=Qnl z_9T{-0JjJ-jZQKdB6X`$8y02#|8Cd246LiXZ>mZ5n&*4-6sMMJ z*JmR~2u%dae(f&GzWCsF@W-KKA`mBt)^VJ_9v}84cJG9|!4#Vm_ur#9Qq?PzZS)Oe z^RJFVODQ7hVNx@_W7a5#Kp06#n=Ti#4f!DIEo^MPa!+VES@Z};_}wmG6DF2pT{0|Z zT^k=s4St5DY!3qX#0eLpADabNp_VX3a;ylhD8xU%|J0 zo*#Tpp#E~kBuK@r#c&RR@z&U#j5s%> zei;~K^4#G&)EipYl?hgUwQP9dFSTw2#3L3=Ia35GORHI>z4=*V0^L*;#DGyA?30a^9;3+cf|B8hJ6c4>vJ zuC@ne*|s<1RJq;S4UMdNChlhD&AekPYjX^M_@?8=y+usl1Dby-f`+~H7Gn~$`IwO8 zXj0?NhDa^R98VD(R7F<6gBqHN%j=8vYAM9M!JDgYE>Fi~j;5tBpiCSL4+Uv|EzLLf z%d3XM3D0OSTrMU;S~}(l8a5KSP8tRATOWE4$TC&v0lXP5p()!qeigm7l>pXq8rEKD z#kWNLOmni=Y7Mq#4`nUa878q-P6%60SSY7V{uTN$D69hhhLW`jOWF5}ceUogT|uyi z$e_;4zc+#mr}$K#ooV=Tk?LlZ*Uns;xgRI3xl|N)-q{mY5-5L3{DUu#FE)N%&bz2)yT-7CId2MA-ER!ztL2! z`$7keq=Bx$r69#rc_F+O$RVbhM9MsSHf!5yeEclsPH3m?&wQrj^93|5K^)7|bzKep zaV_rF&4d0PBB0yQ-w}rdubWYP-n%NybAf}kft}9y$`LLLUL^Fj>ylc63o}F5*o`c) zJ`O)+L8Ld{@$JnyoK3e*0>z+cjZd?2ed~Z+*iCKt8LNj2&A8O!Ib$R;u_9ynp%r&w z>kLT)KRt#>@%2KRy#JEt$`HcU|HYwWAqoL9ACV^rL^snNi)1&Zi~AmM+gqW*8X=Gt z4?z$VQq)<~sRmrk?dZd;8%{!*x?A-PhPT~1p$AL&kl@V0Esk^bf`L*k(_eilEDHwU zBj38_VpgphZun%J1Xg#Shu((t~t&9oa4;M-j-K8QnX={nOBGM-~r zQ}YQI>)2b(Yc>)xm%|WB4WNiIOXv=E-s4J#sW_X0#1Qywn)+WIX~A3cX{; zUeD5+EDE!;ur|YB7SIfO^HK&ep;PQ5e&9Y&8UM;aOXKtnPc3B_Z^uJ*rG@i>==u1K z=4t4hj&dTrn5fb`Pgm4|f0y{9n;;j?2kS~nSnIvW9!%)i!?M1iwUL=vW2rt(A1k7K!QGWca?FtFd}4Qp&&{0|b2w^nW(E*Mr5Wep z+)Z1ILx@APT@O~O1m1-2=sGi3lcn9r6XJ!X0TcA-$mbcaM%?8ZS$64xSB$kv0T4>~ z3!x66M05gElh&R1-yKE2kS6JY!-lEZXljEXqUjJh$8FoH6OK0m-|BWbdkJ3am^>Fj zCTCN@Hj+L14Z|51T|Z&N&=q#`!J+7}RZ1(XX1VD~9b)tN7}4sWO9nl*%0iq9SC&Lyqt zEK;H<@ImEC)8-Gc7CvHt4va-#nrg+l$QG#O9|v61FMZK@-2%JF!F;2qs#FxRanBaz zFdg&2=*jO?%4k_VmeF*;LgS%brlKx1kk|XfZN1@E@G|Qk*PKp%UbnPO`d*(-8-9n1 zJSvP(=wXW+eNCZ?f`q-()bJ=XWh-T#53d{4l}LvuY5i%FgXb$rGf@Da4wx3lEVVyB zd70I>9jg<;L6p(Lw62 zd{B^)iPBD09I2wSfhT)gpVK!9u_FZsE8qssL3P@g|RzyxgD1^ z+dZ82QnY`^m8}xP>F z9PFb6-*djTmkEAAWY?qOTc$dYs{eqJiz9xmE*fA`Bfa1`zL(1|G8&IL z39)>mC?avUc=KDl+_ys^K-*ydKpXXnFc11_g08_H$Rmw(VW+xNyN{bVEd!p{ij^0C zawDK7o$4qJW85Rv`0yu?5hvFK&@qJwj^rh>61<&V8F`i�svMd*7Y9GLHs*fniiC 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 b{sC8>i1Dz0B(~QHak_}tG7@8qTgU(aJ=(Aa diff --git a/public/sitemap.xml b/public/sitemap.xml deleted file mode 100644 index 38e480d..0000000 --- a/public/sitemap.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - https://queuenorth.com - weekly - 1.0 - - - https://queuenorth.com/about - monthly - 0.8 - - - https://queuenorth.com/services - monthly - 0.9 - - - https://queuenorth.com/services/unified-communications - monthly - 0.7 - - - https://queuenorth.com/services/contact-center - monthly - 0.7 - - - https://queuenorth.com/services/managed-support - monthly - 0.7 - - - https://queuenorth.com/services/consulting-training - monthly - 0.7 - - - https://queuenorth.com/services/infrastructure-cabling - monthly - 0.7 - - - https://queuenorth.com/services/wireless-access - monthly - 0.7 - - - https://queuenorth.com/services/local-networking - monthly - 0.7 - - - https://queuenorth.com/industries - monthly - 0.8 - - - https://queuenorth.com/industries/healthcare - monthly - 0.7 - - - https://queuenorth.com/industries/retail - monthly - 0.7 - - - https://queuenorth.com/industries/manufacturing - monthly - 0.7 - - - https://queuenorth.com/industries/education-finance - monthly - 0.7 - - - https://queuenorth.com/contact - monthly - 0.9 - - - https://queuenorth.com/support - monthly - 0.8 - - \ No newline at end of file diff --git a/scripts/prerender.js b/scripts/prerender.js new file mode 100644 index 0000000..3179070 --- /dev/null +++ b/scripts/prerender.js @@ -0,0 +1,201 @@ +// Build-time prerenderer. +// +// Renders every route to static HTML so crawlers that do not execute JavaScript +// (Meta, LinkedIn, Slack, Bing) receive real content, correct per-route , +// meta description, canonical, and Open Graph tags. Google also benefits: pages +// no longer sit in its deferred JS-rendering queue. +// +// Output layout (consumed by server/index.js): +// dist/index.html -> / +// dist/about/index.html -> /about +// dist/services/<slug>/index.html +// dist/404.html -> served with a real 404 status +// +// Run automatically as part of `npm run build`. + +import { execFileSync } from 'child_process' +import { mkdirSync, readFileSync, writeFileSync } from 'fs' +import path from 'path' +import { fileURLToPath } from 'url' + +import { render } from '../dist-ssr/entry-server.js' +import { services } from '../src/data/services.js' +import { industries } from '../src/data/industries.js' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const distDir = path.join(__dirname, '../dist') + +const STATIC_ROUTES = [ + '/', + '/about', + '/services', + '/industries', + '/contact', + '/support', + '/privacy-policy', +] + +const routes = [ + ...STATIC_ROUTES, + ...services.map((s) => `/services/${s.id}`), + ...industries.map((i) => `/industries/${i.id}`), +] + +// Tags the SEO component owns per-route. They are stripped from the template so +// Helmet's values replace them instead of duplicating them. +const TEMPLATE_TAGS_TO_STRIP = [ + /<title>[\s\S]*?<\/title>\s*/, + /<meta name="description"[^>]*>\s*/, + /<meta property="og:[^"]*"[^>]*>\s*/g, + /<meta name="twitter:[^"]*"[^>]*>\s*/g, + /<!-- Open Graph fallback for crawlers that don't execute JavaScript -->\s*/, + /<!-- Twitter \/ X Card fallback -->\s*/, +] + +// Metadata React renders inside the component tree. React 19 hoists these into +// <head> in the browser and in its streaming renderer, but renderToString leaves +// them inline, so the prerenderer performs the same hoist. Leaving them in <body> +// would put every title, canonical, and og: tag somewhere crawlers ignore. +const HOISTABLE_TAGS = + /<title[^>]*>[\s\S]*?<\/title>|<meta\b[^>]*?\/?>|<link\b[^>]*?\/?>|<script[^>]*type="application\/ld\+json"[^>]*>[\s\S]*?<\/script>/g + +const buildPage = (template, url) => { + const { html } = render(url) + + const hoisted = html.match(HOISTABLE_TAGS) || [] + const body = html.replace(HOISTABLE_TAGS, '') + + // Preload this route's own LCP image. The hero is the one marked eager during + // render, so the hint always matches what the page actually paints first. + const heroSrc = html + .match(/<img[^>]*loading="eager"[^>]*>/)?.[0] + .match(/src="([^"]+)"/)?.[1] + + const head = [] + if (heroSrc) { + head.push(`<link rel="preload" as="image" href="${heroSrc}" fetchpriority="high" />`) + } + // React emits its own image preload for the eager hero; drop it so the hint + // above isn't duplicated. + for (const tag of hoisted) { + if (/rel="preload"[^>]*as="image"/.test(tag)) continue + head.push(tag) + } + + let page = template + for (const pattern of TEMPLATE_TAGS_TO_STRIP) { + page = page.replace(pattern, '') + } + + page = page.replace('</head>', ` ${head.join('\n ')}\n </head>`) + page = page.replace('<div id="root"></div>', `<div id="root">${body}</div>`) + + return page +} + +const outputPathFor = (url) => + url === '/' + ? path.join(distDir, 'index.html') + : path.join(distDir, url, 'index.html') + +const template = readFileSync(path.join(distDir, 'index.html'), 'utf8') + +const written = [] +for (const url of routes) { + const page = buildPage(template, url) + const outPath = outputPathFor(url) + mkdirSync(path.dirname(outPath), { recursive: true }) + writeFileSync(outPath, page) + written.push([url, page.length]) +} + +// Dedicated 404 document. Rendering an unmatched path hits the catch-all route, +// which carries `noindex, follow` — now visible to crawlers in static HTML. +const notFoundPage = buildPage(template, '/__not_found__') +writeFileSync(path.join(distDir, '404.html'), notFoundPage) +written.push(['404.html', notFoundPage.length]) + +console.log(`\nPrerendered ${written.length} pages:`) +for (const [url, size] of written) { + console.log(` ${url.padEnd(42)} ${(size / 1024).toFixed(1)} KB`) +} + +// --- sitemap.xml ------------------------------------------------------------- +// Generated from the same route list that drives prerendering, so the sitemap can +// never drift out of sync with what the site actually serves. + +const SITE_URL = 'https://queuenorth.com' + +// lastmod comes from git history for the files that produce each route. A build +// timestamp would mark every page as changed on every deploy, which search engines +// learn to distrust. +const lastModifiedFor = (files) => { + let newest = null + for (const file of files) { + try { + const iso = execFileSync('git', ['log', '-1', '--format=%cI', '--', file], { + cwd: path.join(__dirname, '..'), + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'ignore'], + }).trim() + if (iso && (!newest || iso > newest)) newest = iso + } catch { + // git unavailable or file untracked — fall through + } + } + return newest ? newest.slice(0, 10) : null +} + +const ROUTE_SOURCES = { + '/': ['src/pages/Home.jsx'], + '/about': ['src/pages/About.jsx'], + '/services': ['src/pages/Services.jsx', 'src/data/services.js'], + '/industries': ['src/pages/Industries.jsx', 'src/data/industries.js'], + '/contact': ['src/pages/Contact.jsx'], + '/support': ['src/pages/Support.jsx'], + '/privacy-policy': ['src/pages/PrivacyPolicy.jsx', 'src/data/privacyPolicy.js'], +} + +const PRIORITY = { + '/': '1.0', + '/services': '0.9', + '/contact': '0.9', + '/about': '0.8', + '/industries': '0.8', + '/support': '0.8', + '/privacy-policy': '0.3', +} + +const CHANGEFREQ = { '/': 'weekly', '/privacy-policy': 'yearly' } + +const sourcesFor = (url) => { + if (ROUTE_SOURCES[url]) return ROUTE_SOURCES[url] + if (url.startsWith('/services/')) return ['src/pages/ServiceDetail.jsx', 'src/data/services.js'] + return ['src/pages/IndustryDetail.jsx', 'src/data/industries.js'] +} + +const entries = routes.map((url) => { + const loc = url === '/' ? SITE_URL : `${SITE_URL}${url}` + const lastmod = lastModifiedFor(sourcesFor(url)) + return [ + ' <url>', + ` <loc>${loc}</loc>`, + lastmod ? ` <lastmod>${lastmod}</lastmod>` : null, + ` <changefreq>${CHANGEFREQ[url] || 'monthly'}</changefreq>`, + ` <priority>${PRIORITY[url] || '0.7'}</priority>`, + ' </url>', + ] + .filter(Boolean) + .join('\n') +}) + +const sitemap = [ + '<?xml version="1.0" encoding="UTF-8"?>', + '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">', + ...entries, + '</urlset>', + '', +].join('\n') + +writeFileSync(path.join(distDir, 'sitemap.xml'), sitemap) +console.log(`\nGenerated sitemap.xml with ${routes.length} URLs`) diff --git a/server/index.js b/server/index.js index 4539cd7..6d8248c 100644 --- a/server/index.js +++ b/server/index.js @@ -914,16 +914,92 @@ app.use((req, res, next) => { }) // Static file serving for SPA -app.use(express.static(path.join(__dirname, '../dist'))) +// Collapse the URL variants that would otherwise serve identical content at +// several addresses (/about/, //about, /index.html), which search engines treat +// as duplicates and which split ranking signals across URLs. +app.get(/.*/, (req, res, next) => { + if (req.path.startsWith('/api')) return next() + + let normalised = req.path.replace(/\/{2,}/g, '/') + if (normalised.endsWith('/index.html')) { + normalised = normalised.slice(0, -'index.html'.length) + } + if (normalised.length > 1) { + normalised = normalised.replace(/\/+$/, '') || '/' + } + + if (normalised !== req.path) { + const query = req.originalUrl.slice(req.path.length) + return res.redirect(301, `${normalised}${query}`) + } + + return next() +}) + +// Public images (Open Graph / Twitter card art, logos, favicons) must be embeddable +// from other origins. Helmet's global same-origin CORP would otherwise cause social +// platforms and link-preview clients that hotlink the URL to drop the image. +const PUBLICLY_EMBEDDABLE = /\.(png|jpe?g|webp|gif|svg|ico|avif|webmanifest)$/i + +// Vite fingerprints JS/CSS with a content hash, so a given URL's bytes never +// change — safe to cache for a year. A new deploy emits new filenames. +const CONTENT_HASHED = /-[A-Za-z0-9_-]{8,}\.(js|css)$/ + +app.use(express.static(path.join(__dirname, '../dist'), { + // Prerendered routes live at dist/<route>/index.html. Serving them is handled + // explicitly below so that /about resolves directly instead of 301-redirecting + // to /about/, which would fight the canonical (no-trailing-slash) URLs. + redirect: false, + index: false, + setHeaders: (res, filePath) => { + // CORP is what governs <img> embedding across origins; CORS headers are + // deliberately left untouched so they stay consistent with the API's + // credentialed same-origin policy. + if (CONTENT_HASHED.test(filePath)) { + res.setHeader('Cache-Control', 'public, max-age=31536000, immutable') + } + + if (PUBLICLY_EMBEDDABLE.test(filePath)) { + res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin') + res.setHeader('Cache-Control', 'public, max-age=86400') + } + }, +})) + +// Serve build-time prerendered pages (scripts/prerender.js). Every route has real +// HTML with its own title, description, canonical, and Open Graph tags, so crawlers +// that do not execute JavaScript still index the site correctly. React hydrates the +// markup on the client. +// +// Unknown paths get the prerendered 404 document with a genuine 404 status, which +// stops search engines from indexing arbitrary URLs as duplicates of the homepage. +const distDir = path.join(__dirname, '../dist') -// SPA catch-all — serve index.html for any non-API, non-asset route -// This lets React Router handle client-side routing app.get('*', (req, res, next) => { // Skip API routes (already handled above) and requests for static assets if (req.path.startsWith('/api/') || req.path.includes('.')) { return next() } - res.sendFile(path.join(__dirname, '../dist/index.html')) + + const normalised = req.path.replace(/\/+$/, '') || '/' + const candidate = + normalised === '/' + ? path.join(distDir, 'index.html') + : path.join(distDir, normalised, 'index.html') + + // Guard against path traversal before touching the filesystem + if (!candidate.startsWith(distDir)) { + return res.status(404).sendFile(path.join(distDir, '404.html')) + } + + // Prerendered HTML is replaced on every deploy, so it must always revalidate. + res.setHeader('Cache-Control', 'no-cache') + + if (existsSync(candidate)) { + return res.sendFile(candidate) + } + + return res.status(404).sendFile(path.join(distDir, '404.html')) }) app.listen(PORT, () => { diff --git a/src/components/SEO.jsx b/src/components/SEO.jsx index d544a29..2501696 100644 --- a/src/components/SEO.jsx +++ b/src/components/SEO.jsx @@ -4,13 +4,14 @@ const DEFAULT_IMAGE = 'https://queuenorth.com/assets/og-image.png' const DEFAULT_IMAGE_ALT = 'Queue North Technologies — Business Communications & IT Partner' const SITE_NAME = 'Queue North Technologies' -const SEO = ({ title, description, url, type = 'website', image = DEFAULT_IMAGE, jsonLd }) => { +const SEO = ({ title, description, url, type = 'website', image = DEFAULT_IMAGE, jsonLd, noindex = false }) => { const schemas = jsonLd ? (Array.isArray(jsonLd) ? jsonLd : [jsonLd]) : [] return ( <Helmet> <title>{title} + {noindex && } {/* Canonical URL — prevents duplicate content */} diff --git a/src/components/layout/Footer.jsx b/src/components/layout/Footer.jsx index b4703dd..4f95876 100644 --- a/src/components/layout/Footer.jsx +++ b/src/components/layout/Footer.jsx @@ -6,8 +6,6 @@ const Footer = () => { const companyInfo = { name: 'Queue North Technologies', tagline: 'Modern communications infrastructure without the vendor noise.', - addressLine1: '7901 4th St N', - addressLine2: 'St. Petersburg, FL 33702', phone: '(321) 730-8020', tollFree: '(888) 656-2850', } @@ -19,6 +17,7 @@ const Footer = () => { { name: 'About', href: '/about' }, { name: 'Contact', href: '/contact' }, { name: 'Support', href: '/support' }, + { name: 'Privacy Policy', href: '/privacy-policy' }, ] const services = [ @@ -49,20 +48,14 @@ const Footer = () => { src="/logo.png" alt="Queue North Technologies" className="brand-logo-on-dark h-12 w-auto shrink-0 transition-opacity group-hover:opacity-90" + loading="lazy" + decoding="async" + width="200" + height="200" /> Queue North Technologies

{companyInfo.tagline}

- - {companyInfo.addressLine1} - {companyInfo.addressLine2} -
{companyInfo.phone} @@ -146,6 +139,8 @@ const Footer = () => { src="/assets/brand/veteran-owned-certified.webp" alt="SBA Veteran-Owned Certified badge" className="h-full w-full object-contain" + loading="lazy" + decoding="async" />

@@ -169,6 +164,13 @@ const Footer = () => {

© {currentYear} Queue North Technologies. All rights reserved.

+ + Privacy Policy +
{ src="/logo.png" alt="Queue North Technologies" className="brand-logo-on-dark h-12 md:h-16 w-auto flex-shrink-0" + loading="eager" + decoding="async" + width="200" + height="200" /> Queue North Technologies @@ -162,7 +166,12 @@ const Header = () => { {/* Logo + phone */}
- Queue North Technologies + Queue North Technologies Queue North Technologies diff --git a/src/components/layout/MobileNav.jsx b/src/components/layout/MobileNav.jsx index fc9142a..88fd7c8 100644 --- a/src/components/layout/MobileNav.jsx +++ b/src/components/layout/MobileNav.jsx @@ -63,7 +63,11 @@ const MobileNav = () => { Queue North Technologies Queue North Technologies
diff --git a/src/data/privacyPolicy.js b/src/data/privacyPolicy.js new file mode 100644 index 0000000..5052fdc --- /dev/null +++ b/src/data/privacyPolicy.js @@ -0,0 +1,527 @@ +// Single source of truth for the approved privacy policy content. +// Consumed by the React page (src/pages/PrivacyPolicy.jsx) and by the server-side +// static HTML fallback (server/privacyPolicyHtml.js) so crawlers that do not +// execute JavaScript still receive the full policy text. +// +// Block types: 'p' (paragraph), 'ul' (bullet list), 'h3' (sub-heading), +// 'callout' (emphasised notice), 'email' (mailto line), 'contactBlock' (contact card) + +export const EFFECTIVE_DATE = 'July 31, 2026' +export const LAST_UPDATED = 'July 31, 2026' +export const PRIVACY_EMAIL = 'privacy@queuenorth.com' + +// Section content mirrors the approved policy document verbatim. +// Block types: 'p' (paragraph), 'ul' (bullet list), 'h3' (sub-heading), 'email' (mailto callout) +export const sections = [ + { + id: 'scope', + title: 'Scope of This Policy', + blocks: [ + { type: 'p', text: 'Queue North Technologies (“Queue North,” “we,” “us,” or “our”) respects your privacy. This Privacy Policy explains how we collect, use, disclose, retain, and protect information when you interact with Queue North.' }, + { type: 'p', text: 'This Privacy Policy applies when you:' }, + { + type: 'ul', + items: [ + 'Visit our website.', + 'Submit a website or hosted lead form.', + 'Respond to an advertisement.', + 'Contact us by email, telephone, social media, or another communication method.', + 'Request information, a consultation, a communications review, a proposal, or services.', + 'Become or seek to become a customer, referral partner, vendor, contractor, or other business partner.', + ], + }, + { type: 'p', text: 'This policy applies to information collected through our website, advertisements, hosted forms, email, telephone communications, social media accounts, sales activities, customer relationships, and other business operations.' }, + ], + }, + { + id: 'information-we-collect', + number: 1, + title: 'Information We Collect', + blocks: [ + { type: 'p', text: 'The information we collect depends on how you interact with Queue North.' }, + + { type: 'h3', text: 'Contact and professional information' }, + { type: 'p', text: 'We may collect:' }, + { + type: 'ul', + items: [ + 'First and last name.', + 'Company or organization name.', + 'Job title or professional role.', + 'Business email address.', + 'Business telephone or mobile number.', + 'Mailing or business address when voluntarily provided.', + 'Preferred method of contact.', + 'Professional profile or social-media information.', + ], + }, + + { type: 'h3', text: 'Company and service information' }, + { type: 'p', text: 'We may collect information about your organization and its needs, including:' }, + { + type: 'ul', + items: [ + 'Company website.', + 'Industry.', + 'Number of employees, communications users, locations, devices, telephone numbers, or contact-center agents.', + 'Current communications, technology, network, carrier, or service providers.', + 'Current systems, products, licenses, and services.', + 'Contract, renewal, migration, or purchasing timeframe.', + 'Communications, contact-center, networking, Wi-Fi, support, security, or managed-service requirements.', + 'Business challenges, service concerns, technical requirements, project details, and purchasing criteria.', + 'Information contained in bills, contracts, inventories, diagrams, reports, or other documents you voluntarily provide.', + ], + }, + { type: 'callout', text: 'Please remove unnecessary sensitive personal information before sending documents to Queue North. Do not use a general inquiry or advertising form to submit Social Security numbers, payment-card numbers, medical information, account passwords, or other highly sensitive information.' }, + + { type: 'h3', text: 'Communications and relationship information' }, + { type: 'p', text: 'We may retain information contained in or generated through:' }, + { + type: 'ul', + items: [ + 'Emails.', + 'Form submissions.', + 'Telephone inquiries and voicemails.', + 'Social-media messages.', + 'Meetings and consultations.', + 'Sales and discovery notes.', + 'Proposals and quotes.', + 'Project communications.', + 'Support and service communications.', + 'Feedback and other correspondence.', + ], + }, + + { type: 'h3', text: 'Website, device, and advertising information' }, + { type: 'p', text: 'When you visit our website or interact with digital advertisements, we or our service providers may automatically collect information such as:' }, + { + type: 'ul', + items: [ + 'Internet Protocol address.', + 'Browser and device type.', + 'Operating system.', + 'Approximate location derived from an IP address.', + 'Referring webpage or source.', + 'Pages viewed.', + 'Links selected.', + 'Date and time of access.', + 'Advertising and campaign identifiers.', + 'Cookie, pixel, or similar technology identifiers.', + 'Actions taken on our website, forms, or advertisements.', + ], + }, + + { type: 'h3', text: 'Customer and transaction information' }, + { type: 'p', text: 'When applicable, we may collect or receive information concerning:' }, + { + type: 'ul', + items: [ + 'Quotes and proposals.', + 'Contracts and service agreements.', + 'Products and services requested or purchased.', + 'Project history.', + 'Support history.', + 'Invoices.', + 'Payment status.', + 'Customer-account activity.', + 'Renewal and service dates.', + ], + }, + { type: 'p', text: 'Payment-card and bank-account details may be collected and processed directly by an authorized payment processor or financial-service provider. Queue North may receive transaction confirmations, payment status, and limited payment-related information without receiving complete card or bank credentials.' }, + + { type: 'h3', text: 'Information from other sources' }, + { type: 'p', text: 'We may receive business contact information from:' }, + { + type: 'ul', + items: [ + 'Referral partners.', + 'Vendors and manufacturers.', + 'Distributors and carriers.', + 'Professional contacts.', + 'Publicly available company websites.', + 'Business directories.', + 'Professional networking services.', + 'Public records.', + 'Other lawful business sources.', + ], + }, + ], + }, + { + id: 'how-we-collect', + number: 2, + title: 'How We Collect Information', + blocks: [ + { type: 'p', text: 'We may collect information:' }, + { + type: 'ul', + items: [ + 'Directly from you.', + 'Through our website.', + 'Through Google-hosted lead forms.', + 'Through Facebook or Instagram Instant Forms.', + 'Through Zoho Forms or other hosted forms.', + 'Through email, telephone calls, meetings, and social media.', + 'Through customer, vendor, referral, and professional relationships.', + 'From publicly available business sources.', + 'Through cookies, analytics, pixels, advertising identifiers, and similar technologies.', + 'From service providers that support our operations.', + ], + }, + { type: 'p', text: 'When you interact with Google, Meta, LinkedIn, Zoho, or another third-party platform, that platform may separately collect and process information according to its own privacy policy and terms.' }, + ], + }, + { + id: 'how-we-use', + number: 3, + title: 'How We Use Information', + blocks: [ + { type: 'p', text: 'Queue North may use information to:' }, + { + type: 'ul', + items: [ + 'Respond to inquiries, requests, and form submissions.', + 'Contact you about your inquiry.', + 'Confirm that you represent a legitimate business or organization.', + 'Determine whether our products or services are appropriate for your organization.', + 'Conduct consultations, discovery meetings, reviews, assessments, and demonstrations.', + 'Prepare recommendations, designs, proposals, quotes, contracts, and project documentation.', + 'Provide, administer, maintain, support, and improve our products and services.', + 'Manage customer, vendor, referral, and business relationships.', + 'Maintain records in our customer relationship management and business systems.', + 'Assign and track sales, project, support, and follow-up activities.', + 'Communicate about relevant services, products, events, educational information, and business opportunities.', + 'Personalize, deliver, and measure advertising where permitted.', + 'Determine which advertisements, campaigns, forms, or referral sources generated inquiries.', + 'Improve our website, forms, advertisements, services, and business processes.', + 'Prevent fraud, abuse, security incidents, and unlawful activity.', + 'Enforce contracts and protect our rights and property.', + 'Meet accounting, tax, regulatory, contractual, and legal obligations.', + 'Carry out another purpose disclosed when the information is collected.', + ], + }, + { type: 'p', text: 'Submitting an inquiry or lead form does not obligate you to purchase anything from Queue North.' }, + ], + }, + { + id: 'advertising-lead-forms', + number: 4, + title: 'Advertising and Hosted Lead Forms', + blocks: [ + { type: 'p', text: 'Queue North may use lead-generation and advertising services provided by Google, Meta, LinkedIn, and other platforms.' }, + { type: 'p', text: 'When you submit a hosted lead form:' }, + { + type: 'ul', + items: [ + 'The platform may prefill information associated with your account.', + 'You decide whether to submit the form.', + 'The information you submit is provided to Queue North.', + 'Queue North may store the information in Zoho CRM or another authorized business system.', + 'Queue North may contact you regarding your inquiry and related business services.', + 'The advertising platform may separately process information under its own privacy policy and terms.', + ], + }, + { type: 'p', text: 'We may retain advertising information such as:' }, + { + type: 'ul', + items: [ + 'Advertising platform.', + 'Campaign.', + 'Advertisement.', + 'Keyword or search term.', + 'Form type.', + 'Referral source.', + 'Date of submission.', + 'Qualification responses.', + ], + }, + { type: 'p', text: 'We use this information to respond to inquiries, measure advertising performance, improve targeting, and determine which marketing efforts produce legitimate business opportunities.' }, + ], + }, + { + id: 'cookies', + number: 5, + title: 'Cookies, Pixels, and Similar Technologies', + blocks: [ + { type: 'p', text: 'Our website and service providers may use cookies, pixels, tags, local storage, advertising identifiers, and similar technologies to:' }, + { + type: 'ul', + items: [ + 'Operate and secure the website.', + 'Remember preferences.', + 'Understand website traffic and activity.', + 'Diagnose errors and technical problems.', + 'Measure advertising performance.', + 'Attribute inquiries to advertisements or campaigns.', + 'Improve content, forms, and services.', + 'Support relevant advertising and retargeting where permitted.', + ], + }, + { type: 'p', text: 'Your browser may allow you to block, remove, or limit cookies. Blocking certain technologies may affect website functionality.' }, + { type: 'p', text: 'Google, Meta, LinkedIn, and other platforms provide separate privacy and advertising controls through their own services.' }, + ], + }, + { + id: 'marketing', + number: 6, + title: 'Marketing Communications', + blocks: [ + { type: 'p', text: 'Queue North may contact you regarding:' }, + { + type: 'ul', + items: [ + 'An inquiry or form submission.', + 'A requested consultation, review, quote, or service.', + 'Products or services related to your business needs.', + 'Educational information.', + 'Events.', + 'Business updates.', + 'Relevant professional opportunities.', + ], + }, + { type: 'p', text: 'You may unsubscribe from marketing emails through the unsubscribe link in the message or by contacting:' }, + { type: 'email' }, + { type: 'p', text: 'Where consent is legally required for marketing text messages, Queue North will seek the required consent before sending them.' }, + { type: 'p', text: 'Opting out of marketing does not prevent Queue North from sending necessary transactional, contractual, project, billing, security, service, or support communications.' }, + ], + }, + { + id: 'disclosure', + number: 7, + title: 'How We Disclose Information', + blocks: [ + { type: 'p', text: 'Queue North may disclose information to the following categories of recipients.' }, + + { type: 'h3', text: 'Service providers' }, + { type: 'p', text: 'We may use service providers for:' }, + { + type: 'ul', + items: [ + 'Website hosting and administration.', + 'Cloud storage.', + 'Email and business communications.', + 'Customer relationship management.', + 'Hosted forms.', + 'Advertising.', + 'Analytics.', + 'Scheduling.', + 'Online meetings.', + 'Accounting.', + 'Invoicing.', + 'Payment processing.', + 'Project management.', + 'Customer support.', + 'Cybersecurity.', + 'Information technology.', + 'Document management.', + 'Professional consulting.', + ], + }, + { type: 'p', text: 'These providers may process information on our behalf to perform services for Queue North.' }, + { type: 'p', text: 'Examples may include Google, Meta, Zoho, financial institutions, payment processors, hosting providers, communications providers, and other business-technology vendors.' }, + + { type: 'h3', text: 'Technology vendors and delivery partners' }, + { type: 'p', text: 'When reasonably necessary to evaluate, quote, design, implement, deliver, or support a requested solution, we may disclose appropriate information to:' }, + { + type: 'ul', + items: [ + 'Technology manufacturers.', + 'Software and cloud-service providers.', + 'Communications carriers.', + 'Distributors.', + 'Implementation partners.', + 'Consultants.', + 'Contractors.', + 'Subcontractors.', + 'Referral partners.', + ], + }, + { type: 'p', text: 'We limit these disclosures to information reasonably necessary for the relevant business purpose.' }, + + { type: 'h3', text: 'Legal, regulatory, and safety disclosures' }, + { type: 'p', text: 'We may disclose information when reasonably necessary to:' }, + { + type: 'ul', + items: [ + 'Comply with applicable law or regulation.', + 'Respond to a subpoena, court order, or lawful governmental request.', + 'Investigate suspected fraud, security incidents, or unlawful activity.', + 'Protect Queue North, our customers, our business partners, or other people.', + 'Establish, exercise, or defend legal claims.', + 'Enforce our contracts, policies, or terms.', + ], + }, + + { type: 'h3', text: 'Business transactions' }, + { type: 'p', text: 'Information may be disclosed or transferred in connection with:' }, + { + type: 'ul', + items: [ + 'A merger.', + 'Acquisition.', + 'Financing.', + 'Reorganization.', + 'Sale of assets.', + 'Bankruptcy.', + 'Due diligence.', + 'Another business transaction or proposed transaction.', + ], + }, + ], + }, + { + id: 'sale-sharing', + number: 8, + title: 'Sale, Sharing, and Targeted Advertising', + blocks: [ + { type: 'p', text: 'Queue North does not sell personal information in exchange for money.' }, + { type: 'p', text: 'We may disclose online identifiers, campaign information, website activity, or similar information to advertising and analytics providers to:' }, + { + type: 'ul', + items: [ + 'Deliver advertisements.', + 'Measure advertising effectiveness.', + 'Attribute inquiries to advertising campaigns.', + 'Create or use advertising audiences.', + 'Retarget people who have previously interacted with Queue North, where permitted.', + ], + }, + { type: 'p', text: 'Under some state privacy laws, certain advertising-related disclosures may be classified as “sharing,” “targeted advertising,” or a “sale,” even when no money is exchanged.' }, + { type: 'p', text: 'Where applicable law provides a right to opt out of these activities, you may submit a request to:' }, + { type: 'email' }, + ], + }, + { + id: 'retention', + number: 9, + title: 'Data Retention', + blocks: [ + { type: 'p', text: 'Queue North retains information for as long as reasonably necessary to:' }, + { + type: 'ul', + items: [ + 'Respond to inquiries.', + 'Maintain sales and customer records.', + 'Evaluate potential business opportunities.', + 'Provide and support services.', + 'Administer contracts and projects.', + 'Maintain accounting and tax records.', + 'Resolve disputes.', + 'Prevent fraud and security incidents.', + 'Meet legal, regulatory, and contractual obligations.', + 'Enforce agreements.', + ], + }, + { type: 'p', text: 'Retention periods vary based on:' }, + { + type: 'ul', + items: [ + 'The type of information.', + 'The business relationship.', + 'The reason the information was collected.', + 'Contractual requirements.', + 'Security needs.', + 'Legal and regulatory obligations.', + ], + }, + { type: 'p', text: 'When information is no longer reasonably required, we may delete it, anonymize it, or securely archive it where continued retention is necessary.' }, + ], + }, + { + id: 'security', + number: 10, + title: 'Information Security', + blocks: [ + { type: 'p', text: 'Queue North uses reasonable administrative, technical, and organizational safeguards designed to protect information against unauthorized access, use, alteration, disclosure, or destruction.' }, + { type: 'p', text: 'No internet transmission, electronic system, or storage method is completely secure. Queue North cannot guarantee absolute security.' }, + { type: 'p', text: 'The Federal Trade Commission requires businesses to honor the privacy and security representations they make. For that reason, this policy does not promise specific security controls that Queue North may not use in every circumstance.' }, + ], + }, + { + id: 'rights', + number: 11, + title: 'Privacy Rights and Choices', + blocks: [ + { type: 'p', text: 'Depending on where you live and which laws apply, you may have the right to request that Queue North:' }, + { + type: 'ul', + items: [ + 'Confirm whether we process information about you.', + 'Provide access to certain information.', + 'Correct inaccurate information.', + 'Delete certain information.', + 'Provide a portable copy of certain information.', + 'Explain how information is used or disclosed.', + 'Opt you out of marketing communications.', + 'Opt you out of certain targeted advertising or data-sharing practices.', + 'Limit certain uses or disclosures.', + 'Review or appeal a decision concerning a privacy request.', + ], + }, + { type: 'p', text: 'Submit privacy requests to:' }, + { type: 'email' }, + { type: 'p', text: 'Please provide enough information for us to identify the relevant record and understand your request.' }, + { type: 'p', text: 'Queue North may:' }, + { + type: 'ul', + items: [ + 'Verify your identity before completing a request.', + 'Request additional information when reasonably necessary.', + 'Deny or limit a request when permitted by law.', + 'Retain information needed for security, accounting, legal, contractual, fraud-prevention, or operational purposes.', + ], + }, + { type: 'p', text: 'Authorized agents may submit requests where permitted by applicable law. Queue North may request evidence of the agent’s authority and may separately verify the request with the individual.' }, + { type: 'p', text: 'Queue North will not unlawfully discriminate against anyone for exercising an applicable privacy right.' }, + ], + }, + { + id: 'childrens-privacy', + number: 12, + title: 'Children’s Privacy', + blocks: [ + { type: 'p', text: 'Queue North provides business-to-business technology and communications services.' }, + { type: 'p', text: 'Our website, advertisements, and forms are not directed to children under 13, and we do not knowingly seek to collect personal information from children under 13.' }, + { type: 'p', text: 'Contact privacy@queuenorth.com if you believe a child has submitted information to Queue North.', linkEmail: true }, + ], + }, + { + id: 'third-party', + number: 13, + title: 'Third-Party Websites and Services', + blocks: [ + { type: 'p', text: 'Our website, advertisements, emails, forms, and social-media accounts may contain links to third-party websites, services, and platforms.' }, + { type: 'p', text: 'Queue North does not control the privacy, security, content, or business practices of third parties. Review their privacy policies before providing information.' }, + ], + }, + { + id: 'changes', + number: 14, + title: 'Changes to This Privacy Policy', + blocks: [ + { type: 'p', text: 'Queue North may update this Privacy Policy to reflect:' }, + { + type: 'ul', + items: [ + 'Changes to our business.', + 'New products or services.', + 'Changes in technology.', + 'Changes in advertising or data practices.', + 'Changes in service providers.', + 'Legal or regulatory developments.', + ], + }, + { type: 'p', text: 'The revised policy will be posted publicly with an updated “Last Updated” date.' }, + { type: 'p', text: 'Material changes may be communicated through additional methods when appropriate or legally required.' }, + ], + }, + { + id: 'contact', + number: 15, + title: 'Contact Queue North', + blocks: [ + { type: 'p', text: 'For privacy questions, requests, complaints, corrections, deletion requests, advertising opt-outs, or marketing opt-outs, contact:' }, + { type: 'contactBlock' }, + ], + }, +] diff --git a/src/entry-server.jsx b/src/entry-server.jsx new file mode 100644 index 0000000..913a316 --- /dev/null +++ b/src/entry-server.jsx @@ -0,0 +1,30 @@ +import { renderToString } from 'react-dom/server' +// React Router v7 exports the server-side StaticRouter from the package root +// (v6's 'react-router-dom/server' subpath no longer exists). +import { StaticRouter, useRoutes } from 'react-router-dom' +import { HelmetProvider } from 'react-helmet-async' +import { routes } from './routes.jsx' +import './index.css' + +const AppRoutes = () => useRoutes(routes) + +/** + * Renders a single route to static HTML at build time. + * @param {string} url route path, e.g. '/about' + * @returns {{ html: string, helmet: object }} markup plus collected head tags + */ +export const render = (url) => { + const helmetContext = {} + + const html = renderToString( + + + + + , + ) + + return { html, helmet: helmetContext.helmet } +} + +export default render diff --git a/src/lib/seo.js b/src/lib/seo.js new file mode 100644 index 0000000..d673ae5 --- /dev/null +++ b/src/lib/seo.js @@ -0,0 +1,45 @@ +export const SITE_URL = 'https://queuenorth.com' + +// Sitewide search/entity anchor. Referenced by the Organization entity on Home. +export const websiteLd = { + '@context': 'https://schema.org', + '@type': 'WebSite', + '@id': `${SITE_URL}/#website`, + url: SITE_URL, + name: 'Queue North Technologies', + publisher: { '@id': `${SITE_URL}/#organization` }, + inLanguage: 'en-US', +} + +const MAX_DESCRIPTION = 158 + +/** + * Joins description fragments and trims to what search engines actually display, + * cutting on a word boundary rather than mid-word. + * @param {...string} parts + */ +export const clampDescription = (...parts) => { + const text = parts.filter(Boolean).join(' ').replace(/\s+/g, ' ').trim() + if (text.length <= MAX_DESCRIPTION) return text + + const cut = text.slice(0, MAX_DESCRIPTION) + return `${cut.slice(0, cut.lastIndexOf(' ')).replace(/[,;:.]$/, '')}…` +} + +/** + * Builds a BreadcrumbList for a page's position in the site hierarchy. + * @param {Array<{name: string, path: string}>} trail ordered from the site root + */ +export const buildBreadcrumbLd = (trail) => ({ + '@context': 'https://schema.org', + '@type': 'BreadcrumbList', + itemListElement: [ + { name: 'Home', path: '/' }, + ...trail, + ].map((crumb, index) => ({ + '@type': 'ListItem', + position: index + 1, + name: crumb.name, + item: `${SITE_URL}${crumb.path === '/' ? '' : crumb.path}`, + })), +}) diff --git a/src/main.jsx b/src/main.jsx index b987019..5641361 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,5 +1,5 @@ import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' +import { createRoot, hydrateRoot } from 'react-dom/client' import { RouterProvider } from 'react-router-dom' import { Toaster } from 'sonner' import { HelmetProvider } from 'react-helmet-async' @@ -19,4 +19,13 @@ const Root = () => ( ) -createRoot(document.getElementById('root')).render() \ No newline at end of file +// Production pages are prerendered (scripts/prerender.js), so attach to the +// existing markup instead of discarding it. The dev server ships an empty shell, +// which falls back to a normal client render. +const container = document.getElementById('root') + +if (container.hasChildNodes()) { + hydrateRoot(container, ) +} else { + createRoot(container).render() +} \ No newline at end of file diff --git a/src/pages/About.jsx b/src/pages/About.jsx index 821b290..9c145af 100644 --- a/src/pages/About.jsx +++ b/src/pages/About.jsx @@ -1,4 +1,5 @@ import SEO from '@/components/SEO' +import { buildBreadcrumbLd } from '@/lib/seo' import { Link } from 'react-router-dom' import { ArrowRight, Award, CheckCircle2, Compass, Cpu, Handshake, Headphones, Route, Wrench } from 'lucide-react' @@ -97,9 +98,10 @@ const About = () => { return ( <> {/* Page Hero */} @@ -109,6 +111,9 @@ const About = () => { src="/assets/about-image.webp" alt="Compass on a dark navigation map" className="h-full w-full object-cover object-[66%_top] md:object-[62%_top]" + loading="eager" + fetchPriority="high" + decoding="async" />
@@ -150,6 +155,8 @@ const About = () => { src={point.logo} alt={point.logoAlt} className={`${point.logoClassName} object-contain`} + loading="lazy" + decoding="async" /> ) : (
diff --git a/src/pages/Contact.jsx b/src/pages/Contact.jsx index 80f9171..461a615 100644 --- a/src/pages/Contact.jsx +++ b/src/pages/Contact.jsx @@ -1,4 +1,5 @@ import SEO from '@/components/SEO' +import { buildBreadcrumbLd } from '@/lib/seo' import { useCallback, useEffect, useState } from 'react' import { toast } from 'sonner' import { Button } from '@/components/ui/Button' @@ -151,23 +152,16 @@ const Contact = () => { ), }, { - label: 'Office', + label: 'Service Area', icon: ( - - + ), content: ( - - 7901 4th St N - St. Petersburg, FL 33702 - +

+ Remote services nationwide. On-site services available based on project scope and location. +

), }, { @@ -193,8 +187,9 @@ const Contact = () => { <> {/* Hero */} @@ -204,6 +199,9 @@ const Contact = () => { src="/assets/hero-tech.webp" alt="Queue North communications infrastructure consultation" className="h-full w-full object-cover object-center" + loading="eager" + fetchPriority="high" + decoding="async" />
@@ -369,7 +367,7 @@ const Contact = () => { required autoComplete="postal-code" inputMode="numeric" - placeholder="33702" + placeholder="12345" className={debouncedErrors['Zip Code'] ? 'border-red-500 focus-visible:ring-red-500' : ''} /> {debouncedErrors['Zip Code'] &&

{debouncedErrors['Zip Code']}

} diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index fef6ffa..1e07fb4 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -1,4 +1,5 @@ import SEO from '@/components/SEO' +import { websiteLd } from '@/lib/seo' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/Card' import { services } from '@/data/services' import { industries } from '@/data/industries' @@ -48,23 +49,24 @@ const industryAccentStyles = [ ] const Home = () => { + // Single Organization entity — no LocalBusiness/address markup, since Queue North + // does not publish a physical location. const organizationLd = { '@context': 'https://schema.org', '@type': 'Organization', + '@id': 'https://queuenorth.com/#organization', name: 'Queue North Technologies', url: 'https://queuenorth.com', + image: 'https://queuenorth.com/assets/og-image.png', + telephone: '+1-321-730-8020', logo: { '@type': 'ImageObject', url: 'https://queuenorth.com/logo.png', }, description: 'Veteran-owned 8x8 Certified Partner and Cisco Certified Partner providing business phone systems, UCaaS, contact center, IT support, and networking solutions.', - address: { - '@type': 'PostalAddress', - streetAddress: '7901 4th St N', - addressLocality: 'St. Petersburg', - addressRegion: 'FL', - postalCode: '33702', - addressCountry: 'US', + areaServed: { + '@type': 'Country', + name: 'United States', }, contactPoint: [ { @@ -84,50 +86,17 @@ const Home = () => { sameAs: [ 'https://www.linkedin.com/company/queue-north-technologies-llc', 'https://www.facebook.com/QueueNorth', - ], - } - - const localBusinessLd = { - '@context': 'https://schema.org', - '@type': 'ProfessionalService', - '@id': 'https://queuenorth.com/#business', - name: 'Queue North Technologies', - image: 'https://queuenorth.com/assets/og-image.png', - url: 'https://queuenorth.com', - telephone: '+1-321-730-8020', - address: { - '@type': 'PostalAddress', - streetAddress: '7901 4th St N', - addressLocality: 'St. Petersburg', - addressRegion: 'FL', - postalCode: '33702', - addressCountry: 'US', - }, - geo: { - '@type': 'GeoCoordinates', - latitude: 27.8306, - longitude: -82.6765, - }, - priceRange: '$$', - openingHoursSpecification: { - '@type': 'OpeningHoursSpecification', - dayOfWeek: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'], - opens: '08:00', - closes: '18:00', - }, - sameAs: [ - 'https://www.linkedin.com/company/queue-north-technologies-llc', - 'https://www.facebook.com/QueueNorth', + 'https://www.instagram.com/queue_north/', ], } return ( <> {/* Hero Section */}
@@ -136,6 +105,9 @@ const Home = () => { src="/assets/hero-tech.webp" alt="Queue North technician working inside a communications rack" className="h-full w-full object-cover object-center" + loading="eager" + fetchPriority="high" + decoding="async" />
@@ -175,6 +147,8 @@ const Home = () => { src="/assets/brand/8x8-logo-dark-gray.png" alt="8x8 Certified Partner logo" className="h-full w-full object-contain" + loading="lazy" + decoding="async" /> 8x8 Certified Partner @@ -185,6 +159,8 @@ const Home = () => { src="/assets/brand/cisco-partner-logo-midnight.svg" alt="Cisco Partner certification logo" className="h-full w-full object-contain scale-[1.5]" + loading="lazy" + decoding="async" /> Cisco Certified Partner @@ -195,6 +171,8 @@ const Home = () => { src="/assets/brand/veteran-owned-certified-mark.webp" alt="SBA logo for Veteran-Owned Certified" className="h-full w-full object-contain" + loading="lazy" + decoding="async" /> Veteran-Owned Certified diff --git a/src/pages/Industries.jsx b/src/pages/Industries.jsx index d635afb..165224e 100644 --- a/src/pages/Industries.jsx +++ b/src/pages/Industries.jsx @@ -1,4 +1,5 @@ import SEO from '@/components/SEO' +import { buildBreadcrumbLd } from '@/lib/seo' import { industries } from '@/data/industries' import { ArrowRight, Building2, CheckCircle2, HeartPulse, ShoppingCart, Factory, Landmark } from 'lucide-react' import { Link } from 'react-router-dom' @@ -21,9 +22,10 @@ const Industries = () => { return ( <> {/* Hero */} @@ -33,6 +35,9 @@ const Industries = () => { src="/assets/local-networking.webp" alt="Network infrastructure used by businesses across industries" className="h-full w-full object-cover object-center" + loading="eager" + fetchPriority="high" + decoding="async" />
diff --git a/src/pages/IndustryDetail.jsx b/src/pages/IndustryDetail.jsx index 3edd2fa..74e922b 100644 --- a/src/pages/IndustryDetail.jsx +++ b/src/pages/IndustryDetail.jsx @@ -1,4 +1,5 @@ import SEO from '@/components/SEO' +import { buildBreadcrumbLd, clampDescription } from '@/lib/seo' import { useParams } from 'react-router-dom' import { industries } from '@/data/industries' import { Link } from 'react-router-dom' @@ -13,9 +14,10 @@ const IndustryDetail = () => { return (
@@ -30,9 +32,16 @@ const IndustryDetail = () => { ) } - const industryTitle = `${industry.name} | Queue North Technologies` - const industryDesc = industry.shortDesc || `Learn about Queue North Technologies solutions for the ${industry.name} industry.` + const industryTitle = `${industry.name} Communications & IT | Queue North` + const industryDesc = clampDescription( + industry.shortDesc, + `Queue North delivers phone, contact center, network, and IT support for ${industry.name.toLowerCase()} organizations.`, + ) const industryUrl = `https://queuenorth.com/industries/${industry.id}` + const industryBreadcrumbLd = buildBreadcrumbLd([ + { name: 'Industries', path: '/industries' }, + { name: industry.name, path: `/industries/${industry.id}` }, + ]) return ( <> @@ -40,6 +49,7 @@ const IndustryDetail = () => { title={industryTitle} description={industryDesc} url={industryUrl} + jsonLd={industryBreadcrumbLd} /> {/* Page Hero */}
@@ -48,6 +58,9 @@ const IndustryDetail = () => { src="/assets/modern-call-center.webp" alt="Business communications team supporting industry operations" className="h-full w-full object-cover object-center" + loading="eager" + fetchPriority="high" + decoding="async" />
diff --git a/src/pages/NotFound.jsx b/src/pages/NotFound.jsx index b53063c..4bbd03f 100644 --- a/src/pages/NotFound.jsx +++ b/src/pages/NotFound.jsx @@ -47,6 +47,9 @@ export default function NotFound() { src="/assets/about-image.webp" alt="" className="h-full w-full object-cover object-[66%_top] md:object-[62%_top]" + loading="eager" + fetchPriority="high" + decoding="async" />
diff --git a/src/pages/PrivacyPolicy.jsx b/src/pages/PrivacyPolicy.jsx new file mode 100644 index 0000000..547da67 --- /dev/null +++ b/src/pages/PrivacyPolicy.jsx @@ -0,0 +1,164 @@ +import SEO from '@/components/SEO' +import { buildBreadcrumbLd } from '@/lib/seo' +import { ShieldCheck } from 'lucide-react' +import { EFFECTIVE_DATE, LAST_UPDATED, PRIVACY_EMAIL, sections } from '@/data/privacyPolicy' + +const EmailLink = ({ className = '' }) => ( + + {PRIVACY_EMAIL} + +) + +// Renders a paragraph, splitting the privacy address out as a mailto link when present. +const Paragraph = ({ text, linkEmail }) => { + if (!linkEmail || !text.includes(PRIVACY_EMAIL)) { + return

{text}

+ } + + const [before, after] = text.split(PRIVACY_EMAIL) + return ( +

+ {before} + + {after} +

+ ) +} + +const Block = ({ block }) => { + switch (block.type) { + case 'h3': + return

{block.text}

+ + case 'ul': + return ( +
    + {block.items.map((item) => ( +
  • +
  • + ))} +
+ ) + + case 'callout': + return ( +

+ {block.text} +

+ ) + + case 'email': + return ( +

+ +

+ ) + + case 'contactBlock': + return ( +
+

Queue North Technologies

+

+ Email: +

+

+ Website:{' '} + + https://queuenorth.com + +

+
+ ) + + default: + return + } +} + +const PrivacyPolicy = () => { + const numberedSections = sections.filter((section) => section.number) + + return ( + <> + + + {/* Page Hero */} +
+
+
+
+

+ Queue North Technologies Privacy Policy +

+
+
+
Effective Date:
+
{EFFECTIVE_DATE}
+
+
+
Last Updated:
+
{LAST_UPDATED}
+
+
+
+
+ + {/* Policy Body */} +
+
+ {/* Contents */} + + + {sections.map((section) => ( +
+

+ {section.number ? ( + <> + {section.number}. {section.title} + + ) : ( + section.title + )} +

+ {section.blocks.map((block, index) => ( + + ))} +
+ ))} +
+
+ + ) +} + +export default PrivacyPolicy diff --git a/src/pages/ServiceDetail.jsx b/src/pages/ServiceDetail.jsx index 0e6b2ed..20a595c 100644 --- a/src/pages/ServiceDetail.jsx +++ b/src/pages/ServiceDetail.jsx @@ -1,4 +1,5 @@ import SEO from '@/components/SEO' +import { buildBreadcrumbLd, clampDescription } from '@/lib/seo' import { useParams } from 'react-router-dom' import { services } from '@/data/services' import { Link } from 'react-router-dom' @@ -19,9 +20,10 @@ const ServiceDetail = () => { return (
@@ -36,9 +38,16 @@ const ServiceDetail = () => { ) } - const serviceTitle = `${service.name} | Queue North Technologies` - const serviceDesc = service.shortDesc || `Learn about ${service.name} from Queue North Technologies.` + const serviceTitle = `${service.name} | Queue North` + const serviceDesc = clampDescription( + service.shortDesc, + 'Delivered by Queue North, a veteran-owned 8x8 and Cisco Certified Partner.', + ) const serviceUrl = `https://queuenorth.com/services/${service.id}` + const serviceBreadcrumbLd = buildBreadcrumbLd([ + { name: 'Services', path: '/services' }, + { name: service.name, path: `/services/${service.id}` }, + ]) const serviceDetailLd = { '@context': 'https://schema.org', '@type': 'Service', @@ -61,7 +70,7 @@ const ServiceDetail = () => { title={serviceTitle} description={serviceDesc} url={serviceUrl} - jsonLd={serviceDetailLd} + jsonLd={[serviceDetailLd, serviceBreadcrumbLd]} /> {/* Page Hero */}
@@ -70,6 +79,9 @@ const ServiceDetail = () => { src={service.image || '/assets/hero-tech.webp'} alt={serviceImageAlt[service.id] || `${service.name} service visual`} className="h-full w-full object-cover object-center" + loading="eager" + fetchPriority="high" + decoding="async" />
diff --git a/src/pages/Services.jsx b/src/pages/Services.jsx index c1a12f3..5458086 100644 --- a/src/pages/Services.jsx +++ b/src/pages/Services.jsx @@ -1,4 +1,5 @@ import SEO from '@/components/SEO' +import { buildBreadcrumbLd } from '@/lib/seo' import { services } from '@/data/services' import { ArrowRight, MessageCircle, Users, LifeBuoy, GraduationCap, Link as LinkIcon, Wifi, Network, Layers, CheckCircle2, ShieldCheck, PhoneCall } from 'lucide-react' import { Link } from 'react-router-dom' @@ -65,10 +66,10 @@ const Services = () => { return ( <> {/* Hero */} @@ -78,6 +79,9 @@ const Services = () => { src="/assets/hero-tech.webp" alt="Queue North technician working inside a communications rack" className="h-full w-full object-cover object-center" + loading="eager" + fetchPriority="high" + decoding="async" />
diff --git a/src/pages/Support.jsx b/src/pages/Support.jsx index 66ed13d..509aac0 100644 --- a/src/pages/Support.jsx +++ b/src/pages/Support.jsx @@ -1,4 +1,5 @@ import SEO from '@/components/SEO' +import { buildBreadcrumbLd } from '@/lib/seo' import { AlertCircle, ArrowRight, CheckCircle2, Clock3, ExternalLink, LifeBuoy, ShieldCheck, TicketCheck, Wrench } from 'lucide-react' const portalLinks = [ @@ -34,6 +35,7 @@ const Support = () => { title="IT Support & Help Desk | Queue North Technologies" description="Get IT support and help desk services from Queue North Technologies. 24/7 monitoring, rapid response SLAs, and dedicated support engineers for your business." url="https://queuenorth.com/support" + jsonLd={buildBreadcrumbLd([{ name: 'Support', path: '/support' }])} /> {/* Page Hero */}
@@ -42,6 +44,9 @@ const Support = () => { src="/assets/modern-call-center.webp" alt="Support team managing communications requests" className="h-full w-full object-cover object-center" + loading="eager" + fetchPriority="high" + decoding="async" />
diff --git a/src/router.jsx b/src/router.jsx index fac6072..9753d23 100644 --- a/src/router.jsx +++ b/src/router.jsx @@ -1,33 +1,6 @@ import { createBrowserRouter } from 'react-router-dom' -import App from './App.jsx' -import Home from './pages/Home.jsx' -import About from './pages/About.jsx' -import Services from './pages/Services.jsx' -import ServiceDetail from './pages/ServiceDetail.jsx' -import Industries from './pages/Industries.jsx' -import IndustryDetail from './pages/IndustryDetail.jsx' -import Contact from './pages/Contact.jsx' -import Support from './pages/Support.jsx' -import NotFound from './pages/NotFound.jsx' +import { routes } from './routes.jsx' -const router = createBrowserRouter([ - { - path: '/', - element: ( - - ), - children: [ - { index: true, element: }, - { path: 'about', element: }, - { path: 'services', element: }, - { path: 'services/:slug', element: }, - { path: 'industries', element: }, - { path: 'industries/:slug', element: }, - { path: 'contact', element: }, - { path: 'support', element: }, - { path: '*', element: }, - ], - }, -]) +const router = createBrowserRouter(routes) export default router diff --git a/src/routes.jsx b/src/routes.jsx new file mode 100644 index 0000000..b8d5163 --- /dev/null +++ b/src/routes.jsx @@ -0,0 +1,34 @@ +import App from './App.jsx' +import Home from './pages/Home.jsx' +import About from './pages/About.jsx' +import Services from './pages/Services.jsx' +import ServiceDetail from './pages/ServiceDetail.jsx' +import Industries from './pages/Industries.jsx' +import IndustryDetail from './pages/IndustryDetail.jsx' +import Contact from './pages/Contact.jsx' +import Support from './pages/Support.jsx' +import PrivacyPolicy from './pages/PrivacyPolicy.jsx' +import NotFound from './pages/NotFound.jsx' + +// Shared between the browser router (src/router.jsx) and the build-time +// prerenderer (src/entry-server.jsx) so both render an identical tree. +export const routes = [ + { + path: '/', + element: , + children: [ + { index: true, element: }, + { path: 'about', element: }, + { path: 'services', element: }, + { path: 'services/:slug', element: }, + { path: 'industries', element: }, + { path: 'industries/:slug', element: }, + { path: 'contact', element: }, + { path: 'support', element: }, + { path: 'privacy-policy', element: }, + { path: '*', element: }, + ], + }, +] + +export default routes diff --git a/vite.config.js b/vite.config.js index 73fc649..4e66a1a 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,7 +2,17 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import path from 'path' -export default defineConfig({ +// Split rarely-changing vendor code out of the app chunk so repeat visits and +// post-deploy cache hits don't re-download React, the router, and the icon set. +const manualChunks = (id) => { + if (!id.includes('node_modules')) return undefined + if (id.includes('lucide-react')) return 'icons' + if (id.includes('react-router')) return 'router' + if (/node_modules\/(react|react-dom|scheduler)\//.test(id)) return 'react-vendor' + return undefined +} + +export default defineConfig(({ isSsrBuild }) => ({ plugins: [react()], resolve: { alias: { @@ -21,5 +31,7 @@ export default defineConfig({ build: { outDir: 'dist', sourcemap: process.env.NODE_ENV !== 'production', + // The SSR bundle externalises its dependencies, so chunking does not apply. + rollupOptions: isSsrBuild ? {} : { output: { manualChunks } }, }, -}) +}))