From 80ba80c303213c84818dc86ddb6a3384a45dc037 Mon Sep 17 00:00:00 2001
From: Carson <92652800+carsonSgit@users.noreply.github.com>
Date: Sun, 26 Oct 2025 01:42:59 -0700
Subject: [PATCH 1/6] hero
---
app/globals.css | 64 +++++++
app/page.tsx | 43 +++--
components.json | 4 +-
components/ascii-eye.tsx | 108 +++++-------
components/ui/button.tsx | 1 +
components/ui/flip-words.tsx | 98 +++++++++++
components/ui/luxe-button.tsx | 271 ++++++++++++++++++++++++++++++
components/ui/navigation-menu.tsx | 210 +++++++++++++++++++++++
package.json | 10 +-
pnpm-lock.yaml | 63 ++++++-
utils/cn.ts | 6 +
11 files changed, 797 insertions(+), 81 deletions(-)
create mode 100644 components/ui/flip-words.tsx
create mode 100644 components/ui/luxe-button.tsx
create mode 100644 components/ui/navigation-menu.tsx
create mode 100644 utils/cn.ts
diff --git a/app/globals.css b/app/globals.css
index f99733f..7062976 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -41,6 +41,14 @@
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
+ --color-main: var(--main);
+ --color-main-secondary: var(--main-secondary);
+ --color-main-foreground: var(--main-foreground);
+ --color-main-muted: var(--main-muted);
+ --color-main-background: var(--main-background);
+ --color-main-invert: var(--main-invert);
+ --color-primary-muted: var(--primary-muted);
+ --color-primary-invert: var(--primary-invert);
}
:root {
@@ -76,6 +84,16 @@
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
+
+ /* Luxe UI variables */
+ --main: oklch(0.97 0 0);
+ --main-secondary: oklch(97% 0 0);
+ --main-foreground: oklch(0.925 0 0);
+ --main-muted: oklch(0.96 0 0);
+ --main-background: oklch(0.97 0 0);
+ --main-invert: oklch(0.205 0 0);
+ --primary-muted: oklch(0.556 0 0);
+ --primary-invert: oklch(1 0 0);
}
.dark {
@@ -110,8 +128,17 @@
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
+
+ /* Luxe UI dark mode variables */
+ --main: oklch(0.178 0 0);
+ --main-foreground: oklch(0.269 0 0);
+ --main-muted: oklch(0.168 0 0);
+ --main-background: oklch(0.145 0 0);
+ --primary-muted: oklch(0.708 0 0);
}
+
+
@layer base {
* {
@apply border-border outline-ring/50;
@@ -141,4 +168,41 @@
.animate-breathe {
animation: breathe 5s ease-in-out infinite;
}
+
+ @keyframes shine {
+ 0% {
+ background-position: 0% 0%;
+ }
+ 50% {
+ background-position: 100% 100%;
+ }
+ 100% {
+ background-position: 0% 0%;
+ }
+ }
+
+ .animate-shine {
+ animation: shine 10s linear infinite;
+ }
+
+ @keyframes brightness {
+ 0% {
+ opacity: 0;
+ transform: translateX(-100%) skewX(-45deg);
+ }
+ 5% {
+ opacity: 1;
+ }
+ 95% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ transform: translateX(200%) skewX(-45deg);
+ }
+ }
+
+ .animate-brightness {
+ animation: brightness 2s ease-in-out infinite;
+ }
}
diff --git a/app/page.tsx b/app/page.tsx
index ca4726b..d643cea 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,11 +1,17 @@
'use client'
-import { Button } from "@/components/ui/button";
import Link from "next/link";
import { AsciiEye } from "@/components/ascii-eye";
-import Dither from '@/components/dither'
import { useState, useEffect } from 'react';
import TextType from "@/components/text-type"
+import { LuxeButton } from "@/components/ui/luxe-button";
+import {
+ NavigationMenu,
+ NavigationMenuList,
+ NavigationMenuItem,
+ NavigationMenuLink,
+} from "@/components/ui/navigation-menu";
+import Dither from "@/components/dither";
export default function Home() {
const [isLoading, setIsLoading] = useState(true);
@@ -50,6 +56,23 @@ export default function Home() {
)}
+ {/* Navigation Menu */}
+
+
+
+
+ Overview
+
+
+ Features
+
+
+ Contact
+
+
+
+
+
{/* Main Content */}
{/* Dither background */}
@@ -67,18 +90,18 @@ export default function Home() {
{/* Left side - Main content */}
-
-
-
ARGUS
-
+
+
+
ARGUS
+
+ Open Argus
+
{/* Right side - ASCII Eye */}
-
-
+
diff --git a/components.json b/components.json
index b7b9791..ce89abd 100644
--- a/components.json
+++ b/components.json
@@ -18,5 +18,7 @@
"lib": "@/lib",
"hooks": "@/hooks"
},
- "registries": {}
+ "registries": {
+ "@aceternity": "https://ui.aceternity.com/registry/{name}.json"
+ }
}
diff --git a/components/ascii-eye.tsx b/components/ascii-eye.tsx
index f8bea7c..4e4457e 100644
--- a/components/ascii-eye.tsx
+++ b/components/ascii-eye.tsx
@@ -71,9 +71,6 @@ interface CharData {
export const AsciiEye = memo(function AsciiEye() {
const spansRef = useRef
([]);
const nonWhitespaceIndicesRef = useRef([]);
- const rafIdRef = useRef(undefined);
- const lastColorUpdateRef = useRef(0);
- const lastScrambleUpdateRef = useRef(0);
const scrambleTimeoutRef = useRef(undefined);
// Memoize character data - only parse once
@@ -122,77 +119,64 @@ export const AsciiEye = memo(function AsciiEye() {
return data;
}, []);
- // Optimized animation loop using requestAnimationFrame
+ // Use setInterval instead of RAF for much better performance
useEffect(() => {
- let isActive = true;
+ let colorInterval: NodeJS.Timeout | undefined;
+ let scrambleInterval: NodeJS.Timeout | undefined;
- const animate = (timestamp: number) => {
- if (!isActive) return;
-
- // Color update - every 800ms, but only update a batch of characters
- if (timestamp - lastColorUpdateRef.current >= 800) {
- lastColorUpdateRef.current = timestamp;
-
- // Batch update colors - only update a subset for better performance
- const batchSize = Math.ceil(nonWhitespaceIndicesRef.current.length / 3);
- const startIdx = Math.floor(Math.random() * (nonWhitespaceIndicesRef.current.length - batchSize));
+ // Color update - every 2000ms (increased from 800ms)
+ colorInterval = setInterval(() => {
+ // Update only a small batch of characters
+ const batchSize = Math.min(50, Math.ceil(nonWhitespaceIndicesRef.current.length / 10));
+ const startIdx = Math.floor(Math.random() * (nonWhitespaceIndicesRef.current.length - batchSize));
+
+ for (let i = startIdx; i < startIdx + batchSize && i < nonWhitespaceIndicesRef.current.length; i++) {
+ const idx = nonWhitespaceIndicesRef.current[i];
+ const char = charData[idx];
+ const span = spansRef.current[idx];
- for (let i = startIdx; i < startIdx + batchSize && i < nonWhitespaceIndicesRef.current.length; i++) {
- const idx = nonWhitespaceIndicesRef.current[i];
- const char = charData[idx];
- const span = spansRef.current[idx];
-
- if (span) {
- const newColor = getRandomColor(char.isDarkChar);
- span.style.color = newColor;
- }
+ if (span) {
+ const newColor = getRandomColor(char.isDarkChar);
+ span.style.color = newColor;
}
}
+ }, 2000);
- // Character scrambling - every 1000ms
- if (timestamp - lastScrambleUpdateRef.current >= 1000) {
- lastScrambleUpdateRef.current = timestamp;
-
- const numToScramble = 15 + Math.floor(Math.random() * 5);
- const scrambledIndices: number[] = [];
+ // Character scrambling - every 2000ms (increased from 1000ms)
+ scrambleInterval = setInterval(() => {
+ const numToScramble = 10; // Reduced from 15-20
+ const scrambledIndices: number[] = [];
+
+ // Scramble random characters
+ for (let i = 0; i < numToScramble; i++) {
+ const randomIdx = Math.floor(Math.random() * nonWhitespaceIndicesRef.current.length);
+ const idx = nonWhitespaceIndicesRef.current[randomIdx];
+ scrambledIndices.push(idx);
- // Scramble random characters
- for (let i = 0; i < numToScramble; i++) {
- const randomIdx = Math.floor(Math.random() * nonWhitespaceIndicesRef.current.length);
- const idx = nonWhitespaceIndicesRef.current[randomIdx];
- scrambledIndices.push(idx);
-
- const span = spansRef.current[idx];
- if (span) {
- span.textContent = getRandomBrailleChar();
- }
- }
-
- // Reset scrambled characters after delay
- if (scrambleTimeoutRef.current) {
- window.clearTimeout(scrambleTimeoutRef.current);
+ const span = spansRef.current[idx];
+ if (span) {
+ span.textContent = getRandomBrailleChar();
}
-
- scrambleTimeoutRef.current = window.setTimeout(() => {
- scrambledIndices.forEach((idx) => {
- const span = spansRef.current[idx];
- if (span) {
- span.textContent = charData[idx].originalChar;
- }
- });
- }, 150);
}
- rafIdRef.current = requestAnimationFrame(animate);
- };
-
- rafIdRef.current = requestAnimationFrame(animate);
+ // Reset scrambled characters after delay
+ if (scrambleTimeoutRef.current) {
+ window.clearTimeout(scrambleTimeoutRef.current);
+ }
+
+ scrambleTimeoutRef.current = window.setTimeout(() => {
+ scrambledIndices.forEach((idx) => {
+ const span = spansRef.current[idx];
+ if (span) {
+ span.textContent = charData[idx].originalChar;
+ }
+ });
+ }, 150);
+ }, 2000);
return () => {
- isActive = false;
- if (rafIdRef.current) {
- cancelAnimationFrame(rafIdRef.current);
- }
+ if (colorInterval) clearInterval(colorInterval);
+ if (scrambleInterval) clearInterval(scrambleInterval);
if (scrambleTimeoutRef.current) {
window.clearTimeout(scrambleTimeoutRef.current);
}
diff --git a/components/ui/button.tsx b/components/ui/button.tsx
index 21409a0..a138a30 100644
--- a/components/ui/button.tsx
+++ b/components/ui/button.tsx
@@ -19,6 +19,7 @@ const buttonVariants = cva(
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
+
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
diff --git a/components/ui/flip-words.tsx b/components/ui/flip-words.tsx
new file mode 100644
index 0000000..43e1cc5
--- /dev/null
+++ b/components/ui/flip-words.tsx
@@ -0,0 +1,98 @@
+"use client";
+import React, { useCallback, useEffect, useRef, useState } from "react";
+import { AnimatePresence, motion, LayoutGroup } from "motion/react";
+import { cn } from "@/lib/utils";
+
+export const FlipWords = ({
+ words,
+ duration = 3000,
+ className,
+}: {
+ words: string[];
+ duration?: number;
+ className?: string;
+}) => {
+ const [currentWord, setCurrentWord] = useState(words[0]);
+ const [isAnimating, setIsAnimating] = useState(false);
+
+ // thanks for the fix Julian - https://github.com/Julian-AT
+ const startAnimation = useCallback(() => {
+ const word = words[words.indexOf(currentWord) + 1] || words[0];
+ setCurrentWord(word);
+ setIsAnimating(true);
+ }, [currentWord, words]);
+
+ useEffect(() => {
+ if (!isAnimating)
+ setTimeout(() => {
+ startAnimation();
+ }, duration);
+ }, [isAnimating, duration, startAnimation]);
+
+ return (
+ {
+ setIsAnimating(false);
+ }}
+ >
+
+ {/* edit suggested by Sajal: https://x.com/DewanganSajal */}
+ {currentWord.split(" ").map((word, wordIndex) => (
+
+ {word.split("").map((letter, letterIndex) => (
+
+ {letter}
+
+ ))}
+
+
+ ))}
+
+
+ );
+};
diff --git a/components/ui/luxe-button.tsx b/components/ui/luxe-button.tsx
new file mode 100644
index 0000000..baad29a
--- /dev/null
+++ b/components/ui/luxe-button.tsx
@@ -0,0 +1,271 @@
+'use client' // @NOTE: Add in case you are using Next.js
+
+import { useRef, useState } from 'react'
+
+import { motion } from 'motion/react'
+import * as Slot from '@radix-ui/react-slot'
+
+import { cn } from '@/utils/cn'
+
+type Variant = {
+ variant: string
+ component: React.FC>
+}
+
+const variants = [
+ {
+ variant: 'default',
+ component: ({ className, ...props }) => (
+
+ ),
+ },
+ {
+ variant: 'outline',
+ component: ({ className, ...props }) => (
+
+ ),
+ },
+ {
+ variant: 'success',
+ component: ({ className, ...props }) => (
+
+ ),
+ },
+ {
+ variant: 'destructive',
+ component: ({ className, ...props }) => (
+
+ ),
+ },
+ {
+ variant: 'shine',
+ component: ({ className, ...props }) => (
+
+ ),
+ },
+ {
+ variant: 'animated-border',
+ component: ({ children, className, ...props }) => (
+
+ ),
+ },
+ {
+ variant: 'rotate-border',
+ component: ({ children, className, ...props }) => (
+
+ ),
+ },
+ {
+ variant: 'glitch-brightness',
+ component: ({ children, className, ...props }) => {
+ return (
+
+ )
+
+ function TextGlitch({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ {children}
+
+
+ {children}
+
+
+ )
+ }
+
+ function Brightness() {
+ return (
+
+ )
+ }
+ },
+ },
+] as const satisfies readonly Variant[]
+
+export type LuxeButtonProps = {
+ variant?: (typeof variants)[number]['variant']
+ isMagnetic?: boolean
+} & React.ComponentProps<'button'>
+
+export function LuxeButton({
+ variant = 'default',
+ isMagnetic = false,
+ className,
+ ...props
+}: LuxeButtonProps) {
+ const FALLBACK_INDEX = 0
+
+ const variantComponent = variants.find(v => v.variant === variant)?.component
+
+ const Component = variantComponent || variants[FALLBACK_INDEX].component
+
+ const buttonContent = (
+
+
+
+ )
+
+ if (isMagnetic) {
+ return (
+
+ {buttonContent}
+
+ )
+ }
+
+ return buttonContent
+}
+
+function Magnetic({ children }: { children: React.ReactNode }) {
+ const { ref, handleMouseMove, handleMouseLeave, x, y } = useMagnetic()
+
+ return (
+
+ {children}
+
+ )
+}
+
+function useMagnetic() {
+ const [position, setPosition] = useState({ x: 0, y: 0 })
+ const ref = useRef(null)
+
+ function handleMouseMove(e: React.MouseEvent) {
+ const { clientX, clientY } = e
+ const { height, width, left, top } = ref.current!.getBoundingClientRect()
+
+ const middleX = clientX - (left + width / 2)
+ const middleY = clientY - (top + height / 2)
+
+ setPosition({ x: middleX, y: middleY })
+ }
+
+ function handleMouseLeave() {
+ setPosition({ x: 0, y: 0 })
+ }
+
+ const { x, y } = position
+
+ return { ref, handleMouseMove, handleMouseLeave, x, y }
+}
diff --git a/components/ui/navigation-menu.tsx b/components/ui/navigation-menu.tsx
new file mode 100644
index 0000000..3b50737
--- /dev/null
+++ b/components/ui/navigation-menu.tsx
@@ -0,0 +1,210 @@
+'use client' // @NOTE: Add in case you are using Next.js
+
+import { useState } from 'react'
+
+import * as RadixNavigationMenu from '@radix-ui/react-navigation-menu'
+import { AnimatePresence, motion, useReducedMotion } from 'motion/react'
+
+import { cn } from '@/utils/cn'
+
+type NavigationMenuProps = React.ComponentProps
+
+export function NavigationMenu({
+ className,
+ children,
+ ...props
+}: NavigationMenuProps) {
+ return (
+
+ {children}
+
+ )
+}
+
+type NavigationMenuListProps = React.ComponentProps<
+ typeof RadixNavigationMenu.List
+>
+
+export function NavigationMenuList({
+ className,
+ ...props
+}: NavigationMenuListProps) {
+ return (
+
+ )
+}
+
+type NavigationMenuItemProps = React.ComponentProps<
+ typeof RadixNavigationMenu.Item
+>
+
+export function NavigationMenuItem({
+ className,
+ ...props
+}: NavigationMenuItemProps) {
+ return (
+
+ )
+}
+
+type NavigationMenuTriggerProps = React.ComponentProps<
+ typeof RadixNavigationMenu.Trigger
+>
+
+export function NavigationMenuTrigger({
+ className,
+ children,
+ ...props
+}: NavigationMenuTriggerProps) {
+ return (
+
+ {children}
+
+
+ )
+}
+
+type NavigationMenuContentProps = React.ComponentProps<
+ typeof RadixNavigationMenu.Content
+>
+
+export function NavigationMenuContent({
+ className,
+ ...props
+}: NavigationMenuContentProps) {
+ return (
+
+ )
+}
+
+type NavigationMenuContentItemProps = React.ComponentProps<
+ typeof RadixNavigationMenu.Link
+>
+
+export function NavigationMenuContentItem({
+ children,
+ className,
+ ...props
+}: NavigationMenuContentItemProps) {
+ const [isHovered, setIsHovered] = useState(false)
+
+ const isReducedMotion = useReducedMotion()
+
+ const interactionProps = !isReducedMotion && {
+ onMouseEnter: () => setIsHovered(true),
+ onMouseLeave: () => setIsHovered(false),
+ onFocus: () => setIsHovered(true),
+ onBlur: () => setIsHovered(false),
+ }
+
+ return (
+
+
+ {children}
+
+ {!isReducedMotion && (
+
+ {isHovered && (
+
+ )}
+
+ )}
+
+ )
+}
+
+type NavigationMenuLinkProps = React.ComponentProps<
+ typeof RadixNavigationMenu.Link
+>
+
+export function NavigationMenuLink({
+ className,
+ ...props
+}: NavigationMenuLinkProps) {
+ return (
+
+ )
+}
diff --git a/package.json b/package.json
index feb4988..616ed7f 100644
--- a/package.json
+++ b/package.json
@@ -43,6 +43,7 @@
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-hover-card": "^1.1.15",
"@radix-ui/react-label": "^2.1.7",
+ "@radix-ui/react-navigation-menu": "^1.2.14",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-scroll-area": "^1.2.10",
@@ -64,17 +65,15 @@
"@types/d3-color": "^3.1.3",
"@types/d3-scale": "^4.0.9",
"@types/d3-scale-chromatic": "^3.1.0",
+ "@xyflow/react": "^12.9.0",
+ "ai": "^5.0.79",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
+ "cmdk": "^1.1.1",
"d3-color": "^3.1.0",
"d3-interpolate": "^3.0.1",
"d3-scale": "^4.0.2",
"d3-scale-chromatic": "^3.1.0",
- "@xyflow/react": "^12.9.0",
- "ai": "^5.0.79",
- "class-variance-authority": "^0.7.1",
- "clsx": "^2.1.1",
- "cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"embla-carousel-react": "^8.6.0",
"framer-motion": "^12.23.24",
@@ -95,6 +94,7 @@
"sonner": "^2.0.7",
"streamdown": "^1.4.0",
"tailwind-merge": "^3.3.1",
+ "tailwind-variants": "^3.1.1",
"three": "^0.180.0",
"tokenlens": "^1.3.1",
"use-stick-to-bottom": "^1.1.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0da6a76..91f03c2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -71,6 +71,9 @@ importers:
'@radix-ui/react-label':
specifier: ^2.1.7
version: 2.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ '@radix-ui/react-navigation-menu':
+ specifier: ^1.2.14
+ version: 1.2.14(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-popover':
specifier: ^1.1.15
version: 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@@ -146,6 +149,9 @@ importers:
clsx:
specifier: ^2.1.1
version: 2.1.1
+ cmdk:
+ specifier: ^1.1.1
+ version: 1.1.1(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
d3-color:
specifier: ^3.1.0
version: 3.1.0
@@ -158,9 +164,6 @@ importers:
d3-scale-chromatic:
specifier: ^3.1.0
version: 3.1.0
- cmdk:
- specifier: ^1.1.1
- version: 1.1.1(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
date-fns:
specifier: ^4.1.0
version: 4.1.0
@@ -221,6 +224,9 @@ importers:
tailwind-merge:
specifier: ^3.3.1
version: 3.3.1
+ tailwind-variants:
+ specifier: ^3.1.1
+ version: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.15)
three:
specifier: ^0.180.0
version: 0.180.0
@@ -937,6 +943,19 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-navigation-menu@1.2.14':
+ resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-popover@1.1.15':
resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==}
peerDependencies:
@@ -3004,6 +3023,16 @@ packages:
tailwind-merge@3.3.1:
resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==}
+ tailwind-variants@3.1.1:
+ resolution: {integrity: sha512-ftLXe3krnqkMHsuBTEmaVUXYovXtPyTK7ckEfDRXS8PBZx0bAUas+A0jYxuKA5b8qg++wvQ3d2MQ7l/xeZxbZQ==}
+ engines: {node: '>=16.x', pnpm: '>=7.x'}
+ peerDependencies:
+ tailwind-merge: '>=3.0.0'
+ tailwindcss: '*'
+ peerDependenciesMeta:
+ tailwind-merge:
+ optional: true
+
tailwindcss@4.1.15:
resolution: {integrity: sha512-k2WLnWkYFkdpRv+Oby3EBXIyQC8/s1HOFMBUViwtAh6Z5uAozeUSMQlIsn/c6Q2iJzqG6aJT3wdPaRNj70iYxQ==}
@@ -3877,6 +3906,28 @@ snapshots:
'@types/react': 19.2.2
'@types/react-dom': 19.2.2(@types/react@19.2.2)
+ '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.1.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.1.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.2)(react@19.1.0)
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.1.0)
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.1.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.1.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.1.0)
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.2)(react@19.1.0)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ react: 19.1.0
+ react-dom: 19.1.0(react@19.1.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
'@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@radix-ui/primitive': 1.1.3
@@ -6385,6 +6436,12 @@ snapshots:
tailwind-merge@3.3.1: {}
+ tailwind-variants@3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.15):
+ dependencies:
+ tailwindcss: 4.1.15
+ optionalDependencies:
+ tailwind-merge: 3.3.1
+
tailwindcss@4.1.15: {}
tapable@2.3.0: {}
diff --git a/utils/cn.ts b/utils/cn.ts
new file mode 100644
index 0000000..365058c
--- /dev/null
+++ b/utils/cn.ts
@@ -0,0 +1,6 @@
+import { type ClassValue, clsx } from "clsx";
+import { twMerge } from "tailwind-merge";
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
From e7c878e5f1576857962ab973a074e598df5adeac Mon Sep 17 00:00:00 2001
From: Carson <92652800+carsonSgit@users.noreply.github.com>
Date: Sun, 26 Oct 2025 04:10:50 -0700
Subject: [PATCH 2/6] features
---
app/globals.css | 11 +-
app/page.tsx | 152 ++++++++++++++++++++++---
components/browser-component.tsx | 51 +++++++++
components/features-alternating.tsx | 141 +++++++++++++++++++++++
components/landing-animated-tabs.tsx | 76 +++++++++++++
components/ui/button.tsx | 1 -
components/ui/sticky-scroll-reveal.tsx | 97 ++++++++++++++++
package.json | 1 +
pnpm-lock.yaml | 9 ++
public/assets/arguschat.webp | Bin 0 -> 55642 bytes
public/assets/argusdash.webp | Bin 0 -> 105434 bytes
public/assets/argusdetection.webp | Bin 0 -> 83454 bytes
public/assets/argusreports.webp | Bin 0 -> 62620 bytes
public/assets/argussearch.webp | Bin 0 -> 104314 bytes
public/assets/argusstats.webp | Bin 0 -> 60796 bytes
15 files changed, 520 insertions(+), 19 deletions(-)
create mode 100644 components/browser-component.tsx
create mode 100644 components/features-alternating.tsx
create mode 100644 components/landing-animated-tabs.tsx
create mode 100644 components/ui/sticky-scroll-reveal.tsx
create mode 100644 public/assets/arguschat.webp
create mode 100644 public/assets/argusdash.webp
create mode 100644 public/assets/argusdetection.webp
create mode 100644 public/assets/argusreports.webp
create mode 100644 public/assets/argussearch.webp
create mode 100644 public/assets/argusstats.webp
diff --git a/app/globals.css b/app/globals.css
index 7062976..39dca21 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -59,7 +59,7 @@
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
- --primary: oklch(0.205 0 0);
+ --primary: oklch(0 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
@@ -103,7 +103,7 @@
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
- --primary: oklch(0.922 0 0);
+ --primary: oklch(1 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
@@ -135,6 +135,7 @@
--main-muted: oklch(0.168 0 0);
--main-background: oklch(0.145 0 0);
--primary-muted: oklch(0.708 0 0);
+ --primary-invert: oklch(0 0 0);
}
@@ -147,7 +148,11 @@
html,
body,
#__next {
- @apply h-full overflow-hidden;
+ @apply h-full;
+ }
+
+ body {
+ @apply overflow-x-hidden overflow-y-auto;
}
body {
diff --git a/app/page.tsx b/app/page.tsx
index d643cea..7078bec 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,6 +1,7 @@
'use client'
import Link from "next/link";
+import Image from "next/image";
import { AsciiEye } from "@/components/ascii-eye";
import { useState, useEffect } from 'react';
import TextType from "@/components/text-type"
@@ -12,6 +13,8 @@ import {
NavigationMenuLink,
} from "@/components/ui/navigation-menu";
import Dither from "@/components/dither";
+import { BrowserComponent } from "@/components/browser-component";
+import { FeaturesAlternating } from "@/components/features-alternating";
export default function Home() {
const [isLoading, setIsLoading] = useState(true);
@@ -34,6 +37,113 @@ export default function Home() {
loadContent();
}, []);
+ const featuresContent = [
+ {
+ title: "Live Dashboard",
+ description: "Dashboard showcasing all current RTMP streams with automated video asset creation.",
+ content: (
+
+
+
+
+
+ ),
+ },
+ {
+ title: "Entity & Event Detection",
+ description: "Entity and event detection with AI-powered analysis.",
+ content: (
+
+
+
+
+
+ ),
+ },
+ {
+ title: "Analytics & Statistics",
+ description: "Comprehensive stats from all events and anomalies detected.",
+ content: (
+
+
+
+
+
+ ),
+ },
+ {
+ title: "Automated Reports",
+ description: "Auto-generated editable rich incident reports based on detected events.",
+ content: (
+
+
+
+
+
+ ),
+ },
+ {
+ title: "Elasticsearch Agent",
+ description: "Search through all detected anomalies and events with powerful Elasticsearch Agent integration.",
+ content: (
+
+
+
+
+
+ ),
+ },
+ {
+ title: "AI Assistant",
+ description: "Search for specific event types, ask questions, generate reports, and more.",
+ content: (
+
+
+
+
+
+ ),
+ },
+ ];
+
return (
<>
{/* Loading Screen */}
@@ -56,6 +166,20 @@ export default function Home() {
)}
+ {/* Dither background - covers entire page */}
+
+
+
+
{/* Navigation Menu */}
@@ -74,25 +198,12 @@ export default function Home() {
{/* Main Content */}
-
- {/* Dither background */}
-
-
-
+
{/* Left side - Main content */}
-
ARGUS
+ ARGUS
Open Argus
@@ -106,6 +217,17 @@ export default function Home() {
+
+ {/* Features Section */}
+
+
+
Features
+
+ Discover the powerful capabilities that make Argus the ultimate surveillance and monitoring solution.
+
+
+
+
>
);
}
\ No newline at end of file
diff --git a/components/browser-component.tsx b/components/browser-component.tsx
new file mode 100644
index 0000000..aca3a04
--- /dev/null
+++ b/components/browser-component.tsx
@@ -0,0 +1,51 @@
+import { cn } from '@/utils/cn'
+
+export const BrowserComponent: React.FC<{ children?: React.ReactNode; className?: string; url?: string }> = ({
+ className,
+ children,
+ url = "yourwebsite.com/admin/sales"
+}) => (
+
+)
diff --git a/components/features-alternating.tsx b/components/features-alternating.tsx
new file mode 100644
index 0000000..d9d000e
--- /dev/null
+++ b/components/features-alternating.tsx
@@ -0,0 +1,141 @@
+"use client";
+
+import { useEffect, useRef } from "react";
+import { gsap } from "gsap";
+import { ScrollTrigger } from "gsap/ScrollTrigger";
+import { LuxeCard, LuxeCardHeader, LuxeCardTitle, LuxeCardDescription } from "@/components/ui/luxe-card";
+
+gsap.registerPlugin(ScrollTrigger);
+
+interface FeaturesAlternatingProps {
+ features: Array<{
+ title: string;
+ description: string;
+ content: React.ReactNode;
+ }>;
+}
+
+export function FeaturesAlternating({
+ features,
+}: FeaturesAlternatingProps) {
+ const sectionRefs = useRef<(HTMLDivElement | null)[]>([]);
+
+ useEffect(() => {
+ sectionRefs.current.forEach((section, index) => {
+ if (!section) return;
+
+ const isEven = index % 2 === 0;
+ const cardElement = section.querySelector('.feature-card');
+ const contentElement = section.querySelector('.feature-content');
+
+ // Animate card sliding in from its side
+ if (cardElement) {
+ gsap.fromTo(
+ cardElement,
+ {
+ x: isEven ? -100 : 100,
+ opacity: 0,
+ },
+ {
+ x: 0,
+ opacity: 1,
+ duration: 0.8,
+ ease: "power3.out",
+ scrollTrigger: {
+ trigger: section,
+ start: "top 80%",
+ end: "top 50%",
+ toggleActions: "play none none reverse",
+ },
+ }
+ );
+ }
+
+ // Animate content sliding in from opposite side
+ if (contentElement) {
+ gsap.fromTo(
+ contentElement,
+ {
+ x: isEven ? 100 : -100,
+ opacity: 0,
+ },
+ {
+ x: 0,
+ opacity: 1,
+ duration: 0.8,
+ ease: "power3.out",
+ scrollTrigger: {
+ trigger: section,
+ start: "top 80%",
+ end: "top 50%",
+ toggleActions: "play none none reverse",
+ },
+ }
+ );
+ }
+ });
+
+ return () => {
+ ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
+ };
+ }, [features]);
+
+ return (
+
+ {features.map((feature, index) => {
+ const isEven = index % 2 === 0;
+
+ return (
+
{
+ sectionRefs.current[index] = el;
+ }}
+ className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-start"
+ >
+ {isEven ? (
+ <>
+ {/* Left: Text Content */}
+
+
+
+ {feature.title}
+
+
+ {feature.description}
+
+
+
+
+ {/* Right: Browser Component */}
+
+ {feature.content}
+
+ >
+ ) : (
+ <>
+ {/* Left: Browser Component */}
+
+ {feature.content}
+
+
+ {/* Right: Text Content */}
+
+
+
+ {feature.title}
+
+
+ {feature.description}
+
+
+
+ >
+ )}
+
+ );
+ })}
+
+ );
+}
+
diff --git a/components/landing-animated-tabs.tsx b/components/landing-animated-tabs.tsx
new file mode 100644
index 0000000..f9894ec
--- /dev/null
+++ b/components/landing-animated-tabs.tsx
@@ -0,0 +1,76 @@
+"use client"; // @NOTE: Add in case you are using Next.js
+
+import { useEffect, useRef } from "react";
+
+import { cn } from "@/utils/cn";
+
+type AnimatedTabsProps = {
+ tabs: Array;
+ activeTab: string;
+ onTabChange: (tab: string) => void;
+};
+
+export function AnimatedTabs({ tabs, activeTab, onTabChange }: AnimatedTabsProps) {
+
+ const containerRef = useRef(null);
+ const activeTabRef = useRef(null);
+
+ useEffect(() => {
+ const container = containerRef.current;
+
+ if (container && activeTab) {
+ const activeTabElement = activeTabRef.current;
+
+ if (activeTabElement) {
+ const { offsetLeft, offsetWidth } = activeTabElement;
+
+ const clipLeft = offsetLeft;
+ const clipRight = offsetLeft + offsetWidth;
+
+ container.style.clipPath = `inset(0 ${Number(100 - (clipRight / container.offsetWidth) * 100).toFixed()}% 0 ${Number((clipLeft / container.offsetWidth) * 100).toFixed()}% round 17px)`;
+ }
+ }
+ }, [activeTab]);
+
+ return (
+
+
+
+ {tabs.map((tab, index) => (
+
+ ))}
+
+
+
+ {tabs.map((tab, index) => {
+ const isActive = activeTab === tab;
+
+ return (
+
+ );
+ })}
+
+
+ );
+}
diff --git a/components/ui/button.tsx b/components/ui/button.tsx
index a138a30..21409a0 100644
--- a/components/ui/button.tsx
+++ b/components/ui/button.tsx
@@ -19,7 +19,6 @@ const buttonVariants = cva(
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
-
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
diff --git a/components/ui/sticky-scroll-reveal.tsx b/components/ui/sticky-scroll-reveal.tsx
new file mode 100644
index 0000000..1d99094
--- /dev/null
+++ b/components/ui/sticky-scroll-reveal.tsx
@@ -0,0 +1,97 @@
+"use client";
+import React, { useEffect, useRef, useState } from "react";
+import { useMotionValueEvent, useScroll } from "motion/react";
+import { motion } from "motion/react";
+import { cn } from "@/lib/utils";
+
+export const StickyScroll = ({
+ content,
+ contentClassName,
+ onActiveCardChange,
+ scrollContainerRef,
+}: {
+ content: {
+ title: string;
+ description: string;
+ content?: React.ReactNode | any;
+ }[];
+ contentClassName?: string;
+ onActiveCardChange?: (index: number) => void;
+ scrollContainerRef?: React.RefObject;
+}) => {
+ const [activeCard, setActiveCard] = React.useState(0);
+ const ref = scrollContainerRef || useRef(null);
+ const { scrollYProgress } = useScroll({
+ // uncomment line 22 and comment line 23 if you DONT want the overflow container and want to have it change on the entire page scroll
+ // target: ref
+ container: ref,
+ offset: ["start start", "end start"],
+ });
+ const cardLength = content.length;
+
+ useMotionValueEvent(scrollYProgress, "change", (latest) => {
+ // Calculate which card should be active based on scroll progress
+ // Divide scroll progress into equal segments for each card
+ const newActiveCard = Math.min(
+ cardLength - 1,
+ Math.floor(latest * cardLength)
+ );
+
+ if (newActiveCard !== activeCard) {
+ setActiveCard(newActiveCard);
+ if (onActiveCardChange) {
+ onActiveCardChange(newActiveCard);
+ }
+ }
+ });
+
+
+ return (
+
+
+
+ {content.map((item, index) => (
+
+
+
+ {item.title}
+
+
+ {item.description}
+
+
+
+ ))}
+
+
+
+
+ {content[activeCard].content ?? null}
+
+
+ );
+};
diff --git a/package.json b/package.json
index 616ed7f..7c571e6 100644
--- a/package.json
+++ b/package.json
@@ -79,6 +79,7 @@
"framer-motion": "^12.23.24",
"gsap": "^3.13.0",
"lucide-react": "^0.546.0",
+ "mini-svg-data-uri": "^1.4.4",
"motion": "^12.23.24",
"nanoid": "^5.1.6",
"next": "15.5.5",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 91f03c2..523ff62 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -179,6 +179,9 @@ importers:
lucide-react:
specifier: ^0.546.0
version: 0.546.0(react@19.1.0)
+ mini-svg-data-uri:
+ specifier: ^1.4.4
+ version: 1.4.4
motion:
specifier: ^12.23.24
version: 12.23.24(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@@ -2602,6 +2605,10 @@ packages:
min-document@2.19.0:
resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==}
+ mini-svg-data-uri@1.4.4:
+ resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
+ hasBin: true
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -5915,6 +5922,8 @@ snapshots:
dependencies:
dom-walk: 0.1.2
+ mini-svg-data-uri@1.4.4: {}
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.12
diff --git a/public/assets/arguschat.webp b/public/assets/arguschat.webp
new file mode 100644
index 0000000000000000000000000000000000000000..6625a307a288438fc99c8ac6abd1f68836f9a287
GIT binary patch
literal 55642
zcmb?>V{~QPwsmY*Y}>YN+qP}ns@S$&u`4z!skmZSoUiJz&VBd3_rBI%{$%dm_F8SO
zxyI;Y^xlV}gs7Zo;!f|_hZ2K_Zq%3
zzlEOqx8`@4$+4rV*|F`!ywP(L#zc}yd?|SEayYH*-F0VBY~DUH2U1
ze&uUX9#;t#wf5UsC)7Mjb3w!H)VSAi@dq4KU;2V9XI<`B)+w%MB
z7yeTI4DhD*YWK$XAZOvX@gV)i_a=Ad*GqRRcb)svv+!K=?(kmv>h~PCnd`JwX?CR_JuugAGGHBe0s!m7!}arbNC<-t_r;!fI%v}uAi`+XM3{By39#zPrGARr7F$A|<^z6+hp8Q)-s;r{gd!BxVrFe79LXBVf~P2%O=
z^4PVFj<546;EuLbgaa+fVB1Hee_5KVb&!)y12w`Xz9W%(IIksepdH&g-Zc_p!n7Im
zJiP%K%di!JNnms0i)+`fWeqBFM;0$js}rf5@OjPy`F@=@#OE{nPDBf_z&~M-`AoL@
zIstAN_xBt8F9#6KJmGt3w&Cw8jhOHe#1h|>e)z|43`auze{`}q_%78_VaN0-F*
z0EI(^5-vK;?W25KY!NLlxQrgOmET!jWOMkmu35
z`*ItVSzI7WSm19Yh)O8WGkVivg&p1Z?n?kAYXy)>h8V%Aa@O)HUJEwPT%X~;EKUi8
z|J)5p_|I_q4Fdi(fUK;>beS^pO!{^-Bzx9Qt$@^scFjGHoy)^B1Es2kZ4^xgK4d_%
zGj5bg1~IQM;WBGV+JtgYV+?qy8bO8b()E%Sac&O~00BtFaTl@3R^^F9p@2IUC&Xyj
zi=?lzd8?S7CeiF-v!ex!Z*2j}m|jinZb3e>OycfVxY$GN2xlxu%5|(3;Fpd41}1$N
z7{3D6ue)8^JRfBOS=y@N2<0FT+v+3r6$YHx@FC~1X=k>vw5yDiuvfPb;R&lno8*II{iFCd2jY{sYvM5~7E
zF75e{w}H+L`AZbB#gvF@{}m|zI6)T?n7~3|g7HlC$Zv1cW*#4()(BAI<5au=j
zVFaLb%lw`$(F`@F@cwri!T#aI;E9U(LlC;St>7ItFUeiXV=9Gt3aR1!Y(4(I=oz#F
zy;b?=ChRcQ4EqqyIr5}YevY^*Tk?A{d%GjliSLiKKnWuhTN%CPYb|XUUr5o^fKi2>
zAwGxh)KDEvu6DASo^EC~y4wEh@+=%A+*U{f2b7z@_>c0#7Nwg883PPqlR4c|$~*<<
zNfZzK_9>BmY!*}mU1!#Xc0gY=vL)6f=#hF*E$DDh$CEA-%$I>dkf^*hu%@{kqUARAxJ6%fFCt!!LRh36
znV?Adf3-ApJv3xNVEU`{wvRl9-M9Pv&j|i&p8>sOp5wW7rX=)T!HfKxGkJzSeEghs
z^P&6qqgO8)zE5SC>k{F>b>P1h)^;x@)l2JeeF=lmI8%t*VuZH4BW-cQ8K9~eGY`4m
zj}x~SUtHYtLxH)dr@na&aF
z&UojH>m#WCY!c_1Z!bg;+rU=yZ9(n0j^UrS^P;uN=T_=K#GI~O{fp;)G72^WDN6R6
z&(wA3c*x{0X=|aF7{duD49IL8fCRy7?TSYEB{!cJdD+6#Ic_s*L^$I;DbA`o9V^kDr{-7MY
z3FBJbNa&Rvryuuk{4pvM%8i_O_{>MD;R1!TCX0YV`01c!8fVnA{+
zMi&Ug1ctUgje-e7`_#Va4Hdod6&7LDw!~kTrs>F3y|oOwc7TWOH~=*83-4&_6i5gM
z0=jzEVBi9Bh}V_k>5-QZTbV*~c~$`!@Ezf2`rxRcr92?=ROzKEqi^X&cVqUKiFiY?
z-qfS?VBoyF{s4z+d)e|mX>Vc?5;%m3)N62GL*FPDn*8Yv7k%4lrC@M?0Q5&tIr+?-
zqS20S9h0uph8sm|EAKv=4)zpKi{bH1Yp7h6NjjF8eRpJPq>v?F8&5qhQVkQW9+St|y0NB?r_XB71gPG-=isOE
z@YO@)@j-gKCIY_lTAvu8MAAsLJ(PS&WbJ
z?kgh#TT%zRnmlg9-8B{bvL00n_d3#-iZut4892@{CFS+3?nNdug$GdUL14*vy)P_FM_J$3KYU&+JlCd>V;e
zl8B)RGreD&_w^nvCV___?3%F1)R0Uh{hjVD
zrdo322WV;kq0D73pYQ
z3@cZ)#PXv?#KXp@e(LaV#d*jyF>%&vl^z;@0QrAqNcN9mtYS>lblH*IEFOnv6fEC)
z^w#I!=hHtbDppFZ0oYTQ6>}u*6o(aZk=jKfaR0`%hQu6ak*RTUU(+iem@|Ehv2)`>
zknJkf3j|WqUsF=Ye3L6Rox`Q5t^GFrt)PemUhGX#
z*Ra1>bzu|s%VzsrlB72%?s8D=#MI)nUnh<|_Y(;KAhE
zDwsavjWhwjKqGYwWDU6huY&|?W7>w!#a7)k)vwU~jj=|n)dX!ULL2mC{S+W}Ksf{{
zWPE1>>{`{7*~?^Zy`_S_ucE&JurZYgCmI_kzbYF-+|xCHMqkceMZNZ^GlUch1+2Z~
zLtm8d7ve?ATXh#4qXZy_W|RU6q&duBlPd56a2nLu~5I@WF=7G)4c4xlbGo&UsU
z;t61O_z>uolahghI$)n*kF(_ub>7Pd|E#qknALj9WQmdAJ8Yv5m@mmJobfT7{G`mx
z2hxVbaaIomP8r{|;4;#Jo1E=L&FTfJOa7C-lzFl!K)@3Ery7LOqg7D%Cl~sw=>Jr!
z{;;Nzy@6gyHk=7^OXD>CoH4kbJ1hY_AMmUJ{pm&S)Uo0KA=d5n$mJ
zxUnes!QtRxbqNN?I00m5nA&^%@d3f3$ieHBt0oLwoIPegR3FFs-|p|XU7JyNB9@aW
zBs~`Vh7bhQuni#VTo0Y}H^@!5{p+pWV5uu-g{tGrPsg)FR23XijP
zsZB^bK+O`jU>AZXkGL3g9TUbcgacrgxC!M4Ad2%wHftBBP(QJ(WQdhAk
zDboPgty_pY$-{2MoAB6=woxQ??yB!ysBg#e_e+j(k|=L8QVrRa)2w~}4yF(-ATyQ6
zq6mCW0pYt0L@bCzTbLq^p{#dytVVkGY8=tlC6FvG%4v>A(5#!HXr(tE&v!tPfp~%D
zwAb}zq!07yJF9%$o%agZnL|?3HUYeC$1r!>@@grrr^JOJxpZ$HZCE-9TYh$Q%jfl^
zuY_(6sC%I9%b{In{N&RBvHJweDL&&M?NLlI)w!Bw^gFh#qC^_SsT^w&!Zae4=W+sS
zRQ>LbCMNBEN@ZWdOxjsYF%^LeP#Ic#m`Ziv6}9cLF#uwUSe4Avr~6As88*t(wRupT
zaj3phlQia+mNQU|_%(44FB_}0y^F()U@x4(NBS~E!PiO|VL1kiuuCol-tCV;;=}8g`eJ4hHot+T1!;haHx_8H0)3k-0+r?-QyL+^-X)pTvfeAeG!L|XXuVgdxHYF??1
z7$~^c@p3cIuh(wQNatDZ!@Y#ZX1oeHk3j7c5Qv63&5Z}kf;6s_TDG8B)!`(LZ({Z0
z@ZH@_K$UWad`vfTdw|Us;M46=Dm`h&Z))aBjcA+#4Q)v%VSP;gmYD!<6^Ci;
z7wck(TYyD-F;-KYf0zCTD~{yl=PCFYEfM}menP=N@N_*-Kn
zx7=;E*-EcY*zTFIsB^oXqzg?`Ul@0+MUN+V3Iiy;(m?sd2E^Gu#Z$otu_?iuO_Db}
zGm!N@rS^SA#Mp$%G{z9(0_+#ztmVr+RHkA~ofNmlU?SwN*>50M+Nd5~wWmB5CV@iU
zZX8NJ{FJFE&UyNjtWCQJgel2Lqpd9YtD+y*^JmlXTcO^np4H(xh=tBd;*&rS+
zuVUrj5@vPe@UNHtD94V-*6WT^pS(_Y%BPupaq#xh&<3$tlVggY#gw~L-MYSPM=syL
z8FooYmI>r1(J4Z&xt&-$HOw9tQ?qvLRedb(dfvDBmL$+5)O%_Qg`JfK
zV`lSl*H$Tf;O|=Vr)Ki^7O+5C{*-QhQr`$QaI#oW3IBt@9BK*~=#H>0m&E_ZJo)p`o#pa*a)-?yTlztqSRgd%fTtY(MfJqo-{a_Ft^X
z|3PsS)%d?*Fd5S0WT>wQ@g&PIM2Jz@R3qXz__|d|H&~>CPL06%Y5Gi2V6t?DSPLX6
zI%5NI$GS#ksX5{mx@NaLOxP~QKE&BF*pp$aW6or!oDjacg{ousO6Mn1>B
z3sKa$7%mdOUtDJRUIw|{mJF7~n+?fC9iTjq!I_yYR0$#2k+16sTiy4}wL*)BUC(%!
zT*j@hX7qMZ$2iTOqc4#Cr%z&c`nx0YTNjQ%XI%tYZi(-^Z
zRSq2AyXQkhJ!J&|A5?OEl|U#l_-For&`CfF5ZTm}m+>3uq_Z1bFkR14!SgzfRVrQ(F=%NeAriWelex
zjof>h)u7c5ak2iCa=@m4N;!rS*hvmRJt**N<7gc8cvKU^>CNGd3X_9BEmrGtsv+uM
zju|rTSGVckJA}V~i#AP<^@|wvAr6
ztSxx6faNs01PXWWZ`bd?(m2VLZRyX9iC4PF>QI1W_B^=8Gw=|9ct9Kx_aLZ6f?Z|c
zA`SdP(e#!iaO&aYK?|yJ|K6|o<6GSq8%DT1VEr4{?vFy~k2LM?
z3A)f9Vg08+`t#mMFEm7G*`93}ukJ{55Ukj04l2_g_Ao$bp|xNVnZXrr_`!L~iT}|s
z3xFLs0sf-3^!gBVueQVioo@@&s
z)BO4BP;%%2vfbbymya$4X#Oe*=v;{$yw_ir=v7!hIl+0;)7mp5%IyQ57wkzG*6d@+
zl@U11#KR%O6QMpBLKb-n)QxP#i_%EipZ#e@{$e2izJ%v6(=}6!jv?3Gy32o|!k%us
zs~-I^3AG>L9@drwZEh`8PCU8VXj?(%&~ME6`*g{WELkyNyYqyF4MOB0*tDTXT#$Jn
zk?^11?O#&aU$ZFS?puX+;VO`9J67g~>IVVc7)-d%fnP+ojzuR86Dgh5v)}+U7|*&8
zF^`Zz{VsW^f%%||PZ@QfH6hZ3aPo~&>t!74qT_Gfz^w?p%JL|2mTL1vnMYu4TlkH{PZRjmgV%~yfzgeziKr&G8Qlb?jzTc0Z*^AP+0fK0Sa&J_Ta&L=TQddsFumeZy0?hL!6!(y7}s8E
zr}S#G3RfN&NEb^}n%0n5iCq&IH?+Fewpb!&r&=yRD;sB4V(Grx|C?b#zrXm-xX|pcVm8^
zIzTb$CcQWP^;ubY6Y2NRcN21dRp~sFmja3)LpO4J^Z0Mp5-uaV!x!bZi+8YH-dQBm
z)FNp~QY~^y2EqZkoB$_DmOxCU;R(ZV>KsiTrW*4;df&_(Iv3+SY`vToYwFTLnLq(my^_V}0ixHie7nwwoZ9s99bIvg@~p%;i;`|FV6slirv(}-ueFVJeu
zKOq1*N$>8@(=GWU$z_6rZrDw3A%8^XDO8+6%yNF#>PPZXijdpv;ggyqLpJB-RBo_t
zrAkVYAwhUDzjP8dQpZ~z8Ryg+NVDQ|d)8~y>x~$%`KZ^N9&&me?XnL-Gd5!P>JOWm
zytnzaxSAGO@B#bX3usw6JvXNMVcn>ij8O{-MDHGmv@M8X)#;(zfgY@FWswaf$O<{&
zMy~o;YVS6ufcy$DX=%dAqDmU~w#ufC<-)D!TP#i8K*P)%cAO~(4ae0q@_oT_{ownJ
z2kzsoA`z%FivH)hs?9iQ(w>*kEi$@3wZ?)-f=U}$l(~cr$lEsiIZj1vvUS78?nP==k)
zpG9Z^;%+@ei39)Qq9rgPF`cBC3p2mVR3gcmG9cD67mXJmfztK-cVTT0+`*cRy=*wD5c
zG`mCHZk3MPHs|~z?^Ga^57e8m^nnBdO2%s?5VCWIH=&x=ie?8-izULkpyxNqov>JV
zTT-88EzjTZdrv%{@+&4Y!a^Th_`@YqNN^@Xu{qc|6sF|HA5mScP~miyD4dNTG!uGi
zjryP4>LnLW5N{ht$SEAMv?k{PU&6PDjD+P>+KO5ysUS5AmDZ>
z*l|H4y#L+BimI?gBnK5^f8V60$=mxJACtLcui1U_uJT}whD`EsDiG*
z$NC%(7J0Oxp3$DCiC(w)7a#ghN`65hU?Vpj1Je5AHaZ|e*h@UGxu2X$q(ZyOp%oI&
z0;%+30nE>}Wyrfjfb@$z(nPaI54a?>5FhZCLv=`zKBDdEI#y@+%fpME0k?T^!-&Ds
z4y2TM89Rry%1*gJsJ=9RG6i2kSJuEQZB(aX
zNfZs0JI99cx*E=J5+Sx+?Rg3}LVe`*^a}l2yPh4iJqU0r7tprcviUYgkA38i881q1
zXTtp$kZIY5vf{p$X)otaxhiut!f5KNJk{5JB2bV;L+Py={P-pEG{E;xCUWfbh=74>
zSu7R3WI)_13Q4vwfU@Aj0e`fQDgXcgo6SuV0KwZh?rcV-{*TZ9_yZ(;k4IkKku4!7?n4
z8=6iUUoY0{9vJ6KfUlkZ&Vz@6LjS#;wN-5xXAc^+wh8+uK?3t?05jVbJ#a68RkRzA
z8PhYhn+jF^XebBUV(%HSQ(yb0_VfU6Os#Y1BQ0doN%D9g5a@SM%7xsS}F`uIWk@$gWsO@@P>@r6i!u
zP+t!-&s8E`TB?o+Flwwl@r)F>uODmDcQ3$8>1$@!E;#Ka+W-JC9>A=Zh_M~%6&dtb
zk-kfZYkb@&i>VgSpW&`tLj+%)bny;+BzAT8ECmHLjkMT8^cQ|a=9pedaYhL+onOu-
zP4%Jnz|{ia^E*WW?5G-Qn2M!8x7%;#$IB1^$-pmfdUV14lB~76G&E$oAcxYAyy_>F
zxjL$kD_!Uo|^E0^n!B-j%56(l2=uJW3GMQ3Aw}AU(@2s{FN@}
zflDi*>1=w3wGXk&7i?G_5Av4MCNX!(oQl5vfHv4{W^fA!Pi~SLdo;cm6oYyc`rT1u
z1@t-;c~KY@j@sXz{e^Rc={x*MW*ZbM`LbDyx%1(ypP)?0e&tEW%U44%SY$1co4V+>
zOw4&d{}u;DCwReugO6~aM-Vu{#WE+QUn0XxDQDV_%vVtaDy^9h<9XDZ@kpN0?h9^C
zeQ?kcN!S=t!w`nZ7`k_5mPDDIFuurYh
z>HZl{%`IrqXkc44LcAr%+9JDY?v!Ke+=xc;;<7WYsrF%)&~81XeN}2ur>#7%bP8f%+ULR&0v$#w9dq@UDj`
zV&hEZTDL=`Xl8L)r{5fhMq6MrDZl_n*%YuK`>TB$8p-8UZSpWScQHQ$XhpGUPprAh
ziO=XUgqb$aH!Dfz-OD!A8MV>u5Zh(c9LiY?1anc)Qt*8XiwEJtwjFXF@C-H>rx9Q^
zB@db@JdKiZJmm(d8)zGNs90A#-96mBF)I`^9Mw>y1*k~oDe+N=jh!p+2xX4FjUoVs
zj;OSuJWF88=jpBo&-sCq4d&b+diEu6#PkpOfJYdTykl$DBGhn`y+}l+(77m$Tmt&_
z+G~t31+1dTgBxr4lBm206pmb~X%@UY?t7YqqhB&JZzaDe^10Jc@JphGr;ReVRynyA
zi|BNu-T`3jpyKGej$cs+MDx?ItK!GZ@taxGUFXhLU8od&FDJw<=MEt=vztKd*Bzx{TqsW_P@&J~`=%(kdjGsyFXo>aHH=66D*d%oeqm{DT~DqGlB)(h=9n*mb<@
z^``L6r|4BXXIt%|<<)d%m`^T4mC0IuJ|r6EK90?UowAl$;GPlhpVeqqzmTwxl|0fG
zJ3G4_qM{fhYs%J#r+sxS(Ur6anH73PFTi@9F(lkx6>u8qUC~73Q1mB&ByZd)_35g0
zQigu#83m)_O{P1YJXXtqMMrixGdT2RX9h?~lo8PP6F)DpPKhQ>nV-Y6&90&df}KQ3
zHW{-p$Lhj3Gx3xTJaKGD1_(e0X1Oj+C#m_KS&A4zp9XzNm*pAGG-iDUFs%^O;40y`
zNp)&rl*D>Y76^+c%20mEpM^K@&3du{4xtJ)n)Wy=TxxeWAEERb($hIujAQ(hNvlUt
z#DZ^s1HpV|o&}~pZ*t4lsKY|ej-bz7h#}f$p=8gVhg&iAo|rsn<*!l|du!MgiH)_r;y0-EH=|Jn})!ozPzIiYd83`zl_0NH-Q
zd*dORkN4fFKUx9nVI%4(Po4;u2lspugXHeD;#-R|JD~e#fGPpYr`KKj5hxTHEAosY
zaNNj;n#BecK}~-RmJf0iMN?QsD@(ANhGB!orws_2a5O|#7xRo9n74jZbB~hRYiLb-
zExeX#w-oPOdX;5dOr~cGyKno=aX~>P`}UWMCimtsi^f;z?ivMLs+N0u5I`H<0!T@?y+fA$=)u>XA%#+T1k%$gu1%O15C40KWT
z>3IH{6sncXWvKQMC^30HY3=Q0wC~p3H{A%(%H-9SkfEcsT1*XfT}#6?NN@CG^tiOyH9>2@$oa8XhyZS1>bbtb9#W@nn@
zlP==1Lx@3{+$j1q98>9Pzi1w#7WqJ0?ho^#1)+U2B
z*D);b3SHm>*3YKmARgLSC^K2*rrXc#n;8>p3t4XfcMbD&bf#-!ByE8TFWV+uA-
z*2bKD)EHsT?!-q%tTIpmd~H0rYL(YF2>C3!QC^0jpRN(%A~+@IBb3!KBdY}uGZGTB
zj?X_bm$Ckl(-v8GZD7maojrnr#P)M8zE4#S!Y+ArfT)?hwK&PhW@zj_yOfD?7ogR5
z&+2nFnH`BF7`2~RLfV7i&59hhTwbLa8~2Q|LXAbw5_u~1jnx>1g>hNop*!|;SY
zJ_wAIg!iDWCOx1YlsRfg#2zX`&|HQ!YQXG%hTpH!m?4?sy57SwN!eFug!IG>j
zl=*YBh<=)hMIaANIobf*Yn7^KG#mW}42fY)7Fax+e1HFhLc#te!LxNwHE&wERveg=
zvHPT8Zap$A;%Q$pIG=&IYc2$_3|4
zJZvVyP7a*FW`>1*wJV$L0O(wPg`!q`IReg#$D^`;VBfa|afB~6h;gWddt&DfC3{o#l>M+um%$bXe
zP+F{u^zz>t;L*hhD~VSus5r51tUx=TGR#%W>N!K%s{l5yGp-*aEFOr-Xhocwzj@ra
z3DXW+RvjVCuLoJdmS%bo`w4|J)EnI8c88N0SshR)RH{$3)zbuul6imAB`~6S5SZfM
zWlrlkJ^EtJ_p$`9tFTAy!Qkocp>_(AFg}^(e0xLe=v9-bC+H~R{Dpam8sSH!kauoeMS&k_FN||Hq
zW}u{SY8hwd_THPY4LNcTP}~mz!4^8oCgtr?x{iQ)^1s%H+%a>@duFCBB9W%G)xMcD
z)Fa*v#8~F$WRn4-el9JNeZnf`s)$d5Go=TcM}i!{S-S8PG7!pkRJL+;UD^o*!dOS(
zG=oo;)}J`?62*W;(2mYJQw!>iAVRxrNWiu!Ew~6(>dTfo3IQ!iGq{7rUL_jtL?PSp
zZI`=3UQ!j0M!xnnF8J`$Sx{LUmxw%7wTvj5;@+tNn?hUxz|RSXBEg>z9h_Vtkk+}}
zHvUQMoB35A)y((dLBER@^ctS7Xni*G(y=IS!u4pwcN4-`$oAmJiZ>z#hQPSo3EweE
z1A^QH{vuz=^tuD3aEwPsetn<)4l&jxNv|j3=pLL;A?rG%&~vvbzBj-c(n%JDs1
zI5x`#wC{dC`@G5Y_i0vB5tdOS5O%H_Q?=T~i3odMvf!etPfKc93A4HDcP)gWAm+YP=Cw*PwVaSB>
zO>WOBxg+SM-D@{{3_AG?r4hYQIp_@rZg(>VEjJ~AY7YfD#;A&q7t|WW54a6ONn-p_
z((ThSC6cZ&C3J5FhhxyR(7@X5Qk7jLu0RDy0Ww0n0P0d{iLO~;_4=V5lq)=`M`j%}bxTGM-FrAzMSH};>=1FXDuc|@2oDAXHBCD1
zw;=xXK3~!M3H;9CDl(~Ka;}NQl_e$`%kJ8hEpnSDbx}H*2{$Sm8eJmGOl)d07&Kup
zKa)6(TbM(S3BJ=bvgrFKY89ReS)Uf-1t!Q;Pi_;wvA6ui7N?He7JwPtnja-7-Fli-N&U_#{ILCF7^8Itp-=eGk&uC(6*62rCZlU_}_S
zQrX0+*$4GT4J15Cq8}&Cn<7y4y0;{ie1haZN)=3tG1$d#G!;9_7-8H(^_svDl-XCV
zKaWs(Ls+w$_+;kJMMGW!gjZ6(!v#z%MFHMAx
zshs0zcyg!;)S}ht=KmWU)iy21g%vzYY=~_SLZTJI0hnkh1fQTlnXH<Io3V)T4kz3_J}ezQo}OK?^oIv-L*GyN`N?qlB^K9tY&eiVk^hj0o&bNHeO(2TC0oYHuz}imdpxhfQbTas+03?33C?1M7tWJ>6
z#~9KpWK{sc?=deWnq*JpXp-XS%@NHZ4-#|)tvW2hF>z#q4s^Q~buu~v%FG{XwJ`=&
zTqg{=aJM_+7m$+uvfez440znHo6>p|;*pJYa5}quG*rVmy9xUAy%KLlB-6L96HBdh
zQxq2a_xVgl{ei(~7ulk(;ym>RHU~g&VNMp!I+r2VZ!Ty^sy)}-FtbZ%7}RTMVNM$I
z_#Pb{T?6FHI*
zazEU2f+-&t(MqPbnf058XfRNQIDD~OJJ1rt$e3N}BW2z=eXyD{hS|WO+BVY|L+!Fh
zu0P6yHT=wDr3QU-ap1JRZu1UL3pR3fz3W965j6A(0MPL*)f=|_l^1qpK?_4iUQDG^KD
zrB3IU*f18}T8S+3FgqHq8_)X!l8FXw>fU+>{nj!P`>6;gfR4q~br5Gr006iH(mo~7
zf5@aiJ^ckJs60
zAF3<~B`Z+@F#$%7l=X!8ATLCN1YfAQ9&5^))jl^Z2ydthFgy4;BE$i#EtAf=re^bd
zZkOSeU$K>J4`@?Li^jDX3X+_!+TLVy*uqwMY`J3ZzADwh8XWu9+zZ;<9H|e3q-PhE
z`_soqcY^D!we7B^z?PKHDIS_GMk<0@G(x#wS+lB0(g9u#`Vi(2Cnj%G?R|4ysntT$Q=KN_cf;LFZ6H_9|vdqB%fin)4MJ^SVi${6Wa36yRDqJBbiYIdXFF^(Zq
zE(ra7YFo?~XdGJymJ$~PiVDwg!B;svQ?otMTdqDq6$VQzhk3@?WkQJuSsFNO26WO*VSc$^d&XdF;vTT(rv
zQb5f@wP$NxO3E$5WO{hiEQ(0Kx-ZU!ZpPLd{A>>_CmIHo*>UAqGJ+%bJwdMe-D2jT
zB-A<-K2)zpy7x7m#o_XkmWmt*U(jY28M;FrbH_{-GAr1bas`YiZLWU=Zk{{a2OKH-
zbPC+fNpIS4cv6=3U
z%(!IhR3cA3r_l)?23!OfS!3H0z!h7(_ep3nmR_a%Je#LDkd-e*-*>K@vvOIY^T`JI
zO}mXg&l%ystV`w_ZMHOKHYq5|9ML%tQk8%U9a=B>M!p5N`@cNkbf@#6jy>ZA-qd*%Xx44rGuR*>_NTjeO>^H&n2>_ywVBotczls4DLH4h7qu{Gwt7OCpO&A
zLyR9iOirY!?E7K8dCuy_yT9A8>5<5Y|yjL#S0Ws9U@!m@g5QC>*<-51Uh|CDO7@L&a
z!5&6!{Evt~>%#Re0f4`#=)0~GJS@n|RX&!V+z;E~#PMMUqY6|+c---L`izpg$~@c=
z_PtQ2Nna@1bbNR|Ga;!icJ0$6YHMvfF0y
zG#!atv86-R&ZtEXqB`DI(|+Sg>e(ziNV*4J_enl4GKu=ceo>VJ9a{t(?Wy3Np-tkm
z9aj)CpHLDGBHF~mwIITQoMA}=ybx`D_yl!!y_e*6B;McJ#Mdbsu+4Qmg5PeRT}|s
z$}$lFvd7oRM02S+Lk5NAG41#h&dpp_LOK{6v|b1WM<|+~h-hP~E-dATh$|AXf+pwH
z|FJ~*81C;ngguAhswZJ7aUD{R^!!LK2PVQN9|_3r>#}gRaXzLJ#4-yQd$pL!w`ody
zQw4rdyJ0$h8arNcI_Kt6?wBgg&6;Rv
zr763P1C7{hx7TWulZkM;m8fM&S6}v98Opzl6IR;L&2D#T>v$w&h@KQveUxEBZ?A-e
z3h&_r-@UFF8MO$P4O2UJgO++e%Gb=RY42bC<~!K1`V%l+45U;L4{`ilT9IRkNAoIFi{yagfOPue0&o}0hok}B(Yycw9tUC-4od@t&q3ZDnOl2tUtw3mRvPCRaVNK@9Aif+9l7Y_(@3H{CMWg!l#i>|a
zvz%XgOxCP`){*=(DM}(~+2+gz3a=%WG*PX>nRl6SylZth!0CMGvvP@b-Co%J$cCzm
zd?*zug2|A(aD#*5*S?cN$st^|`G%BYKO7gIeeF%?MRnV?Ous=o*VHN}Ex2}LVG?__n!)M-ly0awv3`dk$d+!O2Sj|%M@8IdSD}q4
z95GQHw0;=lsbu&Rxo?p#jh{i@E+}R-&@8EWi
zfJz0`j;9MvQpV@_r|dG|(ALo;-MIRay}CpvdV@1GZd?RIj@}JuB
z#Uaz^0UN+d0=6#k5|w(VrNTrb3f)S<Be}v(=oZ}oVelc;I1HVc8ayqyBr3xxJCRXpetUq-py%W02!`RfHi?5f4#bTVk{Q#aPKO;
zwa2=2g@{-H01A&=wYxIm_pbuN>1@E#dF6iJCi)l2(HHM#01iTFm8!akY@c`&q*Fux#2Q
zXB!?l9quSwX-+lOVV1y*z+7^@0(|1F{sElX^!(f7y@#RGp~LK*}zqhj_NfG$~dZpLmYCux>oP|UN
z$hn{6g8LG_U`m0@WWl+*^Xz2dBGTSe*gI!
zI28l*`K$jKjjZUOTy}!7dXP!Y0!1#Aetm;4kj=xJo_E_@=4-k6@MsL(;eK7^$j5NG
z=Htm(#9D~*B)pt=7i#kZnc)RmQp&NzI+ww#`mb5hXNf=P1%+h#)`;jI2tbDPfB=l+
zL=H$|#Mqy*TwNM1nO+maAF+#;23u~IY~#j(uJ6za#Jjn*m#Q5zceFt!iLZ}!%fD<2
zByLo+AG7~Yrfp4Op=~ZPcnrl#nS1xT+Lq&2@wr%RAxQyWY{@_u1m#164K5~dFL8HzH32F4C7NL=
zx(o_yQF=&ul#&!k5?r_h$10Lv#d{xkHdYPXxUS>va-GBKYeaxmhLVk`+Ay)oilvV8}Br
zZ4Bxm_~I3kp6iag3PS02Q!wVJ!>F@MBgZMV+m;pE=F=mPr2d>=O|*0bn_AQ>Z~ZB)
zkZgldQ5YTz4te#Ww{BFOuqz}{}BzwysI&l9zfF?^`>+Yl~HQv
zUlRYm04$$L>{Oa{3bMb&OLy&9U$}9D_;jn6($6X-`TgE=*Z$>8U2#1cH75RXP`w$j+aE%*30+sYvUZAnXvC7Oeoe73
zE!gbI=4&PGTKO`IU0>w(FB}^8FHk~}IyYuE_2DMyK;TkD<4;w3(saKxp49o~2|#eH
z$b21@iC3K*n2Yqq?{yedLL7Xabcda_)X3Er7jxrrHO8J2H|*OZ+-;|(?b+i{lq;Xz
zE?j3wm*YHo7tK?8zpJH)tB~Zfr=P=Uy|h;9ZNDXs7$YcG^HAu1LcEC|;T}#+NU)Z3
zrtv8E2ynkQ;|re``t_vO*^uGOJKZ%z1^3Q)9{-6pUP2Gf)GGq{^@6Y}vL*7Lj@}H*@o6faDxL
zr=Z<)ETW+>jKAE=x5_`$hn@v}C?S(Tr^?L}e8L`I;%)Y8?Qmnk^5AJ*AF;)n!#DKu
z@CxEO)Z~Lf_eIlTidy$&CM*g>IotK#L)9BZTEp3UNLjr-GTl_n(2Cw`c3}nS&$oc;
z1Y*^sDg;|-2ijcwDK~9%vfnMF47xwV()vWK?fNT@WsF7zIAb<085YsFx51*J`fQka
z2Ncx9JnYd!VXBS7!G})h<7bf0yP6&GuH4nVSztk)+tTGiLECl5is)r{JOHf;)BAg~
zX&PjViw0tPA=XYhZo#{MT|E@!(LSGcjLYpK*Pky<7nDco0FKaT=W1cx8rzIZKoe>S
z2>PlQhEHf?^*(8|ES031LDhaJ-0MN(_2XF37gaKAKQU3o38;}HI*y1#o_4OCPUU=TmVu!r{aRIh+n-54oVTx$q
zJ?poR%khjT4ZI|M55g<<>^Xu)u$NVR6&wI*$brcu8oyohEs;V)6)wFM>%D2-DcaU$
z=VhcQV5!sz7$l(mk#Z|_Z^4F3bN;8jT}NUGO)ps4LG$*neT8Pj0ALcv=dvr8_OG}W
z&Zw`d=Av>w_pTOyU-32Qyhf8YQcA534a4E8rU#vCj{<(ygRHvhb!r`pQXhagf=ex=dU+t!E4lHvf8Z
z$d=aO2?AOD1X9)Y@2)S;%~+Ks{LG8ntkKWyF{M~Dc|`4W_DM_+kZ72+*MnxMm88Lo
zmh@Rb-Qj`^lsu7ZK3jv0A|iyQIPuts3GoxL
zn*J-DgnbLXEe~HCddEb&v=P%)n;SG}DW3Kxlpp}3+=?PiDR&i&J%o?qN7ny0dsK)1
z7L+lW%zD*+>5m_)rcHqCI)QuRmgui2>HVJwokbu93E4oHSH6~CkGc9GxdoC*+5mgj
z{@37<>mMo+WUyCb>1DryqGUQgCIK9T+?lZf0F~ZfbT{L73doh_DwblS^o;!g^;VMF
zDb^i%B5;TQYk0Z9r=Ky&w%x>YHr}3HiI3WRm}dNn28mGup#C$^$*_0XtRVK4TknYZ
zyR)a%wI9?QY>y{!av&njR61K
zQA~ZUg*Q*Xj{&h(1&EhrN{dt5*r0Czm!78Le|dKq|8D?LY8KX97vb!sx+a;7Uovr8
z51m!3^J-{W$uHc)as`J1YCIefXVdY?=W1UW4PE+m|GM2(4G}c1|4cg}z`CT+JXH+#
z;95VAdo~SU8dNvC|$+
z&splqy}_wqmiv>>rM-I_|iO_|ANpS0k-TT)WJ3KV@w0#1DKweVbY0ObhKWPR49-?
z(OxzI`KTrdUP*fc)7gA3VCdGsg1^h>q5es`s9(z+NWaBpxIR>2XlJW07oT$!d7g}u
zRC{&vvZ1&O;u(I{HS44*ZWKepydXMU;L25<@oNLavVuGc{A4oUd~>~pxyzQ&hqXz6
zSh-x+-S{buQTF%BA#1N~ZaFb!%V!Ab0u-eq4rS>(sRu&w_bEf$-d0lX$o?Sy#1_lp7>ZhLf4yUJm-u7PRQWzMl+{m?Y7uKBM#87?i)
zPc{Fy5x7I*~j(f}`Cqyal$Qg9}j>K+f$OH4a{g=2QllruqYlVHA&%VNPvpiZiQ6SYFR@hbB~)glq5@
zR0NkQzA)BJ=a|2?ETDrdQ_&x|BAOo(2(Cgkr#92u{D5mEjMvV}P96wR)*tZAQTi-D
zfxWrz3C144g&y=f8Uveec*?KfRUER5-p=eGxcKY7d50mYuT(#
z8!qb@$H1^Bt9kIbS+Harv5B9!G7EfXQ%Wpj#Pu_
zi-d8LE&{BZFxH5B
zsbNNlay%6iDGAV~u8Kp9zgI!Wj}A$RE0Q0Ki)b=mMu0Z2IQn>q1Zb;O&e6Lc)o1_U
zI6JE)IBq_|7&a}i~QJ*bNLhrq&`
z-w|~fi$mT4qw1ffp95i}uH!Y{jxS>(0>HPgnqCL!p<0A|;&{V)cL3n)dDnm-Ih)Bv
zxt^KzH5T?FH1lEjAy1PDF~enb?D
zxGyAdUw)Z3IG+FKs0wbDp}zCE_dW5<3XCMyI`+h)H8gtnZa<|^*ZclbfrkKdYvkj5OrGC=x
zE!XNKW%x(}Kdn!d&_3P6i2SP!6!D2|r8`cSH-FLyjxud7+&VG0Axh3G81Q)C~qvhXj+^Cs?52ks4c3>n3eH5QNS=9-!fvx}-TTV&_Uf9Cw
zz6KC#2>_RG%~MGSOwVs)cJpM7ov4IoBDsMY<^JrK;1|5l$E)%tfAcXrySG3?rbXQi
zd)ZB`0S5)n6-A`0@4pU<1b@i6CI%15>egj(a}`C~`P=ugpI?O((KDHeGM2CNy8qdA
zD(@n&(T$z)_aWW_hNzDD3tiA
zrXEaSlQvn_LZi
z(x1EVw`;4M`7eKR|0c#%lsx$#u+;(H>oX!EAYIZEj-3w~MxR<78$RHC1
z*RUWj{}qbWAn^U31#aq#@U_?{j<7vt%Fq_=_=MWUpKqKg>|e)f4TR+VQ~yL&BO^slz>mw_-+S?H;Ip~uu7`G`^|nd~CCYw_
zNs{X0PB2ZP%?3LTPwcpg5SQBJO4)N@mwczc?Ye%%$K;9E&?e#wN8{SfD<9N^URn#9
zUoM57&v!>!RGKDQ?xq)aJhWj($|XO0zOQpa1ANexX6m?(O;J$JOtd!~O-$jcr~_m_
z6`ZAI;t2s-;<4Z!zz0cg3C#tjga+<#UUP4|L*%oe6$$Rp{!QC@XX%3Ks*APh83kvI
zBch3&%vv1_1LsS|gP|8pZSiLY6jT|?Qbd2w)q$nNN_f^VqQ+wg12g~_Z0Ekw2awJI
zcBlUUhG$}B$0fvZ(!Vj3`7KkV`c}JQ0Ppg+^&L6Aeu9kR-C#u|RXKzKC2&ip>?Ua~
z5=l}{JGOKzt3&9fwR&+e#q2i1r{5KB?Uo7ZbI{{;d?()%$ou9*TNb~p5C9{e?vbSM
zqec|{EPpvuY88T-o#^h31DQydmsi1H1z
zd9&^>-_{p(ko`x}g0u9vt69)-%yoJ{ATjB|oto{9u?v>HdX4+O&^_zAL8)5r(=gb7
zS+3k$kxerSgb-J7z_xOZM3v(|NIJl%q85{1baxuqs_=CeW{vJ6cx7F;y4Ejas^(-&
zxl59EhjYl_Q_?ybZ3TLWOz@&cGkQ$Si#e%`rk&IK9of6%99e-?!~o%U(M5>PIS!_~
zUk|6ggbbgAbuV=iwlL&6Z*j^iijRXG{%nC9q@M7ow6OF&55wPm5W}!leQ$
z^~(FUA7QanLFtLD9HGh%ddk=x#z!Db?zY{SS_R4
zNrnsGvO(Dw>;=V^#OG;Yf^i&&kdj@k4?Pr<_7+2LpP2~TmNoEU*2;z
z7vsq-ksL^2@&N}HjhD*Q%vP<^hr~6-aNG=x`X}vYqDUwJd|b~Rg{h&Tib}LM7J*s?
z`0<^P>Plx3L4?EIiK;kB2I$z@FzIgNUiXtyA>_QWcqpzT&YqwJP$IF2#yL{jD!?h?
z#P=rgX(eRsa$F2o9367b!q-d?Ng7v#*`NRJoqJlv8={^c|K^@A4t6WK{H{7oEyyW_93M=zf%lH?|avRFvKn7eGOMckJ0zmT{~PFg8&IVm3SKRwnpUH
z4<}#Vn!ITW6z@^y^Tt*M(AkEY7bhUQa#Zm<52;61%yc>IRujbwg|Bq{w*u{z2=@oa
zDE>3n${qj;kMeg-qhFV_09qCeTB}aMWVmrBX5CL8Bfj@%9bi92_M+VTe6L)d&iP9xk8XvEl)!h@b;#qr!gre-1
zTjpU4OffKX8W2e}WqVU`W57P6wkVTJ*nLk=$LHsww$rNtj3U-slOW|4M9GgJ>VPTa
zRgI^gqqa%#PSG<;-e?HVCI&`>j{4UZSn{iCWN_<-moPdg&d8ZO1o1%*uuhOqTGHd#
z#0`UP64MikI03Wab08sz{O5yp$
z)bSKt$*8L)oSNHtHS|jMwnVLz0O&CiaZ#&lkna^kX(1Q8r@HpbWE1YK)|;qqx{jz<
z3WcIU)x&-|aQN;bvIb=$P5G6SI7<)KY_pc-jiEZ>^CGj}*1v||9^@V==U~qCY~*u;
z{+r}sUB$T_vrUZSdQ#4UX8y=vF(jcxv~*{%K}
z9Ay`Fk^llQVQkCp+pP9J8!$I}L#Dx;fV}DyF>VsyCs)pk#=5%m&?Xq^$xIENlm3_q
zMfDQbRcn)Zt^AGC>7;wWDGC93!;FeEYtI*`nn`FzNQ9G$(|Bl4JgM9IbzsNHKBD_%hm?ixwa^}KCXdZH-_yaPz;EOswDi6*J>0+*`uW~PZ
zD1eAW_OnHa00n`}a+r&NYouJcDM{
zHu9z(p&rG0$PgEOegyIcbsQU-`s!}CKuPvolIrRwmwS`&{f9+J3b$LAb~31
z-C&&jziXl|E-7VV7`HPijeZ`ta+{sKp$xFNhv!J0A#h8&tl&9iN^$J#B7H5$z-kc9
zmY%L2+S9Qv&5yNM=O~t)R*r|%Hx-%v6nwk$6OjOG45_KJA4^OO_qMbU^KvlS=0{G_
z1F=+{XhPn&50Pu1NRkTV=A23$24~4|mysVd@(k!F%})7i_YyG72TB@0eM((aOy;5s
zh%FMJ9i5}p{w*lvM7Y7Olk&A5I#}<_NaJG@J4isq&}}*&Bsfx*;x@Nf&@p}fQVn0tX?{@a^Y367$V2u)X;(~MnD#8
znx^*{vzF|G#wqR7-i?I}=JglqttJNAzeA{=_NRK&m5yZ_C9-R1sR~-L`$s5d=@V89
zDxX*}LRJUa)M@W7v5ZIQrvQ-3lIX#|`z0REgWT|-{
z{wXCBoZUJ`UoBA**;~sC*6DrxiDbcyyHBHZp)=iIEgp7e0K*+D@)IWXO%>
zPy*FKvN7Gd*HW0mY2F!{HDP~rAgQ{A8sKm_FlJQa&Q$jHP{s0`F=aSzY9lzw{l$bN
zOn2l2f98VzV%mPgp{s6uTzaveGCuIl%g-Z5h>TRgW+&b%K!ZK$>wFqiuiS&xelDgZ
zBrzugeZ0BUV|Q^1Jdy4f%t)A2yt0Xqxt8bk2tY0(Qsw+wc;${&93-s+MXiM@j9rb!
zZT#uB5#O5%hqgGnXBhzf-R$41^?zJy#85eJNuij!vc#W-+O3I7-#!Yyh7(}z$WbI%
zR;T#6K_?~t-!*j_^e!IB!jj3oBJ8tH%hu7M&kmnL_0d-pJ3rc~de7REmJcuTuS&G@
z{RNCm=BX8aN7Z=yK^y_{k*5BHwAh!&l$l>{-)#4az9b`sdoO3TJ_;IalNSXT@xtj*uw`1<~FjZlBHN!(~?XH2PD
z+0>uHl73^PhjRYh{w~KeaMgI{P8sxU7lZlH@%hQAii6LX_haSHWuZZcV~Td|?Xi2a
zyDgF|Ev?{4C9nNjH}B15O2~XqBF6}G>yGiCEe)IV9ehFygSy^0;o6_?3`~x>|0v>i
zM^6>eo*A{D>3>(Z&NM3Ffy~@;?8&{Q
z4b8{k+SWDif|ueh*)*lVU_6Z*@w5q%AchtT`JY&AnrW4TmIoks+?%-Sodv$**=a_J
z1jRHwXkl>ZHkpE&0t}_%20Ywp1<1fE4u*`q{pAmWU?T`?ilwmKlyI*qP7qXN9eRE{
z47n{(sVoY=tEF1fUgz(ss*$Ma;FB_>akin16RruVs(~Ka1g3L3N+{@@4(s@W?Rw&q_
z2~W{rOt5}UbTP>vr*+t)|J|W)ZtAf+4W<*WPatjECJSuR-3O`w@+$%v;nYZxJO+#$
zmS~w9d5!?aU~o_;E6t$53H0;>AppAD>C8t!z(HG8(-J}T@39H{h)_1%Kir(9IfBJc
z;?^0?%kJ3lmtwr0p~?lRHbkx5$u_6};4U5wmE<*Q5I)xL{0M|OiYRw2noWpB>}`s1
z8jmJ@Ie%MRcfErG6zl{P8xJv{{i}INoVn>k@Enoo6871$mWEgxa$bPcuAOHX+
zjuZd@XXT2lmQ8dgkVpPJJk13MJiBSKdRLN}2QhE@j2&wU!QB~WVQVv^NB^6fjhxo*
z)s~Oo>Kv%9*y>q_!GpVAEn}(UVY)Kax3qzE=_q!$UIQtJYgs5v5$G|9FtSVuiqjnc
z-o|Rk1Hu1qkI{$PnpB478^%+A6aa%0kP}!)Feb%lwmtJnG{odOE!LSz!%Iy*Ia`qf
zicdII#z|?JDPf(pKj}Zm?cN5#+ud9+To20UgQ9RXYK{s%uZ9*b(l9Ou85Om+jT4U~
zkBgzTyEe-N{$T7zLqtK%s)SvqitEE9r&-d;-QrmV7`8iq!0QVG78Zf;MihWCZ6(gI
zXvgNK1$3Z2h)wu^bu=cM4iv*lk~
zqcEbNMRHwm(ClpsjHvnPYK5pzz+c)xMy5_C7Ae!c5dW$0$H>yS^>2E{dO(*5K*rI~
z^0y>+{v3a2!GLHS*%d0g&Dw=4tSu)V#{wEY!``!#7FA~=i9b>XQmwbf4j;ZeYV3_n
zsT~5E1@Sa3wjvp^@^@C7I
zI<568ofcITDmBjGt}p)Zo_RjVJ}RKQFCO~GSGNu$C^OP$P}cqJbY9S^y1<)RJyF9<
zy_e5s3;iUvfmBHN$_O;3EvXvhYV}_Pv9Rk=!W|LtQFFe?meb*-dW!~3yrZ!Wr
z4hw&%Q;!R94lx!x%vgu9c=X#)b1ysY7rU|%_x02Fcm0c8(fcZIhn_&`xl%A(#UhA{
z*bM(MkQ+I>2vJK#*4D)d4`{gpSWilWSS&skh?Hf_?W{eB{j}Nu6~k6k?6RxB&gq!I
zwfLG9f2v?56k>VHIL6~2tQCd8Q{|&^!cjJlvq)+l;wL1_L>gQQK
zH!Ms{mW#r9kA;#y8v!4X%bO|Hon{Lpxta30IFM2|G9|A6k%kdj6`$R3l4Ml>K|fTn
zr7Kegp$fu7IQ-l!LQpsNspAA}U*$YmgW5#6wQJRPu2NBN)}zX6qg1vw3oziy%$Uts
znlHa9yxY=L)iTFD93b~5iqv-(_LiMV-I~M?uY&_1OpwrO-7vSkb;{CLXNBanzTBDJ
zD#RCIRxQfvq=lE&oV%OSZBFs+FDPrV(kc>_!?Die-aKtW6y!Aq=iS0H^a7LavAMrI
zzrI*$kDJHJWS%zsZY--T#q_js*9z-Ty6$s03%Jc5^CJWxHy=qj@3We68Q#_!36{k^
zWVII#k#v~7{g8~HV~|(t0)Obvz9sCFEP)@r45*$25B3F9r-w9HmlmdeHd(f-C*4FK
zErB=l0g8hDWTS=@Z|yIyMso}-wum24Sck2D12no4)iOn*gPZUjgo518a}wS2|?v5xhC7}zAHJRyr2D3p$i@ibbOsAQff
zdp+yij9LXl!wU%(lS0%%?7j<2GiMfL&2Ig=&M!ja3RyOpfmr*`hUg@LSyabpY_~Sa
z&=Xy`Vv@Y9q`YXw#dD(;BD5BeAuFPB!0B-NB~Y0RRn0t^
zIJXt^{SrS8O0lUvk^C&x;1joz$9I5mhss*_MT>->Xa?=HdNKPFKx<)k3^!gQw)^A@
zF;AYvxu<*>KmZZ94wF4}?qA_=I7D7ID7NFhxAiyxRgJzFdVB5`v>hpd~PTOtbWT!N6scmid~$Y`3WpS$EHy?
zI>txp00aCJgr|j$-V^i6{u3*tmI=F@i|wW~aqKhUQ5%0%0jV=2nIPgvQO=%e(5b~&aei^@XK*jS=11A)rP8Ft=`UPDYc1+q7H
zk!JG~WDhzO>=i^;qjC_yb2&i{&BSr)D~iXcm&L%Z|B>>G*3062P^GN)+4k>bFU32@
ze`l1C?K%=A3LYW1|E~F7qx|IsOaN)^4$#Vsp+}{9Y11R$HCXo2KLx9wfK!@VeBG0V
z-imEA`#kGP=$s00dL!^dV!nYm(^1IBr+lsWk=kIs^7K<&ZmZ<@#u3~fgS#_-i63eC
zu@)h+_JN)Fd(N6-tr`M{NT)D9<(6pg4rNpK%Jv?jBx<6`HA|Xb3%^kYIeZjQRV+gl
zLQg!0P{^FZtK4}Try(}RBKMzqKK10h6FE-;6C}-;e_m?fi8rwwdc1!MuUzwBCa@N+
z571AC62%35lzrdye?E;|YhAr1Ir!`+`Sk4NGMP0rgFoO2Z)Oz#E7T)Z-%
zy;Namh`qEH*)PtfFc-L7f>*oFyU6ChNDHPcSd|!gzOjlop@G-@2R+dj5@(0S$XARR1@9r
zs0?NLJulKg(2?1Rodb!~{CYZFc7SR^fR@e{`65_xYwsx2aa=_qozI1=6@w0W$%YGw
zt*P5fx9Qvtg+k#}crc~g({>8EzyJez;|c#GvW~26bOm&cXO_@YL$2lF8p_i%uMoZ}
z!H)?Y!HpBWjB_#Uj7>AP5!E-)jpwJ8kwZRAKC2KsJ}azeQG{EZs+M^F(pk3~5d~Jf
zxX%;i>*_HRQ?w;7Sd`7(_q1E8+7GV2Z0wo%7vjW!38RZH1*Otn^@^rsvyxY`r^PhN
zVg;g-)~tYuY|-PVK!g=CkutjZOXsPo4#7LIcpBJD?uPm2!fZ*#Po`ag$;CF1Sqr*k
zh_J0_>TC#B4Sy{VV7B+&6EM_txs}r-LN=A_)EPbsjAe$Pr-*W=wzb8K&vnu<@+w?r
zgG(FuL%P?8)y>Fus^GDHHOcf3s@q@1W$|-3Ufpab1fJGl))qY)#r{_B))wa$UQhd-
z!V$*W-#RT_l4iwic+yXu{3Yh&|Gr`|tn*hFY1)DaEo=;pUWMAV~!-=c?@`qT^Um;n{B{=N+YeMgvQ;Gkb7vo!1Fi@E
zCcK*H`Z_6i0P}2$XahuasXtDKH2D94IgoiVKb3JhDL%<@<7t-6(11AC(38@7OUz=1
zv=&YQCLA-Cr1&DQ;iS|)V#Xx*RdvBzj+k;|Sl+Xe`!7NL
zdOYNZp_OzrTE**+2^pFvb3FI(WNf=a*i`QpXW>GGvM(V#y0
ze6}smn!ZvLr%GS{dJad1|4#NeRjxuwfqZPf%6u?AhzWSzw5A7|QyWXlLSI0^y7{A)
z9P!2rHT<7N?)VTE1OmlPO}UN@prfaKL_fcor4X6}Fj}Es?z|Kq^N-Chb6FG!hTG1Z
zAK#Rv>bhSsju_t{Z-~&sosJ5l{0>J@J|yhiYq(y*N$4A;!_ekXAp+l;!Z(Ut9h@KC
z=hJ*;zV^q%O4&8+SdCDx6F{}4^AH}XAY8U)b)Ilw-xk#zUv*kwxncbQAx-mk-iPQ1?h4(`5gtIPBCEtq{~UYMgNRM;
zp3A8AX;Vp6vZMN%w8cK%Xo3_N?{e{2YmWLfYuK@z|dlIG?<>1Z+E
zxX1)p_gQfa1u#Oej^e{LXu7apaXsis+8hYuw~y;VqoCc7{GI8kB9GuWd5-94U=*hj
zs`vDEIhj1_ZoO6|Cpnn{jX+wK@h5FQ)o^m6z~zd??1{FMycsTl&OTrb2Vi4*MQA)+
zEhB8530b3yKB8EneXZJTnrm+#RKyHQ5j{?WWm3+waW3&wREvENhDeTpRWKpI8VzrVpJZdyO_d6
zJerdG38l{r{uz1?XanjR93F%5!E)QjtnI5iu@4s4pc}Vx1K!}$Z0qPX0=_wmKGGaJ}
z9uyWLTbi|dBQOZxnc+dO1nDwLGkvB$p@8fmpS+uaOPi-aE%a(LwfP9;M=JXjL+`(P
z$LNJA1iT2j*&<9YhgsfKfG(ml=+!R`UI>5mS_8SQQoOe`+Aw>rP+(K-17^}}zG#D<
z9k_-|3P5@rNf#zu0#oUM)g$*Y4B&Rikqpu_k}KUL3|j>Sz+P?FX$WkdT8M1CLOO#q
zb9h&(Bxa~9eUlHKlpJ3rv+oNMXmHj*eahs#3cHSb>DLoQ;S~*za!FlJ2+<>fqm1+(
zR(e!G_j*HHonYxt(k#&kNvK%Dghl8RrIY15ne9zu9IboJD=RhIC{+@Om7Kf8P~ZVQtN
zuL$8H_f*woIs~DAD~7;EGYbJGUKZ-lzHxv7rSrZhIP_0E3$$0
zy2_${8XAH1gPUf(ncw_2F;;oiTzsJf5^DzeUWAxYva;y$EmpEA}^YBvP`2hoCQufs>u3)w!l^6wp!2s(cy3lnjjds5$?b6;r81
z_0n7-CYa*%bgb*XK%A*qT*u#9uo7W@NJJ#|B;*^HWb}_Qu@Nu1UIo2XhhXww3vGsQ
zVHR!fh&K)M_}Q9%0unIx?flAIZQnj5Isqzg)$2B=^qz}bO=}*eaGI)AMcp`du=OyK
zJ#=prJpZ`Cpwd&5&sgX#b+K>NiD{130rbLaG^tDGsAMyMV=2$(|6oAB2mK=IoQxrf
zIUMk$*Z#J^7I`v;nUDj3;ie`;y0ZC|VdtJgTblF14V2#w+xpBvMKIFA)`?!FLP8-p
zIsS<_xmA(h%D=@XY^pHL{h24Z_`d?K)JsL6AUGBi_W3+;DdnQS1ss4iP||Q
zC8j7v{?hDYE5V^*IW5Y>B$=(rRs^%V>Lc|5-*}2(;X7^NU#Pz7Ove$Hn
zvHyQ*Vg^!uGw11s8p4e$#MLC;HESz&lRk&C3qO0WPnu}zH)b_1|1Z`lgJ+clrR1j2BBgx
zGE>qWkm^%P3wYl7o;x*ulB{KAmvbYW+%+Vzs!p{p+!QG{Y>dx7><0&v_$Lx!OKkja
z?@5ZN%y9vSrRABm``||hasmWZwR%?hVn-=i?CDwIW#*|Bh6{B}3fF@>(@^QpZ~p2%
zj?iG2O%UQZFca<`ATtqs)
z@`PcmBgQBUB;Fe^fDOEes#|d(rTXe?-yYM2$KxI!2Uk0?-bryylE&?IO&?y%~=W>vir3wOE%U}Nfc@qj^!Yfn!c
zHSX%P3J49_75LX!Cs^2@e3PN#VL1-mtxgjlP6n(Z(0t6fIQDjj^a8Mqf8MDPC3@3H
z;*EEf43Hnuvtmy9YRU4eW+!PgHg8WgomjRtkxd5N5Il%6E#vTgGgbZxeveeFft*fl
z1PoAwC67DUQ082)M_PEDtc?3X@x-cuM@r3maG+MfK}<7xvv7BL4#1
z?Ro~5dWjD-O9z)Rk9i5?%xxv%m?oAItz~qs-m!muFTDg12uw68+6WkQg;*vfW
zp)=Wm8Nia|s@94D`rfC+dTS?Y$0<~MBq5a?v_;c(cu
zmy3IQ1}-s%
zYin)Q2$B__MB)WRTQk{;h%o0}=_COEgb+w~FDi+=X=I@j|4_I11^3`avcUNR%sgi9gH+9c{>Uu1z_^PnZz!
zH9?7^2$dr?ze`yTcCHud!M&{S<>J11nJHeM5Lo?sFqOzV`p+M`wu4iFcp|@=a=VXJ
zg4{+Ld?9FoZUWt|fhJ(1u<=_w*?gqjF}(vAIga_fg}x0drvav`9>PobY)J<(g2IOGabexd!NFCt
zKH}YoeJVai^_b70cg+u2isS?_)q)p_OY<-0|4%I5=Q+M#J3V`I4XKug%%M(YR3hJ)V?~M
zyr-u_?}79jw!=Gb{^%os>O8Kcuue4@oX(t@9B237*dBEedDx5K;eE{Hp-1TDu>!{M
z%F~M=EFhZqV*SI^P}lHFDd1n!8e+{uA58e^J+F>I@`4O>aDekrGOJxjUH6`KBx
zTbVGhx(5I)8t#2*IU;1DU>2NlDYvBg84xt>gvJDT88{Wsk=DCY64tn?%xM|o*5x??q1~G=AsU54GT+}StZh9T
zPVnmZor1Rqg&iUiz)!8%6kv(2(w%78_LQgpVVG`WI%>h%2
z-D0?bS8t;X=1k!Iq+`ZKQlP`L>MN#)0JHBP&z7(5@%xde11EGM#bD|cJ^FfwH&nF2
zNk|9b`f^m#g0yDX9dcu$etHH4W$2+zj@n-G7dlK1otrh9a@3wZ^0pvVCh-PybTr6j
zL208%lz;U7?XXnr)oMnIX1{`?MTaxR&-a#P8UL{Y?I1mphc9RiX|=SjVa`COFhzmo
z*TUy$wuzfDcU&=i5MTUtRR*P;r+l;iZ|zAB+>(!oAoC>HFDQ4VUr$$i32+axHPn6x
z5Xhuv;h3~+=?RBrbY-AK)>cVr|c@f>7@bmL2zogO}Cy4xpI0`PMF#nrKZ!*H%CtonFS}9-Cdl{vau}XDTNe%)$SufK;3gQ=kt}6ODyMzvWoS
z3iXu^J2EdH2}XP{#@T}oGzQX$c2+eNTDs3YurUm;L|At`a1D)7Xex^do9(VAe__o7Z_CHdOVrY0RndPQg&
zzGA<`S?#KoTS|usK87*%l@y<}pGMVDa_TS}^lva(c6V}+GGBRaB+pF!%rRW^cR4ss
zng7GXcm5S#Jb0H`Lw6qcE@P=e)eM~Eh}Y2r!H(z)xesxa{L2fQOTM?lHG9iVaKahM
zH|m&t{PkU_?ArL}DTI6?__t0JE$V>x^6IGt80mp~mmvC)z1HNNo8HZ%>T}W*b9V9j
z$3Z41HzfG$W7Gs~+nHmL8uf67m}!@tBvuD8qX}K~f+c>$DR)R%0BjqS>9@z?h*$rsg{!u(NT`s&aYJvnp+MOXJ@bCIupVHw
z(kfpY^T~iy`{8|gs2@dtxrZ_zo-)JFNbJIItxb3jTe5`+qzwluC17Z0a=l&qM3jd%JMqH^Ekjqfz{N;zQFX
z6;JMv?K?;7c)s-Wjup+mxGvbJyK^HD(U{yOuy39D1CEid^3b$Y+Wh7!#HZ9Rtcw5_|y+z`VEfK2Tm
zniQRfya}saX%02Hme@^t55*O&EZWEKh;}d&XQ%)&PdyC5^V35M5A%=S(Ysu|Q^`Y>8G3txn#{Y#&axY6TMs@@*1A
zDWMwJPoVuc2_R8+I%XMF9n{^12@wX%6Z^aT2@8UT`W(k;rO|q
zI>wmbD^VXs{MV$pls@!U-(ZG`6Nf)oAN=K+kAEG?X0=2MSS1zbD?Q2}K3A2xc;tfX
zs66dpeT$4yyb(cLt8Xt()^f|7u>CqU&H(`Q7K~_+;-ODymtO~e{l
zC6R&ksl&WkzS{ovckD_mhKj{08SumwGZIprx&7=;K3i@6rgn6TFaJqcWfh&u05^)%
zZ`&CH8ntw4eO$91Gerq3k0d|A3^P7M7ZgneH?yVNXMz-fEdL7trMS5?J2q_APVc@<
z+`dAoL|mx0j^Z;sMg>Udw`~P>X#XtR^t6%yD$Rk|04bWw9mvx+iOoC9v@F_z-cfcO
z!_G#pFO|(ch|1kL8C0c`B*&+Hm8$L!)e#8G|0sTVinT@a_WpzAf+YAY|%z{gj#
zc$(JvJcQC=O~THcQjAg+($enJdR9ln~l6
zpfvLC2ZP8d{Yw@6WyU|n5ZZ#cBDDP*Nc(|^!f^c;XX>?3C-#%jmPY>;=SF(7i=_#m
z!ud{6nJ#!gUP-T_k#kpUge3t5ZG6JM%`mY7|FT#*eP3YJ=sZ9%qEE)-^C1kK>@)NJ
zzp7&N(30@08F~34i7f+!nZ5)~KMuaY>R*&&65Z=rR#L8$m{ojGS%}(ua`TJGah?al
z(iA|5Q0Cn!BMIt_37(}$9(>RTmqr}E6*XG4VF5I!yAS-H)>8TF&Faab;F1ZirP-n4
z${`_40p+r{i;o3LzzUN^_!)Dp4;H8Ym_YxHt03jIW=jdtc+l~FiQ`yh5NOxZ{z9SK
zitUVl)ajp?h{(*naHT7pe0=mdBW38;DEhT!^?xg|*(}Zdt;+)6k*N3$Mq6
zjHng~{hJGa{zO{!vHj-`?E@9tQiHNc$9^n)j}to!!pv2N@5;$&hdKcE!NLk#bC)6S
z_O5aR6u!+a0tA0U4oXFWv>e(mg+X#BZ=lQ6Ug3MORC?PwO{Q{)fTc(TF!erU)3cTaLrryPTi%qLWy
zkZLrU)E#zTR2TPPWNgtxp~~Pgr&Y#{2Fegpw)Nlk%|;GHr8`vnJ*YneU4}WaMlxkE
zti}cPxR_9jEjXU1G*}+t0
ze=M^TmqIuc%s>9zYa)~whK!bz)^$Df3#kA-N8O*31D~gST|?PJEspOBM-&NT!gwT9
zZX1SFDoOebA^)8`l~&hgMF|QQN8;`lqyAes-hxS-0e#IXjV_V`X<%E4<$u~Dk*^{p
zvs2yUde~IkD7CwxE$Ofelb!&CvL1|4Azs0_Tr~k8Xu&rNngp>rXBbp=M5)x+m`im~YxbY)j8)q>W;XB;
z!MKSwP373r3=t>&u%c@7Q*eR-=s*Ah0KnE#8PG@IcwsvG
zXAH{YsP)kl6JS+d;09V8*n|%ApdxW=zdQj3dEHaWzy=7`xO1F`7$ATEdw@4=Ik5hv
z89_nrgZ=-ZxBM&pb%fSVIs~Z=k;eb{WSOokPDV@a-7$z{ukCCSMIS7@G5M_ZCIq~1
zrL^%wbA*;}r=oApKpJ1gbCV-cv9OU5E+ZE9&;Ph&-J|_b@O~yYFW6e%^mp7ps9!gv
z!_2vSJr?v&l!+p4wuBvR6GTqCt_osN_I}aHYo`ptjtDljHFR#NNpMOn5EE)tshD4M
zS|h>%(U;W?FbqrB8@Nl2ANl%P3X@aWliuE|=LTPD{?mcEPGGFD6>XD&)XU*>1t*Aa
z|JrsPY0TEdvmIEh~$5S3l+fPWYDtmeRK%}&I69i!<
zw1Qv2l{UAg)unM}}?{dk(-R<%W~rXVb*vWDx{#RBOX~x#LzN
z1Rg@&_piwf$Y@;_dbs`N|EyIfben48^ELp=gAhQ>r)~fCN5Dr^b(uin_@-p<3-D}%
zsP|#MKf@`_|$GP?W~4)NeC@4!??|VuU&xVmXB6fL>0|H4kbY07vZE
z<^#}Gdefjs8zY40nPpE3V$^OeAub(B45k6SA7PvjwBfewKB$8`$T&Y%o9!-8AV_lL
zCCjcEV3L%RUrrS!@?k`};~)jr;~4U9Y!A|0{?*?GCoM20q!LVBTL#7{bL@m^_AU{~
zIOJZs`NF{AQoNjMh0dsv{pLY|f32OJj<7n1xTL4KWEj?`A`(MmhL?wGqX&-@F^-H+
z0$-_+{k%qtw?k@8s9w|Qi((f*$%uxvk(3p-%e%q<=o3HH+2JWoVcXIAnEU-?8guXy
zE97KdSqqK6X*@$Xrt9NTcCPO2y_{jQ06%R5YJo(QrKAf^{Ep}hiC{niWkr}vA^kg`
zVqq)#6u7U{(^c7JoWHz37%;879)GGp9r_;d1Ohl~Q}5LmF$~&3G;*@oD8ZcsTIc;Z5nn-24$y@-l|<91
z&OqaxzdmsGzzm*H8U^04hTvpVTqI`~`CWI3Z_wA0Sp^ZrQ5NW+?{-eiZ^7XxA=;
zSVGYeGOdL3<4yL@g4Z+CVxXezk#
zmxIqEss6d$B~V`$`}>m}iS5A!aVEm(u&2juE%v9as+gs3qXO@o_=%FfLbZiC&Yl$_
z2g$!<%k~Q6C>t>ql)BXCCqBchU9)=aRXg-;6
z9sLAk=^lsx2WNV-4Kj`HrPBO`{35EGz{`)f)43}A#kyu|h8Q7v-i_SeZFos?
zamxRgZF@u1Sq8cG+^hG4>?gDOJ>anq2(H``ppC{U0EV^01*1>VIBfe;p`lz+AxLeg
zc4)my=VEtf-7(>s1dt``AecY)fTGVG7PD)i+gbDLCC32h0Q=ZG^~gbpvd4nuRovcR
zo3x%cjCxI%(Xl!{&qa;lOww8gP0kAAyDEc0h9sNR<&_7?^+=0{4q$4-PsYO%hZ-pX
zoL%&>HT?1(6pCIJt4I1LP46*2ino=|Sm%eGb{wJA8t1gR5qP4(!YWSsU=l)kw3pj_Y->9{m+S#JLgIL}j#
zjv?)iFHl|)3Pu+X(&H3O^**~kilUwEL&NcktMLffbfY*gVJ3HeIsH|X7;%@#w6^jV#d0R4FKzFVWJS$ia)aS}OY%e_c
zKq3atCm6(gNEyMVXNs)O4+}M*n0+Ka^hy_YxS8V+PKk#~&4eIli3PY;ywFNt`WS|W
zI{h3UVs-0f#DdAr9SopK?y+A7;*NnJTn}7-V~!C&%sO)?v4Abt#>5=Zu!mlH@
zt|k6+s1_)lhi^fQr0U}ymZ=xK@de8>x-G6H3XR6Pm@ui|yITRff?)#ls;B8G=uA(O
zk6Izv;X2|wg;lTs&Gj`9B>V7YIKsfF#Bgrv$W7Y&P`AL=!^aacMwPLFxE(rCjh$Ja
zp>!|0D^lA&o;&SS(XE59R{#Y5kkS{hT|&SS86|Fg9;Q~)b+-BXY;UMwjt{S1h;|W5
z&e@{$sKq>lT!Q&xR*k71Z`}PK&1cB5wu~G57Kix*=Hk4by3ig
zPtf%CFfQ3#8g>I+U^?riN<9!uFSfqQ&AxMmKw*lew8OAeiyqVcxa+47uDeR_MA|QQ
zDEq{6!sdG#hJslQRAe~}JvnnhFn*@)fGBiQnC>ku}oy&KLvZjZLKQC=UCzc@r$!Z7d
z@d8W&LmOD{ZS!0%*iZu{-vOMXa7g+0M6T;+p5HuKfA@0(Ynx%f61SJ?K$8-s-QFK{
z4p0=Ix9;XavmjdHS@L}Zv-5z--|(n8ZxVAlwDVp3%Y{%C5nowr+b8Wyp|m4DAzpFP
ziMwSx$5%|w!pDnV04-W9I9MP8y#r9~@Z|_9`gu3(m8<`eCoAwW#epq6I=&?wj$3iMjqT
zXuIYqjzgN}#h2T*tH5l0k-ddBq&6u!)sDopKjcQ^mKvQX#R74VB9-@icd?u#gfQ(z
z;SL3+2hi>c+oImSmm2Yu`bTUS+{l@zTb|B%K|+Z?tD`R&YtVbHngBw)Iu^|uSYoC3Q*f$!vkbih~+w`;ghkCk*_^98xF*Wj|w5()&xXoY~pBX
z&4H7u!~h^BoB)m@X(Cqv&R)6JS5A{&>oe%d_wETnnkP#~3vmfnXAwrWrmTCD8<2Ji
zVTOmM8{2U!Dfs3M7iRcg6yj}TP52Zzkx~_7gyY$cy3h1E&pY(Us!aCSdv?O4b67;o
z_sGHh@DOH;e)LnmtL)6Qp>X99-ldvBC{704V&jsKx!rJ4iU_q828@#Tp@_nfl~#AX
z)c*k5>?ltNjISC%yr%H7qY^Xl-Lkq-@6;EtaY=`R?tf?$O;(&MvLg~gP`U6yjEe0u
zBmuy6IgbdW50eIY>gO?M7+NDEPp4bOpN|mlDj@}$5|ooANgDgQT3IzQFDvmpHAhX1
z@-LM6F;d1-3GhTOo--^M9eLR$7=ml^EF&cDg`tE03X4mBbLMJAzJD0>q??pBzd@Lqv$suW4MhKC6
zhk--dh^SJ8t3IoqjdM0ju_`S!4QM3}u_(gw~#
z5bRTk5ZOg(AoW@6J+Z=n3LS*!At(9Gp6|crB$oiCvO!nX_;68~{C3
z45t?wZz7YIw?_?VyaGh7=8qpS!`*@Hmuv;+SmL>Rvkl!q8IMHvpxhqZQ$Fj#CW+vl
zome~){3_Tnhv9?0BUeTt%ZUpGUaF9OeDHJ7Ex3>uGaybG+O9lhqhJdyLuJ`SP8nWq
zOUVR`<$3E0RqhH8&|)|1#SWF?k-Sv&om{s(akbx74kSE4>xS6g=G4^;Pba~=Os>Dj
zTf#NpqheuNi2>;0vwbJdH@*D64e+z?!<+g>=@dKQl!zye`CA4ZnWm|Zsr0NN{pkfr
z9sF`~RtL`H3k*W6z_t+?9Q?=jFD5H;Vkh=_IdhD?t^v`BF}!^Y8tT8iL+A)k(2bir
zCNrfYm%F>d%dY=yOA*ZEriVNoZhQ&iw#}-K96fH0o(+@hHUzJKsQ5)>~o`Vx=rz9GiwE*M$t^=B>2jNK_
zze*3jLHOi;A8r5uF#%Fn8N>LHAIdE_{d*mpDM73X->tIBZ%~mRUxiL%zolxLgXCU)
zC+y}zrU;-c>+AA@bm=F!e@X0hwcEot-xEO=MG6kTdT=kTK2CNafH?4L;Mc)m01a)p
zm8EG@ol=Pg*M>