From 19a608952a28f7f76b4b7ba3943579c799ccd641 Mon Sep 17 00:00:00 2001 From: Kobe Attias Date: Wed, 14 Oct 2026 20:48:50 -0400 Subject: [PATCH] Retire the notebook in favour of the workspace Eighth and last chunk of the dead-code plan. Drafting, editing and publishing live in the workspace now, so the notebook pages, the note and organization invite pages and everything only they reached go. Redirects: /notebook opens the workspace; /notebook?newGrant and ?newFunding open its new-RFP and new-proposal screens; /notebook// opens that document (/workspace?note=); the invite URLs land on the workspace too. Doors that pointed into the notebook now point into the workspace: editing a published work from its header menu, "Draft new" and "Continue with draft" in the apply-to-RFP modal, the expert finder's proposal draft, the registered-report moderation draft, the referral page's Create proposal button, and the landing footer's link (now "Workspace"). A proposal started from the apply modal no longer carries the chosen RFP in the URL; it is picked in the workspace masthead instead. Moderators keep their ChangeLog door: the Publish menu shows them a ChangeLog item that creates a DISCUSSION draft from the standard template and opens it in the workspace, where the publish flow already treats changelog notes as moderator-only. The published post's id still goes into CHANGELOG_POST_IDS by hand, as before. Dropped with the notebook, per the decisions on the plan: Word/Markdown document upload (its convert route, Tiptap import extension, JWT signing and the Tiptap env variables), organization switching and invites (notes keep belonging to the user's default organization; the organization service keeps only the listing the context reads), the legacy-note banner, and the notebook-only chat panel pieces. The publishing form the notebook's Details tab rendered goes too; the workspace's publish dialog only reads the help text, option lists and hooks from those files, which stay. KaTeX's stylesheet moves from the notebook layout to the root layout so math keeps rendering wherever a document shows. The Inter font package served no stylesheet that referenced it and is removed. The smoke specs that drive the notebook are left as they are for now. Co-Authored-By: Claude Fable 5.1 --- .env.example | 12 - .../components/ExpertResultCard.tsx | 28 +- app/layout.tsx | 2 + app/layouts/PublishMenu.tsx | 62 +- app/layouts/topbar/pageRoutes.tsx | 1 - app/note/join/[inviteKey]/page.tsx | 135 ---- app/notebook/NotebookClientLayout.tsx | 46 -- app/notebook/[orgSlug]/[noteId]/not-found.tsx | 14 - app/notebook/[orgSlug]/[noteId]/page.tsx | 15 - app/notebook/[orgSlug]/page.tsx | 147 ---- app/notebook/api/convert/route.ts | 36 - app/notebook/editor.css | 97 --- app/notebook/globals.css | 61 -- app/notebook/layout.tsx | 10 - app/notebook/opengraph-image.png | Bin 223324 -> 0 bytes app/notebook/page.tsx | 45 -- app/org/join/[token]/page.tsx | 148 ---- app/robots.ts | 3 - components/AIMode/start/ConciergeCard.tsx | 4 +- components/AgentChat/ActivityFeed.tsx | 15 +- components/AgentChat/ChatEmptyState.tsx | 51 -- components/AgentChat/ChatPresets.tsx | 141 ---- components/AgentChat/ChatSources.tsx | 69 -- components/AgentChat/CreditMeter.tsx | 67 -- .../components/BlockEditor/BlockEditor.tsx | 1 - components/Editor/lib/convert.ts | 243 ------- components/Editor/lib/data/grantTemplate.tsx | 301 -------- .../Editor/lib/data/proposalTemplate.tsx | 311 --------- components/Funding/DocumentUploadStep.tsx | 181 ----- .../Funding/OpenFundingOpportunityModal.tsx | 341 ---------- components/Funding/OpenProposalModal.tsx | 270 -------- components/Funding/fundingDraftOptions.tsx | 6 +- components/LegacyNoteBanner.tsx | 46 -- components/Notebook/AgentChatPanel.tsx | 644 ------------------ components/Notebook/LeftSidebar/NoteList.tsx | 78 --- .../Notebook/LeftSidebar/NoteListItem.tsx | 153 ----- components/Notebook/NoteCreationPopover.tsx | 27 - components/Notebook/NoteEditorLayout.tsx | 409 ----------- components/Notebook/NotePaperSkeleton.tsx | 10 - components/Notebook/NotePaperWrapper.tsx | 71 -- components/Notebook/NotebookHome.tsx | 149 ---- .../Notebook/NotebookPrimaryNavigation.tsx | 138 ---- components/Notebook/NotebookTabs.tsx | 92 --- components/Notebook/NotebookTour.tsx | 200 ------ components/Notebook/NotesMenu.tsx | 206 ------ .../Notebook/PublishingForm/PublishButton.tsx | 53 -- .../PublishingForm/PublishingFormProvider.tsx | 2 +- .../components/AuthorsSection.tsx | 31 - .../components/ContactsSection.tsx | 34 - .../components/EndDateSection.tsx | 41 -- .../components/FundingGoalField.tsx | 40 -- .../components/FundingOpportunityField.tsx | 93 --- .../components/FundingSection.tsx | 243 ------- .../GrantApplicationVisibilitySection.tsx | 24 - .../components/GrantDescriptionSection.tsx | 28 - .../components/GrantFundingAmountSection.tsx | 46 -- .../components/GrantOrganizationSection.tsx | 26 - .../PreregistrationPrivacySection.tsx | 56 -- .../components/PublishedStatusSection.tsx | 81 --- .../components/ResearchCoinSection.tsx | 36 - .../components/SectionHeader.tsx | 15 - .../PublishingForm/components/SectionProps.ts | 4 - .../components/WorkImageSection.tsx | 153 ----- components/Notebook/PublishingForm/index.tsx | 174 ----- .../PublishingForm/useCoverImageUpload.ts | 2 +- components/Notebook/mobileBarOffsets.ts | 29 - components/Referral/ReferralImpactSection.tsx | 3 +- components/changelog/useChangelogDrafting.ts | 45 ++ components/landing/LandingPageFooter.tsx | 6 +- components/modals/ApplyToGrantModal.tsx | 7 +- .../modals/OrganizationSettingsModal.tsx | 438 ------------ components/skeletons/NoteListSkeleton.tsx | 15 - .../skeletons/PublishingFormSkeleton.tsx | 39 -- components/ui/form/RadioGroup.tsx | 124 ---- .../work/WorkHeader/useWorkHeaderMenu.tsx | 9 +- contexts/FundingNotesContext.tsx | 4 +- contexts/NotebookContext.tsx | 266 -------- hooks/useAgentChatWidth.ts | 32 - hooks/useEditorIsEmpty.ts | 37 - hooks/useFeed.ts | 2 +- hooks/useNote.ts | 246 +------ hooks/useOrganization.ts | 252 ------- hooks/useOrganizationNotes.ts | 144 ---- hooks/useRegisteredReportModeration.ts | 3 +- next.config.js | 17 + package-lock.json | 153 +---- package.json | 4 - proxy.ts | 10 +- services/note.service.ts | 111 --- services/organization.service.ts | 235 +------ store/researchAI.ts | 2 +- types/note.ts | 51 -- types/organization.ts | 54 -- types/researchAI.ts | 8 - 94 files changed, 158 insertions(+), 8456 deletions(-) delete mode 100644 app/note/join/[inviteKey]/page.tsx delete mode 100644 app/notebook/NotebookClientLayout.tsx delete mode 100644 app/notebook/[orgSlug]/[noteId]/not-found.tsx delete mode 100644 app/notebook/[orgSlug]/[noteId]/page.tsx delete mode 100644 app/notebook/[orgSlug]/page.tsx delete mode 100644 app/notebook/api/convert/route.ts delete mode 100644 app/notebook/editor.css delete mode 100644 app/notebook/globals.css delete mode 100644 app/notebook/layout.tsx delete mode 100644 app/notebook/opengraph-image.png delete mode 100644 app/notebook/page.tsx delete mode 100644 app/org/join/[token]/page.tsx delete mode 100644 components/AgentChat/ChatEmptyState.tsx delete mode 100644 components/AgentChat/ChatPresets.tsx delete mode 100644 components/AgentChat/ChatSources.tsx delete mode 100644 components/AgentChat/CreditMeter.tsx delete mode 100644 components/Editor/lib/convert.ts delete mode 100644 components/Editor/lib/data/grantTemplate.tsx delete mode 100644 components/Editor/lib/data/proposalTemplate.tsx delete mode 100644 components/Funding/DocumentUploadStep.tsx delete mode 100644 components/Funding/OpenFundingOpportunityModal.tsx delete mode 100644 components/Funding/OpenProposalModal.tsx delete mode 100644 components/LegacyNoteBanner.tsx delete mode 100644 components/Notebook/AgentChatPanel.tsx delete mode 100644 components/Notebook/LeftSidebar/NoteList.tsx delete mode 100644 components/Notebook/LeftSidebar/NoteListItem.tsx delete mode 100644 components/Notebook/NoteCreationPopover.tsx delete mode 100644 components/Notebook/NoteEditorLayout.tsx delete mode 100644 components/Notebook/NotePaperSkeleton.tsx delete mode 100644 components/Notebook/NotePaperWrapper.tsx delete mode 100644 components/Notebook/NotebookHome.tsx delete mode 100644 components/Notebook/NotebookPrimaryNavigation.tsx delete mode 100644 components/Notebook/NotebookTabs.tsx delete mode 100644 components/Notebook/NotebookTour.tsx delete mode 100644 components/Notebook/NotesMenu.tsx delete mode 100644 components/Notebook/PublishingForm/PublishButton.tsx delete mode 100644 components/Notebook/PublishingForm/components/AuthorsSection.tsx delete mode 100644 components/Notebook/PublishingForm/components/ContactsSection.tsx delete mode 100644 components/Notebook/PublishingForm/components/FundingGoalField.tsx delete mode 100644 components/Notebook/PublishingForm/components/FundingOpportunityField.tsx delete mode 100644 components/Notebook/PublishingForm/components/FundingSection.tsx delete mode 100644 components/Notebook/PublishingForm/components/GrantDescriptionSection.tsx delete mode 100644 components/Notebook/PublishingForm/components/GrantFundingAmountSection.tsx delete mode 100644 components/Notebook/PublishingForm/components/GrantOrganizationSection.tsx delete mode 100644 components/Notebook/PublishingForm/components/PublishedStatusSection.tsx delete mode 100644 components/Notebook/PublishingForm/components/ResearchCoinSection.tsx delete mode 100644 components/Notebook/PublishingForm/components/SectionHeader.tsx delete mode 100644 components/Notebook/PublishingForm/components/SectionProps.ts delete mode 100644 components/Notebook/PublishingForm/components/WorkImageSection.tsx delete mode 100644 components/Notebook/mobileBarOffsets.ts create mode 100644 components/changelog/useChangelogDrafting.ts delete mode 100644 components/modals/OrganizationSettingsModal.tsx delete mode 100644 components/skeletons/NoteListSkeleton.tsx delete mode 100644 components/skeletons/PublishingFormSkeleton.tsx delete mode 100644 components/ui/form/RadioGroup.tsx delete mode 100644 contexts/NotebookContext.tsx delete mode 100644 hooks/useAgentChatWidth.ts delete mode 100644 hooks/useEditorIsEmpty.ts delete mode 100644 hooks/useOrganization.ts delete mode 100644 hooks/useOrganizationNotes.ts diff --git a/.env.example b/.env.example index 7b5d6ab87..849652d9f 100755 --- a/.env.example +++ b/.env.example @@ -1,15 +1,3 @@ -# Tiptap Cloud configuration -# Info: -# You need a paid plan to use the Convert feature. - -# Your Tiptap Cloud "App ID" - account-wide; the document import (Convert) uses it. -# See https://cloud.tiptap.dev/convert-settings (or any product settings page). -NEXT_PUBLIC_TIPTAP_APP_ID= - -# Your Tiptap Convert "JWT Secret", see here https://cloud.tiptap.dev/convert-settings -# Used by the legacy @tiptap-pro/extension-import for .docx imports in the notebook. -TIPTAP_CONVERT_SECRET= - # Google OAuth 2.0 Client ID and Secret # You can generate these from the Google Cloud Console # https://console.cloud.google.com/apis/credentials diff --git a/app/expert-finder/library/[searchId]/components/ExpertResultCard.tsx b/app/expert-finder/library/[searchId]/components/ExpertResultCard.tsx index dad2429c2..1e1d83424 100644 --- a/app/expert-finder/library/[searchId]/components/ExpertResultCard.tsx +++ b/app/expert-finder/library/[searchId]/components/ExpertResultCard.tsx @@ -14,7 +14,6 @@ import { Pencil, Sparkles, } from 'lucide-react'; -import { toast } from 'react-hot-toast'; import { Alert } from '@/components/ui/Alert'; import { Button } from '@/components/ui/Button'; import { Checkbox } from '@/components/ui/form/Checkbox'; @@ -33,9 +32,9 @@ import { proposalDraftStepProgress, } from '@/types/expertFinder'; import { useProposalDraft } from '@/hooks/useExpertFinder'; -import { NoteService } from '@/services/note.service'; import { ExpertFormModal } from './ExpertFormModal'; import { ExpertSourceLinkIcon } from './ExpertSourceLinkIcon'; +import { documentTarget, workspaceHref } from '@/components/AIMode/workspaceUrl'; interface ExpertResultCardProps { expert: ExpertResult; @@ -60,7 +59,6 @@ interface ProposalDraftSectionProps { draft: ProposalDraft | null; isStarting: boolean; startError: string | null; - isOpeningNote: boolean; onStart: () => void; onOpenNote: () => void; } @@ -69,7 +67,6 @@ function ProposalDraftSection({ draft, isStarting, startError, - isOpeningNote, onStart, onOpenNote, }: Readonly) { @@ -126,13 +123,8 @@ function ProposalDraftSection({ size="sm" className="w-full gap-2" onClick={onOpenNote} - disabled={isOpeningNote} > - {isOpeningNote ? ( - - ) : ( - - )} + Open proposal ); @@ -169,7 +161,6 @@ export function ExpertResultCard({ }: ExpertResultCardProps) { const router = useRouter(); const [editOpen, setEditOpen] = useState(false); - const [isOpeningNote, setIsOpeningNote] = useState(false); // Refresh the search detail once a draft settles so selection-based flows // (e.g. proposal invitation emails) see the latest draft state. @@ -186,17 +177,9 @@ export function ExpertResultCard({ if (expert.searchExpertId != null) void startDraft(expert.searchExpertId); }, [expert.searchExpertId, startDraft]); - const handleOpenNote = useCallback(async () => { + const handleOpenNote = useCallback(() => { if (draft?.noteId == null) return; - setIsOpeningNote(true); - try { - const note = await NoteService.getNote(String(draft.noteId)); - router.push(`/notebook/${note.organization.slug}/${draft.noteId}`); - } catch (e) { - toast.error(e instanceof Error ? e.message : 'Failed to open the proposal note'); - } finally { - setIsOpeningNote(false); - } + router.push(workspaceHref(documentTarget(draft.noteId))); }, [draft?.noteId, router]); const name = empty(expert.name); const canEditContact = expert.expertId != null && Boolean(onSuccess); @@ -445,9 +428,8 @@ export function ExpertResultCard({ draft={draft} isStarting={isStarting} startError={startError} - isOpeningNote={isOpeningNote} onStart={handleStartDraft} - onOpenNote={() => void handleOpenNote()} + onOpenNote={handleOpenNote} /> ) : null} {onGenerateEmail && ( diff --git a/app/layout.tsx b/app/layout.tsx index c8f920e9b..79aa40743 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,6 +1,8 @@ import localFont from 'next/font/local'; import './globals.css'; +// The editor renders math with KaTeX wherever a document shows. +import 'katex/dist/katex.min.css'; import { Metadata } from 'next'; import { getServerSession } from 'next-auth'; import { authOptions } from './api/auth/[...nextauth]/auth.config'; diff --git a/app/layouts/PublishMenu.tsx b/app/layouts/PublishMenu.tsx index 0df1585e1..c4c8762f0 100644 --- a/app/layouts/PublishMenu.tsx +++ b/app/layouts/PublishMenu.tsx @@ -1,7 +1,7 @@ 'use client'; -import { Plus } from 'lucide-react'; -import { BaseMenu } from '@/components/ui/form/BaseMenu'; +import { Plus, ScrollText } from 'lucide-react'; +import { BaseMenu, BaseMenuItem } from '@/components/ui/form/BaseMenu'; import { useAuthenticatedAction } from '@/contexts/AuthModalContext'; import { SwipeableDrawer } from '@/components/ui/SwipeableDrawer'; import { @@ -11,9 +11,19 @@ import { type FundingDraftOption, } from '@/components/Funding/fundingDraftOptions'; import { useFundingDrafting } from '@/components/Funding/useFundingDrafting'; +import { useChangelogDrafting } from '@/components/changelog/useChangelogDrafting'; +import { useUser } from '@/contexts/UserContext'; import { useScreenSize } from '@/hooks/useScreenSize'; import { useState } from 'react'; +/** Moderators also publish product updates; the entry drafts in the workspace too. */ +const CHANGELOG_OPTION = { + id: 'changelog', + title: 'ChangeLog', + description: 'Publish a ResearchHub product update', + icon: , +}; + interface PublishMenuProps { forceMinimize?: boolean; /** Runs once an item is picked, for a host that should then get out of the way. */ @@ -23,7 +33,7 @@ interface PublishMenuProps { /** * The sidebar's Publish button: a Request for Proposal or a Proposal, either * of which leads straight to a new draft in the workspace for that side of - * the money. + * the money, and for moderators a ChangeLog entry. */ export const PublishMenu: React.FC = ({ forceMinimize = false, @@ -31,6 +41,9 @@ export const PublishMenu: React.FC = ({ }) => { const { executeAuthenticatedAction } = useAuthenticatedAction(); const { startNew } = useFundingDrafting(); + const { startChangelog } = useChangelogDrafting(); + const { user } = useUser(); + const isModerator = !!user?.isModerator; const { smAndDown } = useScreenSize(); const [isMobileDrawerOpen, setIsMobileDrawerOpen] = useState(false); @@ -44,6 +57,16 @@ export const PublishMenu: React.FC = ({ onItemSelected?.(); }; + const handleChangelogClick = () => { + executeAuthenticatedAction(() => { + void startChangelog(); + }); + if (smAndDown) { + setIsMobileDrawerOpen(false); + } + onItemSelected?.(); + }; + // Regular trigger for standard mode const standardTrigger = ( ); - const menuContent = ; + const menuContent = ( +
+ + {isModerator && ( + + + + )} +
+ ); // Mobile drawer content + const mobileItems = [ + ...FUNDING_DRAFT_OPTIONS.map((item) => ({ + option: item, + onPick: () => handleMenuItemClick(item), + })), + ...(isModerator ? [{ option: CHANGELOG_OPTION, onPick: handleChangelogClick }] : []), + ]; const mobileDrawerContent = (
- {FUNDING_DRAFT_OPTIONS.map((item) => ( + {mobileItems.map(({ option, onPick }) => (
handleMenuItemClick(item)} + key={option.id} + onClick={onPick} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); - handleMenuItemClick(item); + onPick(); } }} className="group w-full px-3 py-3 cursor-pointer rounded-xl transition-colors duration-150 hover:bg-gray-100 active:bg-gray-100" role="button" tabIndex={0} - aria-label={`${item.title}: ${item.description}`} + aria-label={`${option.title}: ${option.description}`} > - +
))}
diff --git a/app/layouts/topbar/pageRoutes.tsx b/app/layouts/topbar/pageRoutes.tsx index 3a64d109c..d4381b197 100644 --- a/app/layouts/topbar/pageRoutes.tsx +++ b/app/layouts/topbar/pageRoutes.tsx @@ -19,7 +19,6 @@ export const ROOT_NAVIGATION_PATHS = new Set([ ...HOME_TAB_PATHS, '/peer-review', '/journal', - '/notebook', '/lists', '/settings', '/endowment', diff --git a/app/note/join/[inviteKey]/page.tsx b/app/note/join/[inviteKey]/page.tsx deleted file mode 100644 index 99c95f481..000000000 --- a/app/note/join/[inviteKey]/page.tsx +++ /dev/null @@ -1,135 +0,0 @@ -'use client'; - -import { useCallback, useEffect, useTransition } from 'react'; -import { useParams, useRouter } from 'next/navigation'; -import { useSession } from 'next-auth/react'; -import { Check, Loader2, LockKeyhole } from 'lucide-react'; -import { toast } from 'react-hot-toast'; - -import { PageLayout } from '@/app/layouts/PageLayout'; -import { Button } from '@/components/ui/Button'; -import { BlockEditorClientWrapper } from '@/components/Editor/components/BlockEditor/components/BlockEditorClientWrapper'; -import { NotePaperWrapper } from '@/components/Notebook/NotePaperWrapper'; -import { useAuthenticatedAction } from '@/contexts/AuthModalContext'; -import { useAcceptNoteInvite, useNoteInvite } from '@/hooks/useNote'; - -export default function JoinNotePage() { - const params = useParams(); - const router = useRouter(); - const { status } = useSession(); - const { executeAuthenticatedAction } = useAuthenticatedAction(); - const [{ invite, isLoading: isFetching, error }, fetchInvite] = useNoteInvite(); - const [{ isLoading: isAccepting }, acceptNoteInvite] = useAcceptNoteInvite(); - const [isPending, startTransition] = useTransition(); - - const inviteKey = params?.inviteKey as string; - const note = invite?.note; - - useEffect(() => { - if (!inviteKey) return; - - fetchInvite(inviteKey).catch(() => { - console.log('Failed to fetch invited note. The invitation may be invalid or expired.'); - }); - }, [fetchInvite, inviteKey]); - - const openEditableNote = useCallback(() => { - if (!note?.organization?.slug || !note?.id) return; - - startTransition(() => { - router.push(`/notebook/${note.organization.slug}/${note.id}`); - }); - }, [note?.id, note?.organization?.slug, router]); - - const handleAcceptInvite = useCallback(async () => { - if (!inviteKey || !note) return; - - try { - await acceptNoteInvite(inviteKey); - toast.success('Note invite accepted'); - openEditableNote(); - } catch (error) { - toast.error( - 'Unable to accept this invite. Make sure you are signed in with the invited email.' - ); - } - }, [acceptNoteInvite, inviteKey, note, openEditableNote]); - - const handleAuthThenAccept = () => { - executeAuthenticatedAction(handleAcceptInvite); - }; - - if (status === 'loading' || isFetching) { - return ( - -
- -

Loading note invitation...

-
-
- ); - } - - if (error || !note) { - return ( - -
-
- -
-

Invalid Invitation

-

- This invitation link is invalid or has expired. Please ask for a new note invitation. -

- -
-
- ); - } - - return ( -
- -
-
-
-

- Invitation to claim proposal -

-

{note.title}

-

- Accept the invite to claim and edit this proposal -

-
- - -
- - - - -
-
-
- ); -} diff --git a/app/notebook/NotebookClientLayout.tsx b/app/notebook/NotebookClientLayout.tsx deleted file mode 100644 index b2aebcda4..000000000 --- a/app/notebook/NotebookClientLayout.tsx +++ /dev/null @@ -1,46 +0,0 @@ -'use client'; - -import { ReactNode, useState } from 'react'; -import './globals.css'; -import 'cal-sans/index.css'; -import 'katex/dist/katex.min.css'; - -import '@fontsource/inter/100.css'; -import '@fontsource/inter/200.css'; -import '@fontsource/inter/300.css'; -import '@fontsource/inter/400.css'; -import '@fontsource/inter/500.css'; -import '@fontsource/inter/600.css'; -import '@fontsource/inter/700.css'; - -import { PageLayout } from '@/app/layouts/PageLayout'; -import { NotebookProvider } from '@/contexts/NotebookContext'; -import { NoteEditorLayout } from '@/components/Notebook/NoteEditorLayout'; - -function NotebookContent({ children }: Readonly<{ children: ReactNode }>) { - // The docked assistant already reserves its own gutter inside the page - // container, so keeping the container capped would centre the document in - // what's left and leave a wide dead band on either side. Release the cap for - // as long as the panel is docked. - const [isAgentChatDocked, setIsAgentChatDocked] = useState(false); - - // The shared layout's sidebar and TopBar are opaque white and the scroll - // area is transparent, so wrapping in a gray surface turns just the content - // canvas gray — no change needed to the shared PageLayout. - return ( -
- - - {children} - -
- ); -} - -export default function NotebookClientLayout({ children }: Readonly<{ children: ReactNode }>) { - return ( - - {children} - - ); -} diff --git a/app/notebook/[orgSlug]/[noteId]/not-found.tsx b/app/notebook/[orgSlug]/[noteId]/not-found.tsx deleted file mode 100644 index fcc31ef8a..000000000 --- a/app/notebook/[orgSlug]/[noteId]/not-found.tsx +++ /dev/null @@ -1,14 +0,0 @@ -'use client'; - -export default function NoteNotFound() { - return ( -
-
-

Note Not Found

-

- The note you're looking for doesn't exist or you don't have permission to view it. -

-
-
- ); -} diff --git a/app/notebook/[orgSlug]/[noteId]/page.tsx b/app/notebook/[orgSlug]/[noteId]/page.tsx deleted file mode 100644 index f29c56221..000000000 --- a/app/notebook/[orgSlug]/[noteId]/page.tsx +++ /dev/null @@ -1,15 +0,0 @@ -'use client'; - -// This page intentionally renders nothing. The actual note editor is -// rendered by `app/notebook/[orgSlug]/layout.tsx`, which mounts the -// editor based on the URL. This file exists so that the route resolves -// when a user navigates to /notebook//. -// -// The funding-timeline modal used to render here when the org page -// auto-created a proposal and forwarded `?newFunding=true` to the new -// note's URL. That flow now lives on the org page itself -// (`app/notebook/[orgSlug]/page.tsx`) where the modal can drive the -// note creation, rather than appearing after the note already exists. -export default function NotePage() { - return null; -} diff --git a/app/notebook/[orgSlug]/page.tsx b/app/notebook/[orgSlug]/page.tsx deleted file mode 100644 index cdae9f313..000000000 --- a/app/notebook/[orgSlug]/page.tsx +++ /dev/null @@ -1,147 +0,0 @@ -'use client'; - -import { useOrganizationContext } from '@/contexts/OrganizationContext'; -import { useNotebookContext } from '@/contexts/NotebookContext'; -import { useEffect, useState } from 'react'; -import { useSearchParams, useRouter } from 'next/navigation'; -import proposalTemplate from '@/components/Editor/lib/data/proposalTemplate'; -import { initialContent } from '@/components/Editor/lib/data/initialContent'; -import grantTemplate from '@/components/Editor/lib/data/grantTemplate'; -import { getDocumentTitle } from '@/components/Editor/lib/utils/documentTitle'; -import { createFundingDraft } from '@/components/Funding/createFundingDraft'; -import { NoteCreationPopover } from '@/components/Notebook/NoteCreationPopover'; -import { useUser } from '@/contexts/UserContext'; -import type { ID } from '@/types/root'; - -// An empty document for the "Start blank" funding-opportunity path. The -// notebook editor's schema is 'heading block+', so the document must open with -// a heading (the title) followed by at least one block. -const BLANK_DOCUMENT = { - type: 'doc', - content: [{ type: 'heading', attrs: { textAlign: 'left', level: 1 } }, { type: 'paragraph' }], -} as typeof grantTemplate; - -export default function OrganizationPage() { - const router = useRouter(); - const searchParams = useSearchParams(); - - const { selectedOrg, isLoading: isLoadingOrg } = useOrganizationContext(); - const { refreshNotes } = useNotebookContext(); - const { user, isLoading: isLoadingUser } = useUser(); - const isModerator = !!user?.isModerator; - - const [isCreatingNote, setIsCreatingNote] = useState(false); - - const isNewFunding = searchParams.get('newFunding') === 'true'; - const isNewChangelog = searchParams.get('newChangelog') === 'true'; - const isNewGrant = searchParams.get('newGrant') === 'true'; - const grantSource = searchParams.get('grantSource'); - const proposalSource = searchParams.get('proposalSource'); - const selectedGrantId = searchParams.get('selectedGrantId') ?? undefined; - - const createNoteWithContent = async ( - orgSlug: string, - { - template, - queryParam, - queryValue, - documentType, - selectedGrantId, - }: { - template: typeof proposalTemplate | typeof grantTemplate | typeof initialContent; - queryParam?: string; - queryValue?: string; - documentType: string; - selectedGrantId?: Exclude; - } - ) => { - setIsCreatingNote(true); - try { - const newNote = await createFundingDraft({ - orgSlug, - title: getDocumentTitle(template) || 'Untitled', - documentType, - grouping: 'WORKSPACE', - selectedGrantId, - template, - }); - - const queryString = queryParam && queryValue ? `?${queryParam}=${queryValue}` : ''; - refreshNotes(); - router.replace(`/notebook/${orgSlug}/${newNote.id}${queryString}`); - } catch (err) { - console.error('Failed to create note:', err); - } finally { - setIsCreatingNote(false); - } - }; - - useEffect(() => { - if (!selectedOrg || isLoadingUser) return; - - if (isNewChangelog) { - if (!isModerator) { - router.replace(`/notebook/${selectedOrg.slug}`); - return; - } - - createNoteWithContent(selectedOrg.slug, { - template: initialContent, - queryParam: 'newChangelog', - queryValue: 'true', - documentType: 'DISCUSSION', - }); - } else if (isNewFunding) { - // "Upload a document" is handled inline in OpenProposalModal; here we - // only create from template/blank. - if (proposalSource === 'blank') { - createNoteWithContent(selectedOrg.slug, { - template: BLANK_DOCUMENT, - documentType: 'PREREGISTRATION', - selectedGrantId, - }); - } else { - handleStartFromTemplate(selectedGrantId); - } - } else if (isNewGrant) { - // "Upload a document" is handled inline in OpenFundingOpportunityModal; - // here we only create from template/blank. - createNoteWithContent(selectedOrg.slug, { - template: grantSource === 'blank' ? BLANK_DOCUMENT : grantTemplate, - queryParam: 'newGrant', - queryValue: 'true', - documentType: 'GRANT', - }); - } - }, [ - selectedOrg, - isLoadingUser, - isModerator, - isNewChangelog, - isNewFunding, - isNewGrant, - grantSource, - proposalSource, - selectedGrantId, - ]); // eslint-disable-line react-hooks/exhaustive-deps - - const handleStartFromTemplate = async (selectedGrantId?: Exclude) => { - if (!selectedOrg) return; - await createNoteWithContent(selectedOrg.slug, { - template: proposalTemplate, - queryParam: 'template', - queryValue: 'preregistration', - documentType: 'PREREGISTRATION', - selectedGrantId, - }); - }; - - // NoteEditorLayout (rendered as a sibling in the layout) already shows the - // appropriate UI (NotebookHome here), so rendering the document skeleton here - // just produces a redundant outline flash before the org resolves. - if (isLoadingOrg) { - return null; - } - - return ; -} diff --git a/app/notebook/api/convert/route.ts b/app/notebook/api/convert/route.ts deleted file mode 100644 index 74facb1d9..000000000 --- a/app/notebook/api/convert/route.ts +++ /dev/null @@ -1,36 +0,0 @@ -import jsonwebtoken from 'jsonwebtoken'; -import { getServerSession } from 'next-auth/next'; -import { authOptions } from '@/app/api/auth/[...nextauth]/auth.config'; - -const JWT_SECRET = process.env?.TIPTAP_CONVERT_SECRET; - -// Tokens expire after 15 minutes. Long enough to cover any reasonable docx -// upload (Tiptap's Convert service is synchronous and usually returns in -// 2-10s), short enough that a leaked token has a narrow useful window. -const JWT_EXPIRES_IN = '15m'; - -export async function POST(): Promise { - if (!JWT_SECRET) { - return new Response( - JSON.stringify({ - error: 'No convert token provided, please set TIPTAP_CONVERT_SECRET in your environment', - }), - { status: 403 } - ); - } - - // The route is already gated by next-auth middleware (matcher - // `/notebook/api/:path*`), so an anonymous request can't reach here. We - // still pull the session to bind the JWT to a specific user via the `sub` - // claim, which gives us audit attribution if Tiptap usage ever spikes. - const session = await getServerSession(authOptions); - if (!session?.userId) { - return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401 }); - } - - const jwt = jsonwebtoken.sign({ sub: session.userId }, JWT_SECRET, { - expiresIn: JWT_EXPIRES_IN, - }); - - return new Response(JSON.stringify({ token: jwt })); -} diff --git a/app/notebook/editor.css b/app/notebook/editor.css deleted file mode 100644 index de6c4ff45..000000000 --- a/app/notebook/editor.css +++ /dev/null @@ -1,97 +0,0 @@ -.ProseMirror { - .is-empty::before { - @apply text-neutral-500 dark:text-neutral-400; - } - - & > *:first-child, - [data-type='column'] > * { - @apply first:mt-0 last:mb-0; - } - - & > * + * { - margin-top: 0.75em; - } - - .node-imageUpload { - @apply rounded border-2 border-dotted border-black border-opacity-10 p-2 dark:border-neutral-500; - transition: border 160ms cubic-bezier(0.45, 0.05, 0.55, 0.95); - - &:hover { - @apply border-opacity-30; - } - - &:has(.is-active), - &.has-focus { - @apply border-opacity-40; - } - } - - [data-type='columns'] { - &.has-focus [data-type='column'], - &:hover [data-type='column'] { - @apply border-neutral-300 dark:border-neutral-700; - } - - [data-type='column'].has-focus { - @apply border-neutral-400 dark:border-neutral-600; - } - } - - [data-type='column'] { - @apply rounded border-2 border-dotted border-transparent p-1; - transition: border 160ms cubic-bezier(0.45, 0.05, 0.55, 0.95); - - &:hover { - @apply border-neutral-100 dark:border-neutral-900; - } - - &:has(.is-active), - &.has-focus { - @apply border-neutral-100 dark:border-neutral-900; - } - } - - .node-imageBlock { - & img { - @apply border-2 border-transparent rounded-lg overflow-hidden; - } - - &:hover img { - @apply border-2 border-neutral-100 dark:border-neutral-900; - } - - &:has(.is-active) img, - &.has-focus img { - @apply border-2 border-neutral-800 dark:border-neutral-200; - } - } - - .node-aiWriter, - .node-aiImage, - .node-tableOfContentsNode { - &.has-focus [data-node-view-wrapper] > * { - @apply shadow-[0_0_0_2px] shadow-black/30 dark:shadow-white/30 transition-all rounded-lg; - } - } - - .ProseMirror-gapcursor + .node-imageBlock, - .ProseMirror-gapcursor + .node-imageUpload, - .ProseMirror-gapcursor + [data-type='blockquoteFigure'] { - @apply outline-neutral-700 hover:outline-neutral-600 dark:outline-neutral-300 dark:hover:outline-neutral-400; - } - - [data-type='blockquoteFigure'] > div { - @apply border-l-4 border-l-neutral-700 py-2 px-4 bg-opacity-80 rounded-lg rounded-tl-none rounded-bl-none; - @apply dark:border-l-neutral-300; - } - - [data-type='blockquoteFigure'] > blockquote { - @apply text-lg text-black; - @apply dark:text-white; - } - - [data-type='blockquoteFigure'] figcaption { - @apply text-sm text-neutral-500 mt-4 transition-all overflow-hidden; - @apply dark:text-neutral-400; - } -} diff --git a/app/notebook/globals.css b/app/notebook/globals.css deleted file mode 100644 index f5ce7cc1d..000000000 --- a/app/notebook/globals.css +++ /dev/null @@ -1,61 +0,0 @@ -@import './editor.css'; - -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - body { - @apply bg-white text-neutral-900 dark:text-white dark:bg-black; - @apply antialiased; - - font-size: 16px; - } -} - -html, -body { - @apply bg-white text-neutral-900 dark:bg-black dark:text-white; -} - -input::placeholder, -textarea::placeholder { - @apply text-black/50 dark:text-white/40; -} - -input::-webkit-input-placeholder, -textarea::-webkit-input-placeholder { - @apply text-black/50 dark:text-white/40; -} - -input::-moz-placeholder, -textarea::-moz-placeholder { - @apply text-black/40 dark:text-white/40; -} - -.react-colorful { - width: 100% !important; -} - -[data-reference-hidden] { - opacity: 0; - pointer-events: none; -} - -::-webkit-scrollbar { - @apply w-1 h-1 bg-neutral-500/20; -} - -::-webkit-scrollbar-thumb { - @apply bg-neutral-500/50 rounded-full; -} - -input[type='range'] { - @apply h-2.5 bg-neutral-200 border-0 rounded appearance-none active:bg-neutral-300 transition-all; - @apply dark:bg-neutral-700 dark:active:bg-neutral-600; - - &::-webkit-slider-thumb { - @apply appearance-none w-3 h-5 bg-neutral-800 rounded-full active:bg-neutral-900 active:w-4 active:h-6 transition-all; - @apply dark:bg-neutral-100 dark:active:bg-white; - } -} diff --git a/app/notebook/layout.tsx b/app/notebook/layout.tsx deleted file mode 100644 index 33a179f10..000000000 --- a/app/notebook/layout.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { Metadata } from 'next'; -import NotebookClientLayout from './NotebookClientLayout'; - -export const metadata: Metadata = { - title: 'Notebook', -}; - -export default function NotebookLayout({ children }: Readonly<{ children: React.ReactNode }>) { - return {children}; -} diff --git a/app/notebook/opengraph-image.png b/app/notebook/opengraph-image.png deleted file mode 100644 index 4a3c4d3a3bc88efee2b709756a27e07423d8c9a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 223324 zcmV)4K+3;~P)Px#32;bRa{vGf6951U69E94oEQKA0yj`hR7L;)|NZ{{ z_51w!{rwyq9RK|L8yOiM9v%%14gdcB{`vR*|NrXu_~LhMq}1i``TB*;)#UZ|*pG<( z^zq$;dW+84lG5GOnwH-5^w_DU&hPKzd~)4=a(m6h`ta+k*XWwm;qBSg_vz)_ih*9& zy{qBl+On_Em5kA$o}%C20001h&Cu7Dkc8UOX4}KniGF>~%X;6=fyckupqz2t$&TCD zkmJ{y-re52xS!AAv*qT4)6k04)_ujLhQOer=H8CFo7aMMc+I@U>g&l#zY0s|EsHTO;$(h5%<$`(9udbQp+P#;7N%k*2|=;kLu6LtEGy8#kKPA@b>ohwd>`_uC8>}z?HR@t*@xP?dbI4+{KW7 zkjK!azrfSFxR1K1%Zz)xu&!m(#M#Bfi^R9OtE8E`qQWih9Yjf7Qp~-`=sNnVhhZ)%5Yjnv0g%+MK_)zMzwxv7Ef# z?VY!+bk4G)#LLIFw~)oDr>vd4x4N{Qh0uj|)zHtfwX?pYoUz5p#p3R~z{9b+Oin!Hmw#&F1j!>FKPmmEV?*yt{)ZM$! z)2bx?h|(;uBK0vcGO9m5-s5$~=f@`v+U$=X#^rp}C!?yWy5jY2G&HcnxHi|_Xz7_p zw;d09%8;#dkH_jTXk)w1-Sb#@HPaJAw&NV{aUN;#3)#%P9x=i=_BhI`zVAmr(vu%! z?{Um~-}k-`air}S=^u=AC3H+{wYW!txYwT+yQVl;fd_^dUX zp(m72Z}n`@)$q;0b);9*<>`2KMedG%ejG38_jnOtfmctCf61%*qF0$-ZHZR3z-j|5 zzO1XJN!Su#DYWoQz)wVeF0|oak^Y!~Dk0Wm1+2OU@rkzUgMY5{%H3VpJrb}MkSgBq zZUL_dP%}Mw8N&=h%?uM^RG5Q+3Jc?DCQ>nSdVci0gX29u!Z6~u2ssR;9(?KnslZI) zcbG=}4iF~r0xNcB zudX0faZ6xebw({d3D@G3l*np?Sl1n}Dx6aaCNBhhuMC zy)v#&iS?brszqEK1y;H=3s}htmv&X$o6B3b{VuY;vR_r36xIWfGIa$&3BH(Ek1Veo z11kbmcN12;j`u(?noU~Spf>`^Do-qfiXuV83ToyT%q*+~N-DT?5p?xl7SCb|ECZ#y z>;P6^nOBtswML%^US*bQEfH8)g(R@jSmIrAl>`=zRbGN%YpJ(3GD~p^MrHFUmJW${_wt1IJGC6~un8q0`vhOEyY0PFGw*6TCt z;~xX7*405>DYB|Pu1aB*Zp+tAQE2z|qB_w+5WgwB0F6@b`=h(fSuGL6hGDg}EMWL*07CgHgr$$~0EA1qGqig=JZosg;IHTZWah=gJ$dkXJl-g*^dQC%js-u4+wawOSW; zZ6a1%5(}#8n$MXjWILNCp&Jv^N~*fRR-J%VolC5OT9<#qtIP4w`*;1K{*{pFC%ihT z32TMct|C16SB(*?lG93Z|-3IjGx3>qOO8s}+XKCN{aGNQAm_MlGujg;>I?7FL$r z6V^>#2xw_(o&}bQEIxtQT2Xl2+<~f+Uwe&JnNjeKpLMCNGW-r$C&YRK>&1cf@uVXB z0k1^1AH~(Fz-o+F2~`Krz0LJtS0L+QPWz)Xaiyn!1@&d21R9fDo znPQ8@mKpEr$H$O}752cQ4M{4|T1+9q7UKw-OUx{%-WDFFvr<)+@u$eDOJqse(3}gb zYr3mT0-R+c!4|TgFw_iFd`kax0+aL}IP(kC7@R8MqFV!f>8dWC^JRQ4m?^7WT7vS0b^% zsy+y`AiHLIF$@Et2784k)fH@eqSlj0Loo=(u|*SqEj6Ia;E$R)NvZUvQD z$|%k`NPvsC>SK)wSva6w!w};JSsMp_F>X0^;8*7qUhCra?ZPCrtZ7IO^|Xr4tmU!V z)D1brvQlBV3udXGRULbVg~&1ozWOSZrIlfJw6?tZJYsC4#@@g17cB`t&yRkY5*21$ zwt0rrL_?$4Dr><*Wb}HqwtCkVQ3l~vr)dUBh_bNy3uuY1Dw3k=udBS8C3;1x>{>}4 zlnFH=iq-SBAD5YB)u0ipejr>CpO8Zsh&8;|8=Htc%r5$LFR$exoRT^c=n5l~YSaZ{ zi$0T@g(|cH1B(m7B?jpqO7pPvvV>UTx9>;UEzFBs>|uSwlT22@uaqB6QPK{`>QXGL zwXj1{S&cJAsuuhE0*ks*?F$JkD#L$f!@q&`dJ^lj96SeBL8|9P z;nr~1i#EZkIu%!K(pO^nb`J}<6TCR#j(n(C?W?p0|F|u$B*!o-t`KRD$cc`@SzC|` zLO)Bg%G=7L2iT8{D25EWgu{S0kxv)~4wLrYD#A(R79AexV;=HqDyl_h787d#lLj;o zC+IclC{ALwZ(<*VrX=Z}E(jySxshxN_OL3I=IJc`o> zVOax>5DnQ28z=dEBZb^=cG}8d_6eG(ih%66R3-;9{dTO`U0&hA&kzM= zUZW0#CAjetdnh`FHewVno>(MRVuluH93%-JH!_P$MM$Z5kXTN6wXQOE$6AI-Xth!h zwnaosMg9^A?u5| zI%=B!sxLnbW}S!M-#_#h0@il&^EZE*fi9h2>R>%@5$=iA?ENe4h%2hDWnOeMxh*9| z)xdHOYY+b6YEadcOmhlBe%)c$T^VMl0DH{;%7}6SQ=^2M5*SpIE$se76V9i zmWZs7+J&o>gKs4S6P?s)aaA4@C~g0W|Q#q2fWHN2QT$$0!uB_A}QEx3&N{qc2W|nJxs`H zb8B6B)snzk#c9{+&XN)>{*Dax=50C1X4WV8v&wDh}Sx!rVOZ~;!Y;rEU0E>wdP1eV7~7*CTFiJrxk8Sem+bPl~{;uTyWYc6J& zNvxQ{S^5g_vf<2pH?5WD?yO5{9%|CTv9Y!8e5?$t^?&SLJCfp95FAj9)kF~T2>CK} z07(%zGI|La?dk+_bOtU!=p60ME%#N{=hc(cz?#DX4M?JAou!kktgNiqCX9Iwhv*|U zQ&yh39FDPLn6wM+M-8R>{kAXbj=v$>{r*A7`q|$62CSDwESr7)cuK(f{o};*q9EMw zeY5BoKg%m~yW*90slIF=hh_-Du%sp==}IcX!W1mFhYC(jCbtKqn&JpfDKv|&GfJTf zgyD*thLs5Euq;$m=b;v?0&i-GT2UQHrC>!QYQQm`!&?EjdK84DP|-gOkcDdkVI8mz zB_+;7r5FxJ6p6sAg{H;YJBmR@x2U?u-eKw{)efS^Ep=zzV1~a6$GR;Y4thcGN~Cu` zVi@=oP3;&R7HYhV%+ls>3R~KDF|UI)3Zn)7nPDAkP(NX6cmvieD(;JLnTJt*yPZXU zc*t_?>9iV50{dK+l1Hq3Q4q4+PJbmatFPdy@FoQ7+jRzI=oxS|T`uNk7}a$(UUXhC zJdK}I0IZ2stO~6_bOX;weL>d`sukp{_6)dT32Pv*>Ht?2VG+F&ToF_;;|d%~C>0ff zEfn~!A0THbPPLtA@vLK^E`*@v@T&8T!x01v;5G5nG)5P^GiojTq|>5jSlG}Zh?cYp zotkxus09uFX7h!K>phMasuu6$ckh8;2=MaV#pt#8R@)~NhWj7O!lZAw+ugOfzX9u2 z8-%}flJMgRxXS!g&MIScJ@}l4UzuyiRfGE3&tt@i@GGxieHEvZ&JB_n!|tn9mW*Q7 zGVY223mofmA*1MJBw?!T5N35Q#cc(4buQJ;-nKAhfle_bb0;`ARMGT#M?Nk z2K(if#NzK4U9g(|`4u`XOphQ{xv#jGJC*3r)x3Vtb8?N`Ek zVpWbaVaww1r&{q1Sg)jBJ?XznXL1s}ijC=YAaYs_9#;ts_GO(r%c7wbIj?Y+p&a_5 zhq)Pwh*(j(qKfd-XC8}B^fHRhUZPWof>4rV2&#xv^#WE^CoskDb*;a3To1OaU@>R` zuRx)Ow$n>E=?J5!I1G=G(2Aw7L5!pTEFLNBM4azT%o=?c5y)lpI#JJJNlPJ1@|0ua zFgi*LbCMEX!MSy_xU8iuOKL+Got4KJ3%I{ z?N-?{yIr<>cyk};_uu==7_gqTUqyoTgJpD|QvGE;sEDN>Y2#Ni{$U|<>KFYI(Bi(} zO`YxES_5i-&_;1&Zjjr87{&o$l|rt1ywWfZD#3FFzZH4dMYn2s{D$=_!Xw714h11M z{-9ZbSj_{#ihgFMSpzs%B}9wB3V=1>yb6#Na0|ZzrQKSG%CUMW3>{oq$B+kjH0duM zMNjE<8k3?>nH3UJn_r z%wLU$`x^OCkm_|oLF;HFjc~PyM6GW*PlqiPkJcb7i6jq|L_k>tg-=h#L z0a#UJR1nuY*4!P<3jC>U+GY-%siD*GTg?zT7?CTI;lqW2e|bQkkcz?qENftMmRhq^ z*y`0+I{IV>7T+z=!Nhm4tE(#&g<(ku%_60=&`{-@B+o44luyZl3v)1^oXi}O2)`k{ zA1zFoyTU8X^7;P9H92vDJYHxBwlGagHSB03a8j0gyLT61Wte+iexy0W}zJH%hLRygCyH4kN+RVCBi=tlpP{0hLBWEJ-Duq+JNi5_%=^el%ccCI>TTZBVU~HVkhT@TW7< zKHrbEtb9XzKWavrs*Jcg>`d;_$dGd;`{t;nlDIToL{pft4*I8e;kt*M=HI z;_xa#tla8B^|ya%LFi(TKiSk^lg<}GtWQ~wBh$?n^@%E41w2C7amglzQp};Q7^LUE z6c!~7!KwtI!nI~*riJH#R6RY{a4`@z5njzr6G}c%E#MWgDpZ66^D6?bL4_@_E!E!X zHhA13%N9FJtvc*CEDxi;suNyjcCH)K(KlNURusB+r{L0XZ6-Z=qr<}GklR+Ule1I*C@yq5{$ca0*9t-896!YJe5L*>wT62(NI3$rhlBD!@UoYXDFQ z!@}FtLyVAR#;i`Jb$DuL0auf&4B6groyO615M2a33s$0K-7JWv;3S8u<-lLp&McSi z=VJa2ZZlX6QD&6NmyuZqn{L=|c;7byv$FfE3|&sh-OBK-VZE&6{_&&(Yl~p%=gJ56 zB`KpChO7cs?)Oc2C6~XwRc*J~K|1=jg78c2460eh=AbdFG2#^!f)_Lf&z9WYv$q|C zf{aU5S*gh0wxtZ$;4ureB4`SP3J)AN^jZ@t)lEPyLan+1wE{>DK&*gX;fG->yw#%^ z#K{2J9i7B*Om7fkMOzk2@>Bo8a*($SdHSsJAO9SB|x!Rf@)bT;xKB)6J(cJ!N=5~dvn16MS zp$wGY4%HoPK^h!{jRABED!PDGB~tk;EkSMz&NwHis#~DZ5I~D?sUxIn0bNZ!H_Wq! z@Ja|2eyy3QT14%~y+u;Bh*Bxj0w#(0-m(3m^F+(J99V{*Ca-GA?BV1KLrEu<8c{SX zv%VJ+sC;uv4GY$_q67Z6>40aVm7h$0xBXyw(l*qjzlHhzaM%{I+#17;ft`Ch!Ln?( zzHcDbdxOp^z?IBAi(hm(-0<<^K6+V_v)h~?TvmkZm8nOKk~yRu!ZbEc8-(y+{eivx z8$qKwLm1r*m(OUvI?Lm7P5_G`i>pC|G4P->Ws5?>VqVp?3$qon7%G9VM(kD%6^3;H zE-o4yqE_LVib6RVs4%RdR1tEqPz91joQnag9i&Kv49{nRR}5xMw_M*)(x!V<;b_`vRa_&+Yk3Rc-8S%GY z-`bf(2hg@qIP4g4X`&@G9oX2vW&{d6^p|geuRnED$711_divL@Q=jM62p{CZ9t) zW1MgfC>4%6dPV8ivd~Vfi>393h*n)gy$baq#3?EmYm|e{Orlmj$n~aGa2gn|xMmdS z8njv1``R!D(saEuXAwwU*+AOcz6xm_GI&kNEcCPyNebt?xErpr;l4;mqNDZwmgnh$ zdyUKTEACywU)-?cLX;1-2h3Tr5{~7RcNMet+YC#OKYm_s{|2nTT)axwJU@{u^Oc_jnH%OVN;3cL8c(6KY6gqoWXMoikGP#CfQV~vuSZaJvHdnaVcL~fYEHJCE zxUAbLHIwE`J<9?Y(=o%e!X*yq*Q{HTY`I(+|AG+HzXo!cTkioGK`9Tg)roB+ay>x##-i* z>{gN>(rAGo9T<>_{OkdxI*=^+p%PGD23)EMoMM|$ z-y?bzE)%n&cRN&x0IzTW!$XIfQLu}RrDlS+#Zc9o1PzW@WBxc;8EEQ4ZM~uwD$V z(zw1~PenIw$00j$A(gL=n-e(-S9uzUobIE~b3v;jSwUaOE-y2-7gx6y$1R)CKH(U5 zOq85@T$RyvWlB3>sxMiyn&sZkU|01_ur)J2wQO7gcJi!)ydUUjfuFhee@HAHjl##o^7EQYwkBfsqb_- z4kz|u*4e^jE=gyw=k3iTwgbc}iMi@&Ay=#6R?yiSwJy{xjHIHblhV#;rRYQ~tA@Ry zW<6_Av;t5yc=_jF_O4yGaU~0`C2X=XASe@uMYr_QsRly^3?SF%h!tQ%dsrcQO8Dtslpm!MxwS6pZYY%vVdWXR`-X)snLgP|B4 z#QqR$@V%cJni?OBq-xf3Dc<`lu9mEfru#~o?#HUAVdX4`J@Cp5rFo&Dbw}@aysr~7 zl=nf%iWT?yj$v4delCLF`JcS?YLQ`mRTz!m%+1{#hsR(3xAu$v<1YYfNpim%;T{^E zwQ3-25gNnV<$=fnu+9=DbCzSmN?8{98qVju%1c!&&1_e!f^zj5N(V(-=deC5!-4pY zAy9|H&m(^WrmznPK$_;lCi&>s==jHv19K~UpiRQ71f&|quS8FoX3@wvU9pBZK!#5+ zJ+R~9$Vg_c2A1FT9ciu*kP3k1neel4Wdtim(u4NmeDKy9p<5MpKDm>u#dCXZRay(j}vsALcKHD8BD@@%~~diQi-jd z2f|nOUcIvC3N{89+{Mz)t2svsaZjH#1=9RS8at1Gj88(cS_3W~{%F)|ptA#|Qi75N zdet#N;cdn-`Ve&Y#DuE_w;I^uK&*?PiS?}9?;zHOOSHhd-65DPJV#G;>J9x)nMoumEAP6+o}HNp0F zOopedae}SwSEg9ATv2Vq;jY0KDVp#I86sXX3Le?Rz?RVouNqR@@m>SVl@Kacte8|a zb&XYLOoItSA6+}LEdZ@*MlYdQK(FbGKBQ-hY=$Q}9%@z+gi7K0(S&#ft-cR>R$MvM zv%`EldcvqaTicOT2XSi2VWEeTUPH;fI7v~qBaIb|Sw&}bjLQmu0P60kCVyArI@fRz_c6#avIJ-fr5 z+EQT}{Znb(#95Fk0+w#&a9*FqUcD%-nqD5nD!vE?A^-p&07*naR7x8-2dNvx5h2U& zd>q)~B=8`!Aq)&XqttL{br>YYshNO?zC@~GgH>X?!jS5kv5bB?Jx};(N>R=l{MC>| z0ZSMSVQnDjY7;<9=fk7Q??=u2i#q(#8V>v3Qk9Rk8!bybmyBw8szaINaJ}WNhGHF6 z!~$lSmbEtre5f%T<6J11^*moPe9k*6o}cFjhHfKWTG;tg%6js-uvmwfQq<`6B}+t(h>u$q?;`b4-3Z4+KdPxOjpcQ!MCU7>A)i=EF3SYG92+k@g_IGt?M zS?E>IUC!__a7JG%?yG~^86dSc>=!beyzr}}Lt#3a@(v2+npR)r z{Rw(SIqTxXp=3CO3Go{BtlQQ0bX`FsW6rj!dn_d^8MjHEUiC1v};> zU70Iu6`Sq1ch?LTo9*Qv*G;}<`1nKrd4RPL|JG|j<^!lX!A1o*IQn62%MYIPV{j9*%f z_AbLBG0R6oJ95b^F5CM{(Tl~a>s)@nufK1cW--fp{GtCqhV^xn`%+}zVqjmWohX`A zqJpI^X)NHdZZ%e1K3Fki{gDXwU}PYEbvp&4s5#puw_UC;+&zyxh9hdcT47e~XOLMC z+SN1%s&(O0U<(N{0#iV&x-ouLD_rpzVghCnR@tWrt7?1*Xw`vz!PAh;^Uz@u9N7QP z;ybw3QBDl`U3EP45NbYMpP?-p&F1>E4u<>L9fEkYT{6Jg4kYzXwhZDCA!wN z91mhTWFbpwmE_SRur9DG#xU`~n}*f*Lx3#0^s(2FMXtERBc;*WUJ?E8m+K`Y{SnKm zDtRJ^Rq2}Hh!BTLJ@B%%v$s`4JvH2G(%+~@h5OhPttZ3ts4U%#4yjr8D-`OY>Gtn( z$8ez)>`9S|?w*}EoUMZRhV%aoa0r#kh7cjd0AH~8okui5GdBWM7Q6} z&cMrquSNRR`}>Q@?GUYcB3cM#&~Xqu&SYXBFT3hhE$j>z$WpCvD~2m5QG!)96D%AJ z;uW6+COjovnlOqUyJIi#Rd=bwpeSsr=5xcOH=$VsW=YsnGU=V3$kI;F4}oFzlI-BY zS=mt`;@>Tkv@dsd)ZlRQ(u%7`XK}C}Pk{_noSdb;ck^VO)!>lr8JfM0L*RE>Rbig2 zT{#yx+%&eCb(9eO~aK zp_M__*$XE|F^;;OL6&l=a7ZZTb_|DV7nLfnXlgjfE{@zUVO5RyNqz4+hOiFboyL=j z{w@ly2n(sF(ZsGDtB)?1qg}}wt;n$A==W+rjzunM zmO_(RNcFIA9}A;N%A76iY&AzY#wf40VJ|f-8M@CQoK-J~SWL0tBi%dz>;HmZt>X#d z)2!rq9@salP1OW7pcKk++?mW=Va)&L9Kf$=#ywW@!+(LR|Zcf>q0w zQ3zNPc=d^KkjFsKEhAZaQ)>b}X@yqR#;=Q&%unOp60-H z(W<@&>3wfnFnhRR1PzM%cv+^#?9J4kCS^V%gCH$uF z^tX7m32^mP5Uka@$VA?*3bB2);23?@%n?M9IKA4Rvx!g+2qmyj$d!QBP5TE=-ZCMZ zIhM;Hn}dN|wZ80(Gr`Y8>ygKdQ*H2vvTEheSh^Af>hvi)*lWA}!gr@bqF@&uI^2zk z0k9gp2D9owu3&RWDr&K!HH4{g5D7jATTHN|J8Xz~@S%(Kn4cM5HQXVX97_E?09Fx7 zs;h+}Uxg~eeJI%ptA;VkVV_4il;XRx@omu+9lcqzGsD$7e%fo`*pDiiwhXZ2U+05P!trM%Jd8^sa&Q^x{txk!lRMYS?VOm|Mh^0>^WFqK-zk!}( z_-hoo7^6DkQv7q$+L?aQja7GjoUZ*ba;_vxhd6A+22Zc)@a%qE1@aPZZg82!Et zYth@kS}+Vv(GQ08{Q>L0$ydIWRe;qx7WC#>$g8D@QEhp))#rU&$eCA8AWP=A`bP6j zXPyXOPp9|S=)ZbV?-kUm{?$FAhvOl0UVU=WAV(e_K7&KF6(6qxPte6dT*)X@03St!t(V}EI zZiTMsZ4vPoP7A}TjvW_n3oGe5jD+)$zb7qSeE``cqv5J3tcZBEo^3_nOL2HW!1u$e|DosE;A*404$&>TE)5NH z$EYSFOU7u}Dnpv?^G=dv46>lKlj8ncR-I4gXb|DbIF?}5JKUmjK*+P;K^{!K!W{V0 zN^=)RLZpet5C*%kk>RZdT-Bnxi~b&A>tn*14~&7JRdOM&#cp>3C;Cr57?s3@#b=2f zkBW>|2~dS+y`y7Ut{^| zEbA|;tdNJ8N?OIdtjv=&<_$Y>UB|L#a({#BpDt#t^7waIjoz;2sC8#Fd@!tUh*-?!DylPv&m6@2m@ireTe2Zx>I)@6&YueF}~Au3(9g;XP*c zDZe_%svs-Imnw4Z;T)bs_JA>J?%uZ^c#Vr=3 zwI4G%tC#fT9I&j{uvm=t@etmI|FC!Mx`}K{bPU-YB!&!i?tq|!EdiE1NCa*~K-$5U z$VmJR{sH9gn9P59yK2>IZ@@k&63iT4GbgjwRIOSMwd|ZVkF*IA(ui3lWX(0bxx}+w+{xesw>(G!ETON4+yxo`{0eD=br|w-*t4~@bmG%*u-Q<=Q0^t;@YNB z&kz(j2W2-z;m%-n)_t%EOnb2p?lb@^w595GaEt7A$&nGJT?uy;G_dt%rILoAVi-Vc z4XJ`K@3sV0BD`CTJl&M zf7P$UthMf4>r?D@D&gHPSy_ zUI)ij;`a1Pp_jcB2@PIV;6isQouE|YGo%cn6Ey{vln)|EhOdK?-i}(F=itM^PPotr z8Ktl&PL#_ea3h3SaN(M(;oSy%pdc4y?dG__kx=HUoWnats&>_7S^RQduW0}q@G28# zbYBx_CQWL;N829nojW`>h*zME^d3SPzv0xcB#y zNV5#GFiY+C&Rpq6=#tVPfUi3%_*RHwFvOEu(N1$cl+<;k7X3aioDW68PFM~n^{vp@ ztWlwIFrwlnll6dryVQsN{_lc@K)FAa84YD^s$^i*figZ|O)d(a8L?E(Fgr+yyNlb) zbx@?D?{88z;cXLoAlz#)j?nH}kR#T?n0h56){3>F8=9-O1XzMuFN94S-UnY+y6(wR z$oQ0XDJ0~g|B?(=z^QddIJWKxuCiPPQ||aPk7M*zN+cj1zT`QJafrb!0livGQ@|}7 zt8_iAmc$+*5U$RGi)Zh0Qg-XeJIl;EL5*dtV1!GGQtsP%|0r6*JocT*cWsP5f0*I$ z9G1g_s7Z?$2dA*+W{RGfYp2L^up9?D;f$&zhjPdoUun000M`BD)i0T@e*es0`Goc4 zwe(LIpGE3hO;=JaaG zSEgq8r1%B<6eDCdOto)_y5ir$VVRU+CG(W%*af6$e!{So=!;C~M5KGBDT)w_^$vto zYhDWZV3=_<>{7yRIN()E0!xVj%XdWs?+c_VhONGQh|U2Wtk8{aC1%+b z@S-O*@Cs|;sW=sS27F-NKcuh%*TTjVl|xr_v_o6)3}S_BH=L+nXLiM7STb3oK);VJ zQ(0@tybgv4_ix;TmmA^O$E)!z%d^S;CRajb<}=s0`+=}ISZW^xSRWPN zzT54T!79QT5GjLvQDLv18L*gL*WfF}iXup6^(mO;TJ{Y{swiS;+dt;5QNjxAVP3UB zCVkLol?lEGj_6~@Ul3#w9)WsKybz`VvY4upkD_`YBuc7r!1u#n>U)`}08*f~1`soS zgUR4~wI9ahzo2(u+Fbx^Uq3-~3 zVJC`^20al9T+I)f+YUiPh(k6lgG#VsHiIcfcX}f98zGAs)Hk>ypjs?El;P853>ygB zC7X{BYZG~O;Maga7_qYdS(cr!O@OSHhpP-xL&oSua})50M=yF!!`wAYUi2v`vrf|% zPhOziX~Np}_J>giUoi2(x?>D{ueGdwZza;=j^1l{77ROB2kQpu0yqeE0LrJf67+SZ^(5hJ7Tl8QoCv$h9`^7 zI@PTewit@Op<>|S*+D0m7KAlLUjwR?6LntgoPPfAfS< zI}d6&gGC|_@2u4sLeY>V69}w@aab=B7_(oLO*m~BuaspcN-Ga@myTHiPp%nl*R3vt z#H|xsg$EN=%wA=F7Sby7I7NSot&m}fFNge>UDLqK7dAr%q!b`)ZOnUTY6p0vd$;Xy zc-9($%5lVU@%u1ZZ8efqns!cxUi`Lb2rI+iHI@|5768vnp-4%U$7;?tW$B=0J%*E+ z3|r2?PiAG1!^{V)D0`oHOqR+>uk{#?J(tvmtOpp})phW{1J*cP2(K1<8A%Y*MMtqA zC-xA|Ook*L$5@8 zwRq80P{u3hL?wEGkm@f2MY~l$AkyF5+B5}IGcSFxK6lEu(=$<2iduMK5}whjV_gFP zE7SkS#Cu9$v#<}!hM0tcPYBcMx(c#7MyZZzE=H<=URJ)d6$4MONAC@^2EcO4o!`En ztjchII>q#vcaQq}DCl<{vd(4C4zm854@WGI_&dna@KD4jTk8AVlnt8ap{GJKcm>`2 zsI1iq=fX(9kBxzcr1Sv>_XAkJt^wB5cS854E45xD^W|W`Qd3u)(t}jF4(*FE?xel) zOc`v0!=QEMo$!NoqmAAOi@ph23S$g1)p@;ozUT{eq-tg#;S~iSe}-O(jioY3GZ#xl zS;X+y9fO2f*|ZD16N;n?6P0X;bOE%@Fy|%z9{yWm+`=MAh?NwtQU?|bXay|;rZRyq z;1$zfydCm}=z6S<*1S&5I#KE%ew{5ic<36;wc{c1{npCuS(W8fmcmr<8(L*WuvqkZ3N1SprhKxh9kE8gOZ%#Ch9zX76ikeUI2JbOFg(bxb&%h44WO|^(#d=x zuIR}uW;xW2U=@os3jM32Z_~2y&+G#V?uEmuErkD#!Fn2Bw5BS5RcNsECq^oA>Xzpy zXqZ`Kp9Z;~8+H-0=lKw_`ZQ|P+4c}9vkUdkUO7?Nof)tw%U$c7Kbgb&3^wPM>joXI z+F|?4o4i>$sZMhi-pKOTs{SD7BYkrO5*_IckZH+eRZh%eC7!F6G;gKhDIJGj05ayZ zeBxro1M5k<09=5qwC>%i(^;y+T18p5`#tHydZ0JIA2LG{ZBHitF05GI%ITIr?_8%E4dKP3pdVyR};)wUn0U%z34wJOm*7b z9w?qD{DZ?DNbt3PmClJ5VcI=h-S@MO@Ns1-M#b3QP7IuS{d<3wSI{S{TGSlfQSe40@`A zO0#;EW~l-mZLC4(u$7#@o*X;OXF>jc^5)gO#*$iyvW;6GAGQ`MSRqOokQMRDW-L6u zG)KAYwO6Hsn0Dq-_l_T-*r%h6!<8PxQISa+TJ06H9$;{nGOVKK`P&=e_(C!|x+qPp z{rt72}o&tp4P7Wq!e&RoSk9752L$Ml1rXBY$%oaBBFnQ|&u_m6u1}6PIAMmI;Fv zBh)h4cZycJ5b}wzGZH@edT5Wnw>$^q-8Fi~S`Ni!Xn~~2anSY(wHR(=#$QmBo=%mN zlo!GetJir~S2Ptzqf{Y&aIyCs#sE z>01D>o+X%pV~}+b{8Tf}W)(6;rM_#EnZe2{Hwor2SSex=3bn1^)iEh}>6A5$R|EDO zkC?cY%VWk?NXT@=>k$aGv|(#_%NrwYg#=Ssxvh9Rgvvny%>21O^k66Dr-Iu&8vZXpBrRNVv@2Q z4W|LR1h#5Y>l)|&n6U0!*6=f6jjIs%Tcz|?XJVZbj#o1~^i(y3Xias_9S6b#^r9hB zrfGH}!}@sJy}mWOqI&RIVj2jXBwQ3-sm5S&LW2~f`cAlAu*rFYP*FBNtA3q)H!B&i zRK_4m(KdyZ5I!7P2(#i9eLOOMb>!8Mrlw)SqGKRWTJ%KxJP}#^*J!v}E|;kT!IhRt zU@8gkE)OQ%lbH@h_|TdBz4HJXaq*D-uvEZr3&V~b3-=lTFWICgX{_)tWs6bf)etAc zBA8T}EE8l|Se6J#eKmyCff%jX3|)p7W7fPh>qPo}R&ehwexKA#Rw;WQ2dmBl4DJH3 zgmb?QSif(G+{YIo4S~v>7P8T+8SaIkAzE@o;!bnb`5?E!FFg+mU@2u~-Cl36p>IMU z>(#QaAZJ*3=im#3?WDs3*S_Hqiv}zWX3#R{_U|xWt&kon%VGO}_O70_jdTmgcCiyZA)Tw6Hr&0J{dafHInVicXJjYM zhWH{mwj{^t%#(AT^L%s$RX$nGA+3rG7C@_F_B}}k7PIX=MD_DkN`yW&Z;P}Y@}N~S zA`w=lT7+7)aa>|JbOi(>mZ%$q-qQV$zh{}sF~gztmp*Q-18#wD=W8O5S-KXo%wg>l zmU8f{YPi2Y@TXLQ9pYkm7j1?*Vj+CS*{ms6L{?%U%3*+5Q9>G{{RYzavMdI=tWmMf zK;0mO)(H$=&6)6c(CBkBmRShT@}A1`LF>ezg|I9$%W9#D8uR3^31eanImknXoM9u3 zyRhyEXxM1sL@0Jv-fDT3iy8Wl<&xm)pUhoRbi3XLHAqIfCg$QE6y|E)y^Trj@ZebT zaqu|d}cXDfOt7XvXTns{hNnZ3Us|dPqnl!xn$- z|8ecw1_3WgbI@I|GF?^+;A%}(YS5)BEv2%uHp9a~3wG9P3xU_QQ2N0#i=jt3cxUv% z3hu=oeQ(dx2i1@o3IAXnJ5$Rd#aH3qAF{}-pn@r^FZzhXuqetbLHYd1QkeM*PgwAO zL17K>%2FDRgfyJz%@aes8kh+EJU#L8ibEQ9@IHfc-=QTZ7@rBRrdCLg4>3DOL(Vp< zAC%;Fxe_jCj}m(|Ol@ZqAp+VpTvSZXGEW&wk=9)V48mN69gu*D*mZ)IhBzulr~Wh5 zJZ}+)Rnrr}R6l4jeAV>PZ-_K$)%@sa$`Vq(rtk6oN4p^nT@khjj4G8mRH|>VH*Shn zHG|1Y_g1u{A@Dq00AE0$zp40rtGT56wbAce?1oxn2*}zF3HV{fJ>;ZQQ@^Y1U3FP% z+1ZJXR7}y6jDf#2b;Bf2aJbAx4rQ3LEag4i3oQgUlfIw8;FYX|-x#otGgxO*jzrIy z7;kOf)oJdx0f?uG4Wf$5R8DTqWzFx$g;@a=Zhf|S_Ds>;8o2WJZ_0RViAF*OJU^@l>wDM3z5}^1+nql zVWY)h4ozz-jy_mmmIz82v%q1+@R`Asl|?8+OS(ZO>EyxbEc5G3O+Jcx`w*4|iy@|Q z(Y_CQq8+o;xH`;^JTC`1S>*|^Uf)9a>-WxA7o&}E-0F2aWV8&EdZ9O-ECWjf4Mw=@ zKDaZLJL|7*0a=>bx71R4DWs2a$no7mW$rUravojG&|}pio3dEX(1~P}?1G|ZxXE&^ z=$(8=%r~iIW-qh4@21Bb-(ZsNxZ;-w;!cmxNWk zAQD&!W|0A!(@A+3gyx|Ec7<3{Rl*BmHLw}-tB|Lxky$`0n0AE6vO^*A--Un|Z=omr z-3`(lVsZn$nbMf0p$$sFKWH(o?S;FE+6#BACDrg5|L=|2EITwu-15|!GV5C%Dd2NY z^a%}K-+=W^0?X-kEueHwLtgZpy9kT(^CO9UMHY)3D^pqEu9aR>4ev9G9pn{|RnTNHy5SSfWrOA!tcZdEd7F<2$QR#hiMEP^Wf%3PMLeF-Qb zH3L>HR68wss&YUEjVy?b8+W)IjM7P4^A(!I&;m)l@!k)H+FY^LFu%2hzdK^-cDPm2 z{eW1~gE3eTI9P(R((gh3J~fX{%y9t!zKgA^nmtn#=&HDMnM{l%HH)F;&zuh_c74(mC5H!d0%10|+1y`We-wL_DvQyyAP0%z5T|V!OZfBf| zKt*pVT?cvFBiQPEE2O`z!C&!6MetQK`7WB$mier<;im+E!nDO~mU;(UQ7#Y$efeD`8n?+=+IbgXTHh9Rdv>a+If2`ONYgq%K=%(MP%D?9>qC?}TF2v7pgB z5qZ!#QRa?kb>!&(mBhioBX&`LU5>39W1YAYYLgk?`cwI`da zl22PSQKeQPCoyT&RIGDgp+ka7w8nyHdtqHEE=8G^Tc?%TlA8OF_P1}EU^kRbFfCtg zf+}mjm8PAonWGV#b;z@nN8QNG>vGBX6GIcBc7i8Zu>&D03Ag?kJoHS$$Vm@H@{QA7_w@8q+?H9jO{D+CP8z zAkwQFUj%PDoweM2le%UeKnjCZhXoK57GsqnRzE+b>qLK&PFI+)n6Z*=PuO*);}wHg zN7~|s$UnwE(kNnCzJt1UT$j~01NTnju4vp0jd#aalaso5bPv?h23FXk*Riicb4i`j zQti7cvZm2w7_*c!`MYV}cgDT5J317Ch4^=^s_>_ADOiz>`{8Z~#5y6uPtLZ#iNVO< z(L;DP9;}YL2=l(wGHab+wjp*sPhiXmtrOD;Qm~#pW;8emfmhN(=zXa$<7l6k0habX z_oEdH8#GboxBi3SX|>X1hSgm43<$rXus-41-*@3L*P|e-8A#iZpj?mvtH%%@tQ@Os z)N1keI$hU-TUD))MH3a{Sj8|Vlb5W6@`iT9N&%||U}Z7~j8+yzmDdW!=E{f54`iEwrQVB+_j#@b11#ZDnB zBeMj$T!?J)26x)S#9C%y4lcX_`F;Y0pB=A`d!An^^%`%3=R?NbS%LDn#{DvCXA12a zPzjc@S6`-ptS5RI{DT_vqJQYZ-wgF zQOKH#GE2Ln&0jdxJW{(EPIAD~=$TvqpOt}yAfYnGkgK$?XB+1NUWfv^Z7^%8>(!r{;jnK7Lm9K->f<9G%FF6k~Qt7>r znRdY)U{w!q*T%LBT#4wRRyMv??L##(8EW>7%d_wqn(p_Uq$PkQ4Tlnu1?S;jYNK%` z)M*PN)**PJ*RkAQ@d}uA7uQ13jcSOp((js;#ej9MH5KYF+}W@tiKO7(FXMy-kKx3_ zvWDXKvasZtvBU7hVZ9c-IwBZ-DG+%yVu8VmQ5}B_LPpC`piEH&MT2(`nhwiESTt=> z4dG_4STb}eJbg?GT&!BaO^`u};fbNFWnW<<3I>rk z(Bqm2cMMYf_GlwkszGUC)Pkf`rCA>25Z;t<*WzCmi+m4RSw$A`H|W=iAr41` zq(5rH`u+1?U;p*XyZ-UZpI`s;`S%kTeK%q~qrZBwBj?zB6)1NrO?4K_IL|V>5@s0< zJM4oKY=jT2ZI@avz7BFx&aI0Xv>nGBIalcQx?KuhS^eNlyPaXnk*0}U+z#$)#X)_r zHqX0!w0f(fRuY|P(sl{ZR&CX(fE_$m2c-Il`AGP79=9+*F@&Xlh-w?=vnrXR=!bX* zOoUi9(Cb<}J5@DU3NdFv?ZD?mN^oGTYJ$cgrYg6Z?$?IWdx?X0)?GAN&3YeBh9QL} zS`1Z}1ufQ{H-p_B?hd2;85*rN@@kWpu9_k%q895MzVLuG*=e`VWu)G9OxH_J5ofGR zskStik7yefhO z%LwDD;WnSx8w3uR`1U9=0bwpzh@*v7I|TMlD~ zA*u`S_&^wYq7|p64p%!KvY^KThxIU-WL8w|UNu|&7_zh%a|BrB-_2ot`ugtK$Jf)8 z^(cl;nInqTvEhk;FP5xd=yo=i-0tT`_MWX%gMR!QRS9m<$n3Fa(T6Yg=lA z1eOTs76BU)AazDU+Udk2Sq?6~;3k{sHXZHE>i*q*Rj;bP`WhII_vBsA%8h}>b}+&C z>DBvQz1M5CdU;o}{BMgJIYZ8H=TXq&MTf`omG@t{@GAnT`5aCL7O^A*`JU_OxqR^E zel!+?`*?DBwa_b``~sc;tg^}8v_p*Cv z-mJ84C!Gqn-j)TRQo6M_7wP`s8g`=l{oU|Tg$DzbCMe%2!BQXT-O!g+=y4$c%P3Z~ zWjT)3b=fm*Q`V7*G}^JA_7CsNKi+=r`t3!`ItN&USZ+9MmwKH-tm8bHmc>1(dF~{R zQ6Dp!L?Y`VYwV;KXSUekd!>OgY!?M;jj@n38rd?=42#Z^f5n5Kt__Nt zfldZl#kvZwSGw=KNW7xDODKIgbqlX{-rC@CioObgtc>3>x>5BVx6G=-Gtb$W1)oF4 zB0J55idjUq@;n1TW$=s^QGF+GgC|)t0-m-6X?Q3NLWQpN}yRAJ+DdNYJmRme%qAQmfw5F*OSt# z|Ga(R`tgNiodYa_r#4=l2duL_&u5z_v<$9eb_UL8NFuOeX)3^qMnYy+^vZtGUul2P zU6sUNCGM-(@XXcp9Dfy8o~4QYp8K6CUKAt?+k^KrZ61_NqkAKsP`PP{TQyC1<8|mfYXU-rX9f^stxDhdRZxoMEBaP}2S6!P zz$#U_QdujHR)+#E_`*$xWgby0Pi+p?Z&*49{8CL0S_`&365h8~bHCrOwPeR~vLsSD zpcO+FfmXFAc6A7^a#RQ#>5366Zb!#Du)9I5iIz%x$nP5&64g!Wl~Mbjb{y~5?X_mY z&Qk-{f4@9@y&%@P0%SgiuT63*4|NJ!w71Ybz~x1zEHw>01n6Co!#Y+!t6Bk4wb@0(VPvPS&HYWrhxpT`$Zf~emp2*^gGIA5Zl#` z`*2LLipw|+Yv{zSXb8+2J|={A#X!Z(i(xFIo6K~pEQ111nikE91VkB-3Xj}KRZ&c* zPQWrfOF9d4e^QwC?HFdc*enTm2>i;HqOlkaniW0pLa-#6bbqi^(xt9K$5X@ger`pE zmGG>6tJ*%jG4^2s=7FD{A;=5%0?GL`&zB+(oRhCNX ztXV5&S}V+jcLrG-sfZp*f&)sy0atfg65a2|%2j1peO)e0yDC~r>vsZ1AHI5#c7OR9 zve@_UmbkGJa-ExiSJJf+aRuDf`O! z{Lradtkq``rG#h|o?C6z)#rTFnEVl3Vor=}t zo%>$Pm(~5w7}l4sYxfLNe;dFGh}8nDq?i6{u7;DbeVsH`CQ0l_mU4QDqam)YM#JbZ z*5tr2`Z3_uVCY15?(~X*eNvk`n!D18Q8mX@I1dDCJ|Dx+Fcx0})^ZRr3UVdQ&J(Vk zSZI#Sm7`VA-6whsh_(s67NtZnsN7Bx7J(G9*8yJz!W!uNc|qeK-4pCY5=CNr!-!R| zodNFxVGLLS^~w_O_@RK8s9k}F((XEowlBM5XiB-Jc zO3D4wUxz)W!u{Tb`^`;M1h8eRg}rWEi2gqQg1-T+?8LY z7WWv@(6Pn%UeDL2#!fG{YOl3k13n)72>FT`7U&gRqtu&PX-Q5s|EE-@DqvMYwKPv= z%;8s~F?Mpo3vn(iJQKm1Nu~_>7*IZVODfim{p}I2G?rm9ap^J9Eh;fHH8psdo1xZu zkcY#j!RMwCZM`9TC9X}2vmA6kr&W5tWZ2qH6D3Ox4oe4GQee18P}ZKiDolCT0>i@^W1-rz_`cF% zP(ril$dEp+R@w*lj=;$Uzi(_CTD4HaE8W@A(`Z$)dNJHjqi19Qcv6P-{*l*T!mvKb zn$Yvx$YGCrG7>)EaX))J*ts|%V0Dh&Ev;A?*OH?+1zW?wLi@n5%reTvDolrhS93il z0n!fd#do(WR0X7|Lfm}pIAGk8T8JPuB5+nJ%vg0E!e z+p&JdGW^b_LK+jB#DgVj77c=IW8nAj#qT=R zOjrS}ELNuS9;~?#t>zF3x+|{QY9<;vg41soFxJ;A&wxVZojDz{!*UGBa^Z9;1SDMAzyY)lUMFN(RECH-&B;{*>G}4Wh zfeB)<_P&XL#azCt9tUk|>LoHoEUI`Ce)aaz*M}E|bvyx{z^hje60AgY@0>a#OdRgM zG}YJAYlM;O$k|9x1Ilqe4rPJxqnEFAA`H}Og&jh#UTHdmY3*_EStGFSk=u7mc!jo! z1@8_nX5L?fD+tiL*na916S&(sx!($rVCuFLXF<`OF z0azs(mYo&y4d_+@z{=tWf|$%`m%tO_5&%nv!?<3U=Pv6n_Z?wLkX8x2nnw8@yF2D1 zjdfrFyVllO;hdyfE3Js7tJ1nE!y)YMd}wGn4u^_g7^(!Z;#dd=d~99SMAFRwwk(md zBw(9Nq^@75ua7<{SZ=kj@5;c`;P4cGZ=W6ySf5`QRyq@&VOZzj>N1+#kC&b=5`xv~ zoT|yO^$6dRLj-GMOV4bCu4o1fKt(fQfUJO5j8Eb2XO^nMn>V;m;yp1awTlYD z%HdzA3%nP=FvK(vGUYNUGP!!gK@9lthQBiT5@!~e6eRd?mzThsESJ+mFfj>z$1lXi z!qPh&a`~L+ZN##O(rKQ%xGb9p5uIgCJ6pApPI(`C>H%x(+wEOTw4ECAh7P!utm;%| zb)ZqP60AD#ml_SS_{T{C$ zHK8V6f6RRKj5Vwu5Z(8Uc;#YcQVUk6(`qB^S(1ClnXn>a^^*WBTgpjTmaII}G)TmX zUn|LQ9}Z(cg9gfQ;RM1O6tG@{UJ1|QfQEor6y7fCI|?Z7+0!5cVPID*wqFxg5qk<) zRbTCxW%;V+R+LPmY^u(8@jg6vLa)qv#Wr>v4%Usp)*EJ3Z-7h$HLR|;Agjrei&ZPK zlZw!urA&$z4e4j*j?Z9kPlB`jqM^FrrCi6I5#~2Ki>d)=)eJ1OmOI% z8L->y`qI_j6P*%%`Xhk#`Jq2yyM#%7`hWkK&zNETaAqPri&iJM2$NR&Se4XjorsZr z9c&k$TE+kFo9E~IyfcYfo5HoRNhZTen2bH13)Ydo|)PxQrV1_ z;F+0;Zs^H&A$qb#=yJeu@SJfA&k2hMq*={UOSBY4PvC)U?=&IuzK#>KM1tS(XqHy4 zvd3Zlf89>@_t#IcegRtVn*2ag5fYW0m1csWbX$$d*>_l-ZSKSsF_UA*AYTaE;M6 z+fPGC$763-2j;^b%!NIvFeKC(&DfPSnz1o!MDa5TW+*3AZhy|5t4#@?VV*U)VxPlA z&J7zA#w$UphGkjmB$cgb!L0TFbvt=@)$OHY-Nq`wdNAA6@2}~_86xQ8T@A9C-GAag zU*Ma}1Z($IKi0|pck^5Lldo5P^5fFtn#U09GS!{9SVn~6+;c5arrYS zzz?|y%+#-1Bk9x%@6uQ?mPg&!F&=nssQ{M)I+LKy_fx)9{LepApVJR}VGi!AQ}oCzYkBH;>tiV?>lmVe`f8TTp{ zhXW6cE{I093_VVD$Qkg5*lIZR>MD3=Cvt%0Oj>$O=%lQv)UXF<2}d#;qA?4Y7A_Zh^Pmk;o(NvyQZ$|zI*&u$G_IOJ(j8se*?o(E zwTfYFECZ}>rA)5cm({0^3Rn-@rO2+kC4g1=uWOEe*xuh#J{mobYvy>mfgu|$t*Y*l0_+46o>_&g$67d2Rpn$SYQ>h ztPVD&Qlw0$<4T>oa8B5zl)lbT*j4H>uhKME#7a|9+{Mno{sjiE+_0`32^M_OgGy5o zB36KNVaNiO-U6Kg^})xl*r`~dx=5o^Bq`IZ$ff;(t8^G^XqJPj$cb5p{&JxSQyw0= zTKhvKS$sw~)g%YPsR5zZVBC`N5G`3_j>saC1r+NP1b3bb5xu~e1uHs#Z`Z z?UyjD+L9B?>t_J#Y)O#wb_K9%@4mhM*x)(6{fF>sSyPUZt1WMfu)34O5m;V|JD=A$ z#eKmHi-*CR^BYUCMr?8)sdcpXQOpedeA{kuu*@xsS8a-LFYYa>c`hIfM65ykfFTPM ztPbb*fpUfU47gB;nSF#-=nhpWOS-&L83}n5%$;O~wouX8Gg7EX;KJ7DoSY2BJ&r;U zsRH~JB4`z_14bqo27`b}RUp?fq8OhGvcKJDT7p$h=yEfohAKNHD|UrpENaEZ;lM#z z(S<9E7B|*Z!3+C!rtHib$b$4>>cbW#&Wt&EX6D*g1*^uA;!s=wu{s@LPSyzFYX+x; zl%9-fS+ZLQ>U+}k2gC)_EJ{(PxGb`gnj})`T(wSSRo{PWhIN0oB$fH(Nx-_SEjhrv zs{q#BmldD9#?!%<60C}bwYl}*&8<&cUQ^B|Qrzt@D82^qjFtvMcS0!iY5^sLR6Efm z#A+88MRQm2tNV2JRQ%SZ?>VoR?4 zF>sZ{rI@67fVveOxx0BKh!wliXrx<*o*zs5bqKyBk92Apc6cy6V*Q%RE*Uw6fge?#q#Zuh>4Z2Ru<0S^KBQ%WP@ zw){-#lh*)P?tkfJ{A#0`zOWgut(^3fww}%)Uj_ z7qAeh{_MdsdKq--x!tn#YOlR_v`6bW?Kb4U4i9J~1jy=e zd|&EXowJNzMoxE^6l8yQP^QCJRdyITN?q!3!*OTJ{Mr{ea{s7@gSX^u0Dg6J zD~r$AI-#Q>JRBd-5BQi6Vj2o|#mUHE!#d!M(LSS8m*ZqKM#it4Nd2}PwqfzAjvNzW zAVZEJ$fC5<_=n4Z0AlnW;Fg>Wl3O&u3D6p^0>-02m{;He{HkMM3BnY%sNc}#{F%B6 zwYn3@8roj_3q>q=zA#1iUdEs4ik_N^=m9pZ4zO{R2g9)ttm3*g#ulBKBsf5ZLl36H z(_T+Yq7(AIlPxR3g&nZH!#ho1c5hA?vT(n!DPixl1IDiRiDg+0yRd^Zz?%cCA7ohe z?Cu{Qp_Tzwt@_^M3cz}({d*o^QtDgHt{NTu2FB%S#1n}SrOq??i>u{4n;bZv!y*oojnZ1 z#=sV=jNb|3m{3erc%oj$??Cp_F!X1}*lAu+xD)9#=qfBir(?m!bo4)r&$5Z609lAk z7sCsY-yO@6>=`mO45ysx$C)#Sj9W+QaX`p|!BAaU962+i!LY}Jr~tnHUEth*)4gZn3| z7}opiWe0xWmjc!kpZt0gmcK;!^uDve)gKkO+WO?Ps}f#q`UGpI?%!xDb>dD4QNaSu z9X;+i5Z*{NJ*n+xF(;vWtM^q*?toG~Q}Qh9gShgHlKY(WD|nb6h-VbM3?O7-Kypg8 zUVYpl1e0hd!-YZRR)}80uXHuXU%bi1K^jMy;8u`ZsLFU5C!i}zMMfk-@k(A47$O8q zNfmM~z6kZ&U|giXAt;%&VhMx~jp820zN{5RWcixRgJ_Xvi{gvsLdtQ#>2QP@4)B2Nib7}HdLhNrN~=8r z*A?t~U0s>@BBfX^!@)OY{pJkIw;J$tceavY{lz-`vYo>cU_JH8KP9>^IW}Cino|uK z-PGPxQ|z_7xx2f&Y9=%ecWwpvdr}vM1>CARA*A|0ch~RQR+dIR79sK2kae>df!P#K zg+}NhfqsBwQ1L7h(3C0+YP?3^_O)phFe*}S;S^z1#b&@uNNn=o?fuU8{gz;o9RJs&Y*sfR^< zef57JFY2DPKC!AALhcQEA%Imwph57e;j51u6OED5pXHi)51X%=&3uAw69Qz3!j?~6 ziM{RsjG#*NAk!}Ku?&k6!zEUU{_{aXjaSIcw1~Jo)%FpQH8T+ zGj!aKo1L-6vg)2;bu2n6uTE#~o?}~L*d^fVvWL}m9IHBr*Xw|6_3-Mkm(@E*`TIG= z8_35xBckQL66aYafp?-=pjMz;nJPo7_1l-dtL2eS7^*4^f~1DPjCi z#G(4O*2B78@w<0USDq5CY^eD5Lj-GUZExR7z$%qi*Y+`LMF!UD{FM%u1|1E)Stini zh&3!^t(T=mhnev!o+7-|eb3-mzx%Og*+$3&i&I$gIFkMJ(tm~Y)lvV5YTRj*kaMEc zeLXtT$N-I%Jwmf@TIAcxJpxjA5l58|6PpaY;GGKtno~ zwGvdy8GVu@z$td#pYalVw9wJ%iJQ(eM&U)Ef-CxMzEVkbv4>|5mUzLjy z0~MuUL?K>`2((BMmT_n(Ey}*wHrT1NA5_2ZZ@|O)@Z`tN&u3T#Q|U|OjjsT#)wuI% z1z;6^^X-GGo*x&(+PZ&Dj_5&p#)7aEugQr`tUX)wT&P6e4RvWgInI{=H)R{$-~ zu(HcxHXO!#2!}k8qn$DeSQR@PRR2mUu;$j-SM74Nff!c5FFja}V>twCG%z~|cBOdL z(5+t3gbRhI#V$W2~sx&5A z2_N$%NdP{AW}Z8FODpo>3+IRmRDNk8zot>|3_z>th}KM69A*fj!?!n2TVC`%)x%@^)lVU~8z$U)Hl#sF*Q$&U>%tj{Z9W%#d~tp#R@F(`gkysU4;93Kqw3guq9}< zU`crCOJ#-#Gtlv%Z1_UbT_j=k6*swK1m_hmr0=pWkUoi^c(IC zU^QXLsv|gx%Jv2g6^bUz8-`LRLFJVW=V(zwiu7nAQTHacPEgPtf{0p>M>dj)~43JpWkn}C;NRj8f8mB|)FA)yu^ zi>-IrsYIgiqHI1Em(7gWc`sXOgDyLf(fb2m9m1%!nKb&&qc0n4Ygh|dTMq@Stp@OkO2UCZ*%NeqA>t^sVhCIwPAn=}B$~{MMdm@A@%_Y=M(vOVy zL|B&xEV)hnUFse7RwAR(0e&T^CElguA#FyZJFRedruONo5H(~GV3CzYmqAx+{a$NpRs~_w3O#Somi6|WgyA_t?{r=` zBvB~Ba46Nu5^~5Cxq=3Vk!%IKkoE>0Ukz-mQAn?VUH{j!garW6l7`#wF|1e;?yi!A zpEfTE@4+igUp zh(eAsXvrwis~c%?M*@pB5MBeYde!drT>Fr_KGr~9JKYVcx+3R@JuGR!s+};kf|GS3 zXvM?N_%NY#)`V9M3R(p|JA>27B<|`w}hi?df!`Q9ZU>ynj4fK|m|A$K@{U@^s_c-Cw7vPcRla-Er( z1)fF!XFEsUoxV5{%3>pa#IF05LA-4fk5(4>aAaLUrS&dmJ3S zpI?!hv8-_J)fopAtBJwrxRaE4 z7pp@FzPF`|v?CRyWWdh}ud1&Hd{zkB<#Zu34g-fz7}jwd>r9=j9x|jE>KhPp7mCWQU zFpxv`)qe@B-jgWo!OglP$ogGDi~RR%IUb}4*4zm~t#p?|!nRxq&e~vBfUGV`u#PCu z0RKwdb}`%=4L&Ut#6k|s;ngA9uj*RVph<>FqzYF*XqUWq*7MX0z&zA~0U{N|Ap?&6 zt5%3)iI6GPi&pYboZ2ZI5(@3omC>}jf{-koD&J!Gni5<&+?uwSVM*d0sO1Yt9mj$k zB+gaW02X|AnDBEb!q?D)pk4Fv;B3J2g9dUueR0{x#L*~HIzzAEe+dJ)36;K5{CIJDRF` zRqG==N~H}A;1vtQh7`H?aX@&2&m70f5gk48XcahDM!J0T%2*a{r?+ZRo^?*RPSn^H z-{!FZR3c>tRvKGdsR_qcDqg$)=RtV1aAK%^q>g9F{t9hOCgwE_EiHkp=2XpjnSq`i zvjsmBzsi#D0$I{FGw#&kX0=5Z@@$SnsX1Z}$YpsKi$JSNwSM$NeCsuG?vihCh=nH7 z9yYI1@SRnmnORJ;*oB8Y^qDM)zhhlMdBoyS`x^|id@SqdGoTGGp?KshVc?&i#&b72 z4;;<8T{D{VZTUa@^mKBywZ?2;6L4RZaW54Ia{e8S5E5LW%iV{t!b)VE4t^XR1YZ`a zmC-4}h5J%v3*D1*nO&77G|B|a&k~9pWI=c>qObx%*k$wGdSxhu#hbmzbjSR2Um%OF z)Zf>480OR<2|_a6NemKd^(Sz#F#UYU4Ws#?IqipeFhU5h;w6J2iqT)E;&%mQ$c#=C z3p23so-29EjYB0x`zkc!g;*J6MHDRw2Mm*?;u-wq8^bP(kWP7e=h&wmNE)`pd!O>^ zXlo)>hSiZY7PKH{cTnFjrqA_`wasvO18vn2i8yEHeXP5o1+va$TBpj)s)r!y`Pq zArgcVXc&z?x+gnXS675rWxg(W;+f_MaYi^QbJYEYITj8Jdon|Kqf>-pzLSYXt$o^z z>_>B)41^{`0*eS1u_{Cx>izantzWCr5g|k&zbHQ1n27r>bqxkretj3kNb|zrU`V+V zETSi@(&7fugJ@-d1uqFKc|{JDMHT`}UH`6?E;(G$QKGvxkA+($OI2A=jBgmSq$tb# z@1h6!a1h@6xC3(wfvjmuw}9zD^ekMcQ`gwLHIUZjw6G0fIQHwm=6JI64%$`a;ljc7 zfT5~)=8bon(Bb?$(JUD+WcM8!F(aNu^osLXI4$JTthd}Z!?^}(BfV0F*7k{S4cK2WJS&*%WO#wKeFD9?RvgJ z`l`a_RaL5GuB(VKT%*06C!XC8-jCSHI+A*sK4uDuU(vPUu&Ph7QR=`Vyh6IcA=aS) z7Wfri>41>p?l}n7VX%6z_>c+c;4ZZmzhu%()nUg%)k1tvFGujTL4Rx2&Wwal;& zrUtn@i)N-1B~yI!2B7uEwt>NehquLBDyC^r?I*d0DfX?(P&AGUVY<6(-QCw^Fq$s) zx`s$QZO5?wIBr89iYjaiZq23Cugf-k7t!~M3`GN}D2+8>&~hNv<0Tb6qFl_f9N9kO z?*=ifVW!IPT!bOIva+{9NfrYaZoux#!C|4+`@yu>`fE_E=UW?LSnRTYzP}Uu z&`hqn`l`UvhdF1#b1?QPmIt($WK90MeXr_$Uw_?_{9`wUon6I|G@e*{*ichduU@^) z2MhdGee!e7tF;v?gsTesjA8v{A%L|}sAxFLLZfFp!PV5z!rFEnqn9cPX}GhzPuB>| zZwE|W+uE}Y2rrad&8?!L-=0_ISR|Y?-#)8qrOeEV`xL7*GRpS$G`;0c4r}`wDH2#6 zml{c>$SWAnHSFJsMC&gOah1~qSSdskw%TKFF-YPg)j{sJ9g>ZdgLYP1A<+h&B zd@1rm36^bEfsje}`LDV>s3EL=g*Br}ux5~jRbyD} zZKo2Hm&14RY$tMb`MCqUN)KsYi3&tVG6L>&-4&=hb)R&H9AsWp=Yq26smMS7#}1-BwmmzCSJKoAyQe2PwHSbXkRJKYSelznMJ(PZDcWW=gur^P>Euzm7J3Tbo7cuU~=S7C~$R|HHe)VKU zxRF~U+z4lc22va0rJNl*MVQ+lbUj#b-7nqV19!IcFUO^8l~Ez6wKCR+d=1;`!cIM3 z^u6n@5%<3dWVJCc)R;SOJS$)+$U8fQAuMYEJ}smV^Bg;#xw4XMyR3iz7pFMobD zA!3~fyQ*Q)FrZj9tQ*!8orGoy(YiW8$U&frckNSzv$VH?)50T=ES5M_5qz(pk5vBu zCe5l~xsVYDQHEW0*!yO^`*~r%ODD^U-$AjujF5V`vUMGOyBlDZJ8S=?;cPMObOg zT7p?K4KK*Es=?G9P&I}nnAOk-mRo)9z{L{O5}2xY8Z{Cujf~a>rcb>5Lkpl4B|e4a8c9th9NQL&8&k1!>Qi1$9KH1 z1OL6(kf&Q~a!8v^Yn_26JZT-hZ*je_#e4%$s#2vkG+}5{L&Yq?rag3H=`==*vbudI z3+-|47Ywsq9avcITCb@>U*OR-N;c3>+(kPS2q|E z>YbeHY~>lj(Ti@@(SWs_dAqMM_sSdv$$d8&oSEycFcq+?85ajzZbT^j>guqQa*>dL zg$?Ms%0Z=7od$@OQmYae)~H?ra+SsmWz}&lRUoURG%LtuVOm&pvWCuImv>$kmdnA_ z)Qm)V_+ktzTCEAA0FXd$zXgR@&NiXFNOW_+VkM1FV>xeYz^jJ?%VZ^htk|Jd;#ijA z74#uu4VrkEve!=mOYw>vOLd{G7ak~dfn!ZA&>*_dCWbvL_yfaAk#lIGBTJ#`h=?Va zRXv%#w+lN6WeHqW+HNhn&7v$YE1e8#&;^%ux+V(&Sst|*a`39qZ5ZxhHhpZ4mJbCU z@4g&hJ#z>8#ggv&hkm>+T#X2WqIZv+s@GG|E7}^i*6ttpuA z_qh;#?qF+=SL62BxJI6}XB&oLg7o;s0qaE`_kZB=j}_nlytw>)fA{tE>#ukBr)yhF z)a(5Z{$S|)f98*T`z`$BFUvmp`^ry#0`}(H8GukZz|!w*t-MXY7-?{ivmN=$uMlp# z+P=5$lR~rr03ZNKL_t(8F&g02r7f2##{#!P2Nv9`YdG%uH_7+PAmVP_GV?yRowcSx zaZ4d;?!s3yHulY0A_-fw)DEVm??e^8BUYtkSr`sFlwwIk9qoOBRS<_HSOQa}@qP^i zOYv$_8r5_kr`dzWUc#>rK(6sPaU;V?-pLXq8#>4uPFyXrH{b)S%6BwO%2Bjvvagnc z%m39d+tUeoTAV9-X9dlm?6VDcN`h+A#BUV3?uG-yEXApWfR#)gUL7#dFtt=xjq&$p zO>HcBX!DHqIH)F+U;1G2jOao|DwJg@VztmmDm<&&Iy$14RTbQ-Xm@f&kqP!Y9W7j{ zP>ee7T8o2qIbc@v2|kwNS=@&{zjicBmkVzITQ_^b=|Y!x|MLMBd!rshwHyswfBpxq zFKMd!Y0X#mzo7WE7UbKBM^7lh@`$xwI6ZNe+jw^E4DMp8V_2u#Z-b`MZ94{Mk}xa4 zx^Xcq`MY$pM|!2Md;enIox{n}BCNTHK^*p~sF7u8Rnf_yd;^(=St_7KF*s8T>sCWp zLa%PsZb!c1@aj$Hs?&L+X1nFEs0iU;8O7=dQjO}h!*NMOVTopzLRhCKvJec*@hsDZ zicX_(A`mt3X8R!1g=OE2T&ADpiPmJ|T&#zDswHR@h3FJ5ju3}I>LJRl^}y=#JJDtJ zt;$*AJ;JasiDP%w9+EIgf+d}VTZL+AF_%RXE15PK&C)!UTZ^voUd2?scbym_+;GxB z%Au!#)qwZT6~naIIypLOx#Ah5vp#;Lll7hn2f-~Ayeq|GeKJ>~(e&QNRr~HI%Vc%+ zonE$gEe`BZ?%J--O&|>cUN=@p>NYTr*ZwyjKMhu1?2`q46tjZiphKkxdq!8?$=S${ z2bE+M@yaS?-oEwK$d|hDtb!0B_e<}$D^f9mb>oiYFoT5w;Xlp4y5Jt+ysv3dOel;dY4JVn;4stcgy*`Op4a>Ph6hnt! zL;C|m`x8+HXpt|?VuZAu?@}I62@b%l21cs}F%MKgAts46kusEJanj@!N*?=s zQKS+HD6l2uN`7~gVvX^t4pyx+rY58?{NQ}75$IN8r@XlT96Q_H8D3>TS9xemE1I}N z&jvJ;B|(NbS|<30LAt8QtKvWw+D{L89Lyu0JH;b{P`(Cc!4Cji30fQm?4UVd5DOd& zEDK-AWhrt^V>G@ei2#-WnDu0tD6A>h>h&!Bu8`G3_?_0fKC2*H7ARb zkU=b!g#uZ~jUKf>eZ)KB6~v*&-Sy^|`dfOXLIBHoSPYXAuk6BQ*G~+uEs~{jQ2!QE z6lUi8OVXU*9z960dH?^)une!(*Yn?53RqjkjQhf6dRka#&cWI#UQXTK*~$Cuu4xnj zcdiodT0H~%WIVm%gpdx_wZ<73!cxy&TN}*6GRSJrNwF-`Kr_pU!PNAihTZM>L^VZP z6v@$)8#&-u^0Ke|iegas)xH1~BBLe#lCOG4P^?zN-RF_oSG2aq>Q{Z3Foxx0qlqx9 zgzyD~8v1b|-by)icvW#e9sXmZ(`wF0UOJ9ey9hB?&{9K zds!B2z_buuS&CrRFO%Rtv}H#r3z;cJ>|M|)p4!bqFf4_ugJ}&*(EnoZY+Bn$vnU)p z43n7{%t?EZF{T0pkI)Mdtv0&ST@Ln4q^V? z+;h%--zqtAdV0X=^h{LNr``6Zd2;S~&%JjxQ?{W$i8GU1J@n@|vP7!>&5Sc=7EUW% zgXUn?bQcRjQuGmG|5u|iX>j5@@}xsng-OEJopT%)%D@VX;RG(#gx(KbnK^TH;)UV0 zP*wIrKWbt2?!(u4_3_=~mW0o~Utm4I&#PZiSWh1=3AZ=()%_8pJ7JJ}1z57$cXnPd z;x1xcoQ^~xxBB1%N+#u!#P7c0(T2$de?Rkkt2uYxrHK7KS>_gPsXb_KI6 zPMZmdtTf~sx-{Sw%R*_WKvrzeIXJ48gVG5-Zio_#%f+vpREz=cU2Az^wBH}uOM3qmk@e@F|EsgL{|$vj3jGCix(}>}1y)Fl zeql8|dG*F+*6zmQRE-&}W=6~SmAZ1uVaV5B6UxB4MKx&u=-ujYaC)cFGI!oWxaPl? zkXK$5CX6vaRe20cJH8Mc9k3K!sEM%IfQ_{r-=OVz2?I;%(UFnMq}9HM8BAn_iqN?w zTy*ALyZLQM#0L08qh(aknzp5|SRE>eCF?zHOIfMI(6v-fpFNk4 zHTPM{U5~npSkzY<@`naPu!)Ix_CoW>um|%UMpl2Og0RP4SkLl)Utj7k{ z^CzDkXoddx=`sKA_YbV+0Z#W$3I9U}YwI4dHYdyMZf+xV|LS!}xR))2eDIMnC|6^JDO&xzApzWYdfz}#YpL8 z0bd&Ju4I-Z70fIutK1U~SfnHMH4mHYwcvg}ZymH~zxUx@wJ^Ye$Wk<`cf@fs=+@zB zp%sHnzYmOCen_Z`Q?aZ#q>-gu78`Vsfp4h8FyT_2A-Q#aj@Cj3-@R2Q3H4!8T3B(C za$wfgKVlrqr#O6zQ^I$@d?vG={qpnU{>|?nSWi54wUK$h$E&S}&ImuVu(m6++~4e0 z7v;FX+H85I&N5v2Tp0u!Ua%tcqZsWXq}_gt1Hub(>H@^VeT`8KLzRW7139ga$Xc`W z*)6QqfDfytsjC&w3U45-kY}LaLdbpW$U=J#kkvC?wNHID9urvP6dbD&UYNM*peY)> z;v=|)5PZ(4d(mkLU+m3E4OO`3q!lW|Lj%*xm>d zvwwd0*ZW8RgMR>p_0_ehg4vhmU~N4(rXh@!+1{=!rq|ku-O5;G-6^wRxWACX!iy7W zEER>4SlXO=%a)wGWV%kudT^~>gljNs-B_=@9vs>W7+D6YhC?f4ux?;lG172@X;@1D z%N`azd$cFEMOSA#8MFc)yS}9jH1edeT5!q2(H3j)#zQ-ibJai56|+mJjaYI zLsX~{p|h$ZXEJ{yX;qh(WrZOK<>N-%r3O-s*eR9==cSwI&JtX9Z4 zDCCY8a~E0cf9~}svp(uWj`5@7VpZ7V0pY?5!P%gBj8H&mq)+XFnulXy)Q>nv}f4 z;)%6pG&Dk<0XcV_4$8&C)V{^aVZ}%A3dP_JvJ6hFB|WU339o$+3ks{_0!wvat)@U$ z=XBKT=!B5zEcjWST9LcbveNHR%qqM_GU2`SPRiOakHkt- zmWUjh#rS)E;GKo+-JzW|KcK#fqN*D_toc#gtb>}6aV+kr@ab4b{n=#FJ6iU8FsN+qbst9Cf$6Tq@8c| za+H|GUsawiN?f_Xs{7V2q_I#DsxE}YBAHS)7Y3!Jp$#c8m3uJDeXKkWo4^iCaDi7C zKbpJs4qCP5a}LQejRpUmW){>`i|2%`UN58^dRklv=iNJ@&yR6n*p%aLDr=||Db1{7 zrW>fWj+3`TADT6kx(dkR*cn<`4yoW}l~xvQtSc!jhOQ}p&)$r)gN^V8ur#dU`ughn76sugJuK~czA$|S zU|mgTdWyN8q zdK0+j9aV&K+YM6osMiJ9RkKo%ygH=Dva+zidjuYGDy*}3N+^xhC9+a~pIKcg*QzLW zk&Gpez-JZApzhNwt5SJwWJp8UJ^r4^t2W>G@9_UXKgp_(z@o@Yq4lV5thbHhBxAkusudJ84F3{(JD3*b7M(ZQNyziJQMYT>bmKm&uM3$zt3 zxFuRSEGq|@BpvVzn#*z3Y;efNS4uQ6 zFM5lRJM~qv)?As3DSWH-TFdEm$!bTWf&P_1wYu^4!G)g@EQEoQEER5t5Ij}#bHg%Iuy2;Cbd^U)cnj*MT5O{bULT3f|ANTjFqV~Cxf`E zGuJ@#DkHJdqRVj&nPTsZIN z&Phc-Mdv+<%j{$7UE{f7zrXmVru&cE7m@Ykx2&Gf94wbvyl?->S@m>dYwEU7?6a>O z`dF{szuH*z3}yjUVK6ch4cB37stK$simVVBz4Ezz)6#X1V;Ur_*3wtZV68-~RfSf6 zUtq#0dvnH%0TK=JuM`{|@yUeME5p)qJgSs~a}6H7+Cz?B15-5{`h z0a%L?i@ncQDzZffcTZ#;wb)K*ylSyQ2k}w1LVK>EFJ8@17ShXV=&%sMcl3{g{)8#{*5m#wd9!>c*RpfNvsnG)-^}U=)&>f?Zx!&VtR1_Y$b8;gek0{ zQVl_0MPfl^ErQqXI?FD&Sz|Rm-z=9BSE>uGCj2*hXUy72wnX7KV_ z_Ga_#sdGM$4cG`X4>4(gTrnrNnsSkyvM}sYeMJG#d98y`hYA3YQ&O)sWL%1+znV&^$3AAuP zIHZ47_IOfAnWf%)kDDoKfmq#RLo~vq+N*O*C#&KnXlN{`DqL+s7Gk1UG6G_$%vwxX z7ZOxVJTT~Bxp#V5u_7$mkJfRaO^mecyZTqSzLVpPcxA)f|DqmzeOFGDSD!5{dh+99 zueF{J>YAK;^{=9j^|StxDoa zzvUjr7DJ?9RxY%H5AOoh75(-AMU{uUpzKn935=uwl#AAk7xKZykd$&Tu~--4wI8LB zPw9nZNAc5yp;+vR0P^+&kjWe_v+2EO7RxuzeBu<)rR5;%LJLQD&0zspdVzWh&Y}&L z#kx?tT_lz|S{y=ZQ{H)4Senw}08%d2>Dj?y*&G&ff&&;epZ_UR3jxyks3%YPnpd{m zo?&;S;K42JhpyOFxFDxy``H+;h&W8XBi~^0tnVtZzQ@$NPEKY#E5;fMG)Kp&$v=5n z*Rdmd_pY%15&G(1uliT|l)IBw#@#&kkI{7hoM3gLDXf;lvQR@xjNWUa;ofHUF@vS6 zy<48R)C0E&6hHI4Zmrcs*>lQV%}apa%J$;*kc{QBw^tDF7-pv5s03QenYy-#5S# zy>(E>{V+9!RgV$J0l zQCOWswSG)m#luAYh=7VtzO!nOq;vehA@8nzI{naL{fCe{mQbjt1>arj!Hc0yb^E3 zZXGkR^t^D4;aFUi3rY#Fx^`e_DhpGG3T-sRaKGrgw|WWzttR8JRWED%!pi#k4y?DN z)v1j|{>7P~b>*C%oDx*+1eWF7liO~i`!qDVRu2oLTE`Q@*hF}*HQ^WSCDc`fk5pDM zFS-+4ZMU540eo?2AFL}5YIrD)3}e}hQS2f-LSR8%G2}i0wbZ`id0`{5_G1Cov>Jm} zhl;qW*{8#zP;}K)Uhx=@>>SbY* zyF3?a38=L3`9`?rD7SKXBjobTyL-UQ0ZyJSmW!nzzl0JVRapy1exo$9NR>B8r8I*z z-!z&m{+*SLdhd*7C<9Y!)O8Z%a5CuPc_L?FvCgyPRnSkIM%^j3LZHl|>mFdp6Ij7Y z!=WbL1y%I1F6QMBbCV5Ls7g7Z$9B{#LsO_uldB`o;SZ5%a&nGLYBz^sb1l4oN9 z*DTI%;LGCog|2slcXggZ@MwrwaL!}XVK|93p<3^zw<5CusXugeuhB{_@A&w;A0J+} zoN}sM3AXYq)$f&!W8k)euEoNbv^{xUdl-i^N8;dEd zP_kJE-ql>81$C7~)`$(!U=(|G*c5#^!axVOSgZjdt3a%oHtLAZ(zN?{)*W}p7=;BZ z3r^PL`**B-QxmH|VJO_fS>f+RG_$U++tz!cRgqeCsI<0h+Id%4Z^f&hhctZp1+kQAA|HyEd23TVlt>dJjrfb|>8LMaI4QH?lp z6c&7jgTpH(8%i~@1YZm^Xmyy2)XD~Vo|(rUHd&d65>`CU^XXaT;8fr}B$X&HPh#C{ zO5ls~iid{+s5_@-ySL-O4UXb?n8ZH0*xujg{!>8}ZQ$t$o z)_lW4F={y*-pBPguETNeAeWEMd*8whP+O2$AQuWlo)S6?dLQDAT3H%xz@%hWiHx}i z_21>I)C6hoQiPT8siek&{VvqHy@hwhMx7plSQ^OESi?+sbvdfWmr@PF$f_{2f%ZEF zzMt!qj>Q5k&>+@~GV2^Mh6zTIwnjL}-Pae!d)&zMqQ8*-6@%})cZKyfz)wfmQ3Yd?K#(TI+z(`{=r#VN%0=6TkYx%qXm@$FsC4M|rhXV2QGN z!U3W7Z z@=XBF=xGIaV-}V`Dri+G!UPF;M|`zpmW!cHTp_IbDva#C3M^;kp_X;2;U*Q0KEbQg zZ+!@00b_(&;Bg^_HF&Bn&xk0GD3Ndgs64e)$2s-iQ8%(K43>KD1Uovs7^(}e0*ja` zgFPs)0-r0i76Mt9HU|sAcd9Ko?+{q?8hy~*RG|}Ra9lWM!;V}9P)xteLnqFN#Jb&& znR8fl>0i;f(o7bOcX@KnY71D=#hS#qei-RzyegW}$zPj!@9zY81AX=5pwUmiEDBFS ztQxgjn*t zekd4lXL8gu7ILG-#Co3hP*;qMGJ)0Afmj&ZC)BFQtizOsdu0V7szABuQdRIuio@k{ zDR%=tv!&F8Ccv+flfHAMiN#SBnx%bVXAQhDJKRwcKxrSpxCjQr)7Ki4S zxhCo0Tqpgd({RJE@1o2~4~Q(Q3|R_7ZSl--4oNlCR%n{;@UWO{kP2}XSQZBM=v?+V zeU!k0i#4L3g_KqafyI0S2EEUORg0P2NmW>3D>N5WRGdWG)uqt4*gy$(nVr?0O`^gQ zT%kD!XM^Wvy+>ftxthSoN+K&|-yd4G`xe6+-Wl>H#A*wyProFVDy-8F>a{c4{^{fA zlh3W5oV18=9qo3TF{;F3rs0h8D)!}2W9gXDv&TkW>ElU>CA|9j#BI;dCJP$LduEC%J8y*+zKUZ=@kzM{|g)5-8iT#hf0uk zmD=w-7^IuU+ED)a8#f@XTwi5Zn?sGnavi&C8TBuJ10Of1h+gR@6pDW*sZ>TqRQWJ$L>7gVbrmv_rL2M}k1{aWaKC`n5;jB%*4>aKm_3ajiFoV_|#)kVR&7*$r)d zg)rMWZwAZYsJ6}vv)@f(740EeEhFm>43X5eh3~+6D`34W2|xWsQFz)k>$G=5_Ykre)Hw~0-+(Mmlo55M6B-0p$TAqR7#n?fxaQzK4409j zFbXUX3!2I(rLoaH_vakDCbhbgbD@-F97rsI7~)roEITHwMP6ZY1HuizAVGo(e+?ZuR>u3`R;0o&GgdmK2WO{h+Y4 zNL0fe63a1z#f@LwTtA-^SaWsW%OPiC>5(B77Og8d??jfiMEBUOQ(kfvSdDN)%|Y)y zR)r&dz|cZ;6rDOck+cG^IMPq>#ZH|CmL@IqjF6T)F02i?SEneN?@7zWD*n&j`Lr~$ zZBe}Yii6h*jkBg9Gc(A*pdm3}KM*Pg4>S}R2$B0H3Iz||$k`iPgGWYw04Jt0GZErP zynC&+*7mpAg>fhm*vqwVcG=pSpZv-UozCe)rM9CC!>@WaD;|3m}lB7ffbe>^P7 ztF4_Ed()f5s@t9$9fTBEo^($Uclhn5uCA!CVnYsh^?FdieQ(c~2%j*<-M%o#U71nT zhD^B|t2ni9&2GYl6qX4qDJ;C#EDF~rlvhfO+UJT(gv02&o7yr##iFo6ZHU)$Xuu+} z>}GOk?+M&10~h!-5vjnZo?Gn%76PLsfWLX) zFN#NyNoWI!P$~kW{7Vp5{UgCNwHK;22Wx~V041*qAM~#FXYEc{5MfNcmj#Q$K4lgb z4F|{S)REFUle~fve~diVKrvD~9anY?W>_D*7!JiNEERS-Y%h$T0v0!VJEwcq)(cnc z-T8OQHZb@;8aH!U<7PiJpfy@(hQkL#-aX*{j~9bRKmV!5N?p&g+qb@KD6B8d-JXf8 zYafa1DJ-Q$wdX_(VMT4lc>A|h4?ZD+_4NJcx5fA5xZgjI?PBb6+^MogQdn)~u&_qR zl|t_L9L;ukS1UU0D@PSwETU>dVCgQA%D&3U{Lti8Wde(Lt;6bY4pQ~(aN~*wJQ5Bv zuviZ!+g%3DJr^d_Z5qZ zI;z%9O)D$xZ~TG%{m89^F)Ro+e;bHo|3TMhfi%Ql6u*{iGGHZjrFzh#44jIkOhdOw zUON(4!WaWtS}5#8T|s7H>%vPRt1Ojs0InFzg2FmxvH|!4u`10_Hid<_d*@=3ffW;2yDSO!7#P)2r?1fNym)$C zJS{K?>j{Ads|OXs(gZBc7e!fUs!E~JCBU_mcSZZklvO&^PN?NUqgKTu$}5~ErnW#U zd(Z8d2vx{rkyew#`Jr$HQcdcrFl)ir%E|#xS$6OP6(KHfO*T2KicIAp0t}fIf}!}A zokD=X${?)n?1%DTCsc{80Ac}Jb{4j7h%OmjMfV8BBSqH+t|C~9t}`eo9=a)|q7K`S z1?GlSt7}G;o!vs^Y4HC7bQWZ_6#JbI#WZG^gH zedt9ZKe$8)Oc7XTB$hT?HH|fxon8#kSU507ofB0vJI`ddQ)HcMBi*((Bf%K$j%vY^ z7<)fyj~!SIQoRz(60t^$kLKsUD&+pkP???ATL`y4r+EAJZxLC{U@_jVDef!@uhWdt zt6d-D&Q0mBqQH`aWz_n~QSJ{hFZz>a`{NS}LjDYT@X$QgLW-f)S5X z%WoyWxH5PMv4y;QR9JQxh74paLsyn(pw$%BAugb*a&{fszwjwx1!mol4RW-Elj5i^ zu*3&bk2eTBQF!f#8bSNr7ravJw5y-(z7T2C6o!W^3$ZR#WjdvY75r(~FADF?@#aGO z?Y$+Z@5Bli;!tqMLWSRH!Ef*q>Wp}I*Pa3)Rm~E(E_Z#Eh`T5cO{O-W| z^cJvwLDqH}fVHhf!fi0ihstav1M92r>?Lt^Evx-%R}u@_N)fE9=5XXaZzCkK9=<8i z-~lXZtowWJ>-9W-;;yO2t@VARmCkF*toC{|Uea)1dkV{hl|FGsWOTUV%R#mBMZ!rU z73xFM3b%$S16ixr1Ft5i10k_`S`uuz-lDZt%G07>y0aH%D5K}msEMyVhd zYnmCBj9pXQQ_S$+d2qiy*8*a=*$`7f^ax2}g?{7P(OKW92D`5$97vun-KYkuqK{Qm zvRf;!en`@akiygkCK&qURS0L4S!Y}mWUDj9Rq*T;gjJaomaYsT4nv)zz7s z?#F}|J@*RZk~P2q%o4CbD&T2G*WK#EW3(2|)S%hYHq5q@mM@z83NSOvwE$J}MV<9A>cQRSck3*hQ|(=&1n1hAMz7b_;Rjs&f;j2C@a zS!V~wDhLHG-X4_5V3mqF92|&U$LfN{PCB!TII>}Y?L}sYI1o{t8C`d+7h=e}cy->6 zdsRmNy&XkXB-ZGAy;Qg{Hu*kYd@$slf%WOnfEDL6#CDy=fYGhm!$Kn=0uI+{p^$si zYp~2UD?+(fSDZ6?rB1@ShtL$(!(Ou{jQuzZ@5=Gbp6{QZ6v8rceSc&WOS~ekuu8aI zpTKnYwLvu!sv`#pQo(AbuVuyas$yYiA3zgMWYmN&lU4Jo>aqT-s=w-|BHxJZZ}$#c_NMNq$?=N=HwA_(Yg zP5EFNvkZBo81!dhx^bSS+t*&P5S()Ql|R@JaPeIDuaAO?&yc?|E){|t|F-U7;af%g zKPdbgg@%llkyuhyTtTFJrRL|N@MwdoLcK0a%^@YQus<{sS;xL)h-AY6s>!TjOOEj>8tzYA zBP6S|LTJ_C6Nb0bxO%4TK6>^xLcU>H!E9f%iO@>I6SY0ByeLdb280<9c#ouF)P1?C zP4_v}6~0Vf^;#9(cf0CIYe88}_?5M=fLQ$~DYLBB`@y2H{Gmb+yb8osW{|pV@iOPF z5vs5QH`7}&%YYT^Da@;kLIn4y674dV#DXs`Lg|5s1$pG2Qcwf5lA29ay`{jqMc2_) zBk7l)3619=B;GesjhaKYlLyEj7J)pThss6*qZ)2Iaq9bzS`J$ z0t#zyx3N)<`&Zu{HszIzD|Qi%L9AzGu+TyH?CzB>5sstI!cyUqjfCqss)4rE%DE+N z#iCG)g!cYV1z@dKRuO_<6T%7_i>ri&EIt9cz%0~+bDevK^LaIIkzI&5Ac-}vg;gd} z=>V?cO`hFlEC`KNceJmvJlv602B}1G>zL$7S zv+Gx8bsatWLqby6{J~JWVqw!c^TkU46Lj1HColx}vh+SW3JGDNRvCfS=b#1*Y|y(< z`bvrm7iC-}WJ##Z`$4JgC;%_-(K&#=g1}PLVRnj``-KTByB^GFXdOGWW*ueTDYi}< zE>;J_NIP{!s5QfJvoahBTRuB-bYCwQelX;{OTxDYjqYrY#DaaLQgA!%oB9RX3K^{H zv=w0txN8KK8lNMwzV2OV%BaTnU2)%u2ZkArk(>lqRECv5oq?D4C0e2v%f zW~pkBFJ7!v8b;H-Bl~LUmV5j#UG=+X8)hqCADn|+Jv-*&7Q|MsqHzW9sw%5F{dZP| ztOv869jphNw90VwZfOD#S7{Ht56&4j4Qd zUU=?>`k#y9fNjyVsESJlNzbUSG}Z5b_&V^(e%wVzJvv+;G(J^><7#j)Lyyi3VoR;i zs1CVHg*4W17~6D)iC7&uS)FEG81475PkV3dsS~}dF>`?*!1`+xmTxBero7tb+Mov- zwxhuM!Zkvl)4)^%+;+}rh+9uwe|2rep?$F)R0d1?koFba z_r*OG)*tMhL2DaX7KPh3UUWJTvNH`@YT<>NRuNes8vXce`4Qr&V8>+PQuK}y>ZEURgz89n|z#m?s@l_(!y54x!gOz+t^=Wo3n;P<9qNgpgO)*KGn`*=1kj0hBUq z0bXKM0&oFR><5-*NvFLm@yPu;d1*omsLIkhs|TqmtGcdPE#?_M<%ML{1!_jsgEF#U zVnKc>l$D1?DvNa@6__0RV9m$J9{a&S2jd%mg%JMF*@O?`@k8b^MrkVos03i=K zghW{818~>~U>S%Ka9m{DSK%`o=&l1?4x}Q^nW1OpR+hZ>F%P4Vg@p)~)RkchldwkB zF-@(bqhoB+VY|>6b;7MWt#2+|n*_r|tZQ`(najGK4rlLYtO{LYae%V470;<)oHT~t zho`5($C`PUFbq%*la%K#7~jm@E0u#vi(aWF45860 z1{$zj3RkEHZ#+6meMMr~`mw78J=Wlf27B@R2_~@MwqsA>15K=XR9F7k$5oG8T(_>) z3q#XXN@5wZM62@!MArJSWrxs&RTDgST#YPvvg076eu* zOko-54GXIt6g4gtgeJ4>pRd8I&e2aJudqQH7MH{p3qydbR_!Qe<#7?Qa`g%G-m4>( zL+OdK$^x14E`3#Od0IslO{jD6B5URecn`o6SVMYOap=s(& zo|l7rQD5npoY!%NyRF!p^H!U3Udz4G$zG6IC<$e`-{9xwf=NOb3o6T=TKqx6 z=AnH@Vwn~Lw6Lb<4N1i}3PTi#rH32JRHdR-fVH8D^vdxew?YsfZDqhAg{hSq$Z}fn zIsN#e$a6=OdWM2m<~>9QmaHt&B#(iuAg=IJ1b%rQ)YVipzM{g)Ag+j`fWac`(`j6U z;41%r3gsMhp)k$2prxWvKSdVuSe2(nO;ow7rG?dDF*;J0un5MLTkyvmJvutpnO{m| zjWi<*;Rdw}udi7Wf>)tcIGqL`%hlDi^W1&rd(30a0a4dKg5?L(yM^^pru*I90Y#P{pGx1# zEi64SZjivlYT5-T(bvrb@Pg&XB1VHFC-j#rgNkw$IB9nc!( z$MBUA>+^er8o0Mm{uN8Y2~YkqXd&1DD+{~|J{B0p0O`~V!{LW0v!acq3@N465V*qi zl>;0cSm7)%VC#h?&%>*qo{YizaW%N}^UmJSzS()7ZNXPNVa_O+<)=>UsUCcD<)%B` ztI#35^s4ZNki|J_ZxI@+>{GC?z^hwZF`;2|_wnxb*Nq0b+wypNOFg9&7VP&` zChMO-Q0z+-j5D_duOak8HWNQWJ=ptNS5c%P{@j84{U{#61C(E8e&MEU}g=Mq@o zPDcI~R!lN*3*o+kqq@3bSbMvE@`T(guL!BIF5d)&C4r@ikjA_0D^3|zqT!AwJp)!+ zZ^^8U6xQZ;xmjYU%p+>Q$0ZD`&T)U7hxpY>$%dYF6_&0h?5=;WrLfw?LMGP2qYkF7 z7ACM3ZDRs!L7N>UYk@7j{c4i#`eF(T_Epo!!h)gI3;-$pq@Yq+H-oY+nJcZ+5z!@H zr6d((6^lhfPFld+N+GQB+E$i;_~%c>1yb2Ra0;r-MHl;tL{|~?R<>nh<-usrFN(fp zm34O4Z=FO610wMEc|e#b<|SmVzj79NBun`#`fsXad%#jPD5X_}y@maJ!+@BQ?e6<^ zs$jua*q3vpU<1ec9m9Ip(W>kd!h4@gPDYeeoI}bPq=&%OBy84!@&4fh#MTFHEToe) z>(UKRcInLLm_sUH0aA)&+4a@;LcdHLeWw24H-kpMZ?*e&oc(ylGbC0_Vfh%WJ-4r} z{7|nemsqa}E&1)3HcDRow~I5#zdAr!_%e|v=cN|k}RO47R)iA9<*u@ zN=vMQ*s^>11!^jR#`*$jh2qe@K|CvwvSJoXVF%z!W>#GZSn%GZxR`FxnzLz`TA`Ry zQ@Nc*OJ2Sf7~+D5rYQhENwjHhzaoYSDiJcAk|6JisyVHf(& zH#p{A>T!VIMU1;( zVEy#uaIf#1?)$W{_7rMhpkdeBgZsPM^~_ONp&Z=3irqnOA@sB9-Nd@ojvUSG^Ta4j zciw$hj_-H&vB=Cd*bhVQbG`2F=FDJWPhl6tVqMseU#-Ead#Ech%D%bxxci!=U>iGz ztF?Hwz~<+*-wj*|khMs32fI)Nsu zqv#aEvN{~jo_JaO`qR*@ECw9pWcenY7nnSs!ulV_r@GZH?>$Z!rHiE)7Ea2Mz=}2D z8)p^__cu(9UNO+{T3Jy(c!ThUd4>a=JaOY=+&2!b4HXt#Ec6FEeYIQyUn~RXkD4dL zg3x&tv2`y_xqo#JVYTW!EK^mjE%pm-*;!LuErQTmILlBGuA#DEwL7HPE9@15UJiaK z?GZO}3wL9gm47K)hqA8_9UYYZT$fzzUDqWfS1l)=j(g4;5n@Z+Dsx&~Fy<9`K*b1r zA!izbS`IF0EQeTh+dE|O?kMY3iiO7`x}86cE()|P{+<6dw%h<>0v0Pw!cZd{iXz1I z<-6DTqV{QiS*9I?_|ufU8lwnAB5Tl%n=x&L;m8>G{%6RLj;da^VN@Oa4nx$1#{?Av zS&&;4SncFw!Xs8Ehf}xRxxPQ_GViffh;=ptxCpIYSvc$VM1P{b0;y)I3F*4Oz~q@S zqvX}r7Q%1Ork8uQw-@$32WIWQ>g~)4GyCF>93|ZO3cH>)s^L-%LM;b6dV)!;Zcom} zZX3<*qlb0JDejx)tx@YyvI<8}Y&r`|y9a}|dgzd4A`7f?i50JVNvsxzdx(*)*FY7T zg&@~LM!ccQZlnHN zbMGsL-~zW+Qd>b>wY1&GD+^}fjBg078nikHv?TxN!lBk2cMyzQ6sq~To}8$qa3*ZcB(W&A zurmd4btZ{53cx~_j#de&vZ%0*jwG-SZE&)>q5U|N%sPt13h#4#pIcdI*83MT;a`FE zVj1`0P?_KU*8rtJTEE=B-Mub1I*2vwn2EI;n{pNlp#4U z@aJ{p)xCK2H)}#=8t%D1c(qmIGd*@tYb#d$y4zYePUp8rWC2#h(}wlnrUxxJSI|%d z)moj;;1ogC>N=<84l65fX=9DswF*T7swj+H1vs@Lz9g-}ZHou^4)^*1TB}v;(rE*! z>ZD<9*pOH5VPz{0)vBeiKr1o}zozoC+|L59;M12PLH78Fy2?@J7`y10*1gkCiJ?m5 z6N`4Gy^d=WS(%by7u`yw{pe;DdIkZj%%If>S`B-+&BIE%OhbA6d30Rc9KX`1HgG?k zN79NN&v-Vo-a;xZmV=y}j4gGPZqORxrF9x!s>yI7NTD)3gyDW_K~g~rw!0?IoMKn# zFGHDi?t_yxdFE8k`zuUd23U`H^>j4yo^|BB*|pGU-06AWaRnD^p-h7W*20zuzrnv+ z#EiRUVcBRIg&K@k*FM7i+K6SNW#nC9(^Qb^UKuR1ib>J!ufcI=RUu^7CN30iq_9{I zYMt;0%&R%G4B-|~f`3ILE6@KsXC5mL49j!qDygk-K^u$A!?j2u001BWNkl!S`u4`zthAbwEW8!5V>$@Ni86(BFdTy#UUhC!=$N_TG7kG zFQGmx89G%!tLJBB19g@5_@#ttuXIcY;wwt8big_D#MFpwe~0XXoHFyPq_7%(GVVht zWz|?73lV-*iwOxv*S+@jLG|iDVAUhfV3ihmS4nv6%)*@H*~k2R|i|^DC97iT)NaUt;MkohuWUvP%#HTM6AKMtN_dT1`tgd!%il`eoA1s_#%I}caw}Ge^06YPI(}VT7^u=tdqodS*{?Jb z&P;s)&cqh0KXbE6)~iiTrG=M;8yXt$jcP(J6~+Ws8SVEv`tP4dzEh$0g|?nTWZ-9L zGNizogzGwBOUQzi1(9_&QB5e<{gU&sxMJuY)}<{MN>)ve;$$oog^!JQ;EHK1oA&O0 z)+hgXq33xixaS@uOhFyM1!vqMp{W%tf0)m&i)UFA3P z9O!bP6)M2_4P@3B;wpRtTT5Fl3`}Zs6Iig|b1|#Ep}0b@G)S!CrUkZ82=bipTZxC& zsx_sB>xTHE1s^0;Q?07Nr>cRxs=~8uRl$;PybvU>vZU$gL=!&im5HhO^r-0~pvou8 z>!Q0zoj*f#bt{f(zpP9n%7`NuY^Ly79WuC(#rUYr^UE||=D3cjti){h&v9tO$OKiH z$a`1APCY8wKv?&T_faemxjZ-{sU`tfa<6bq|2i9;*pxf}q~(4UL>5ZItL^tKMb_2!*Pt4FxHEwj znDx-}uZ&!9vF=DLxL8;dG+wPOyP*`~57DZuh600Dw z#>--SvnHs1q{bkcce5G}7bSwiX70I9k(b(QJt`%P%5 zsul@Tce9cJsBTOa?(AMu{UEBo`T`+>qhD+0M$uWQDAx2Z`0q39Ru4z(Qdq4d?7kXqu&GUrkuWL5!q z1w1Y3wl7=xR{AcAwrvZLitkmpWres>HCW(%EB8H|SG^+vyed_R0aig*RS;R>Q*k8` zj#l_6{h<59Uv>%~B1&((vc9G$X4?AS0zX2f^Pg}nMoUeSA> zu~Uaf5Lpam-Ha4_pH4N*FW_oD(IC>xIJiNyawn_5LB;7{fCF(QiDjJP2G6|E;-GeU)-)`0u{c!5sAaIa zzrJ>b^^x6!1Xm~uxkk8EDQKYv8Sf90SX&i_Vih}bHs-hkRhu={)f%;-m4RXvuYxLSr+yL5!D1D=-rWn3&FvcfGY!*CmD#-eaYEq;xQ+p)Xua^4GRuB5#k zQ&tt>t16T&rH>`Sg{Kv4tV(jLN@^Hf0a`UJ_qvJtsu8tBsY>KRaO*LxEN$BKO2^*K zFus-bCqoQYAmyBUX&5^l`OmRv*;us*>k70Is1l1e1V%P#Z4=(p)T8dcMrazV^pSoC z;RQe)SO?+AB^HucGqn^>Ag#h@LTYijki;5|qWOMuDL0D&hl#oFL13Zso0`m0=>5?1 zSR&RSNE(=henK@rbDi+-*OKss4Xk$xk-ixuuuNj@y@?~-_myT4syJ3g3xxY|>xo62 ziOkOjBbH?ve*bpOol~_FA?)@)D77H4?qgSuh1`{EfWiW+;J4o!vaBHNm4y#13xzBQ zEUK%Gh{gCQ%E1jp)<$^3jp{;g`mwrxNQTimDh>9hQs|XcSgu7L!<35b9q+i_yN) z@?d7ts$sR5N;-i|Y0}@gUXFWW#Io)}ylKI6)92{7D?6$bR`{N9g>a^C?OJ$7g*B1) zjs?Oq3z906H8oPv$kN`0V3Ln}KRk@nvi?O}eS(#B&Ty9Hu)@v9S75!2y7F|xb4`R6 z74`7d8z+{xVLtnm5)4YjdlLL3260aB_A=PtBv zM6EdsLA>UAyY=z4Z?LP@2Xa5gz}7YmXK-utEJ8>p_7#+u5(;wVzZNWm#jH-yta?47Y|8|fCs zag2(1LqeKYJP>h{LPa1va14>A(QXF88iBgSjVzeIK+P0WNtFYSasATBdCic>lJzI< zJ?Gr}&DhJ9>&lWf8p%$|ALpKX?)_fd4`c6sl1}Ova!b~QR{K2@J?KfS`;b<;ifbQz(R0G9!Z_?j=Ft1cm_98yHr5<&}qdb=dY$|SgGzRy?r%B#d2u*xX0 znsBx#tx6YIWw45U#0G7{aWl5!kf~B)tCY|JsmAt^Y%1}~b)B$j&JWt-fn4PDHPD!+xP>-#?srlaRR5#a6?Il_Px@Kz#p98O0&{F-t9eGvmCaY#+%5QQe%q)%vy9_!jWh|xk!@8~3!bsL3vkT|W2$9$?E{C*m))uTU} z#6O+5Xj9LS1)<&1#;P@!Lvh9Xny4yxO3)hm>XGN1xC6 z1X(p4KA=`OSVP!WXR_X}Kbe43@q$q8!T2KNRLU{*qCeR41*1L27*1jz@=2sd6R*09u=I2F#*d!3ihA&E zQdpaqA>^J0%BwK2Tw!VCnVmwDRR=~ITv>Uq5DOXzD{8Et%DV3q6;&LIMd8+N;IzBA zGES))MD~irlE&im(t)MgPj}18Kt*ZX)E?EUu08%A5<#YXoqbk>n05jEP zx@zfm{Cw4TOzZa6lvieQt6WiPS*h3%TCT6$%PN!VD$|2*R!K+8Kgy2hJv?~)f?oX8 znKo_3m%l3*?|+h5R(6F}@fcg(m4Y=ZMSA!J{<9(pFAq-fcPjwSr>A&I9~V+tf!sGX%$wl6<0?ceHBMf zoTw7idWMr14{E`bzT)$0vG5JUk(V45?J4~ zRVG+F}ELMP(L=&lHj50{&_&Q%wXXP%qmVC?Ov+*hq(<@(5Xf?OE%P6nl#+MnW z)fljvrVW(_swA}%u?$U2ml9V~zm{dltx~`WF4clmE4o@U9;Oz5U5H*~TQAmJB;Vy+ znN-&#u%)J>O2}gEWhbTur#cR(@XcO@4@N7IHTHs#RiZt|bl}%)8;&D9%GxlzE4x#` zVcq|uZ$eAR8WL9@*)tq+hl3IhA4WqKh8o*}m8EfLm|2omJ`BxmGXt*-DX_$=&V-J= zzm8FzG!K12a9uo?gikz?^YW3xBD8w#LC+q2O1Qz4%uNJSE za*u;@lxUE+`k|}uz>>ydV)Ow2>W-07L`OC5%or9FS5j9$eKH3&)(*qYdp&lFixOM1 z+znYbu-u`r@V&rw!*8~G7KW+{m*5oNz$ttOPF3I)F0`!t$uB9WNGxL+ZFlFCV@mgi zDtqN~Q&eOZO2TC`Z<=|=;?Ri253CFIz&qqtCJUZ6SD7rXnw`YD>^!FFB6|xEN(fui zau>QDJol#pBDgxvv;U z9G+dl2~`zj7Aiz-##+1eo=mL1`&fOY-#@O^Cgk8V1eVDwqtz(7g@!HU-R+AJ2X#zf zjTj`Q1%K^lLHnXCMI5fRD$CVXtj6*W?)?rpR4q>m1ZdOA1 ziMqS3Yoe|qX$3}^o`TVi6=$NEZi_l*h-RZ}fUwtnMRTBQu2d>uI zGcz2<2(%XZjr_y#Y=j#!%N`%T8?w&XD}>t85VSTXYr2q`tn2Q2tdw!U<(=YKjJ^AY z_lsv>J!whUU4PY!eSJrMLXKFaR^d^*9C>lvWz|Ac&+VSkH|+{{2&}gr!AgevTW%Ot zUQ{wG@}lmz-~Io9D~|M{*kV0s`pUk)4?Am@dW3s0Ymcu?Sp}`OdIP9#)Eh)Kc*FW| z#$dw?q?%pA;hKS0Uukg7lqH=l$t%NDh1E0QRb}9Uu)3tWk{NF|#;as=8GP(};E1)N zea^+FrQ9sL%kpfMua+PderF#c#2VIzkXspzc;>W>PZ@EQ&8e`I+@ioz!PttcRr0V% zE)Q!>llDseL=h`mhyg4mwura7L$FvWKWzi4cCiYvPJ*hAmCl?5qNm=fuGE*r+z=SW z?0q3n)yQFC&?sb9!Gk#5TvyV{g%&efzx}4zJ0kDyVf9^leFV6MXJ;HLJfp~h%HoKQ zDXQUjuFB$eEUh6OsaJ@UgF)(FI{NEer6DC&Oci2QN5$YkN=uFwl+}AJ#zG+LnJP~N zte1SWBZMjDp7Nr-TSrYjVG{v+$qqY z2B9mgZ}Q#Q9sI_HqwZh1$Z}FaSczJ!2Y1S2p&r~4RfLqGNixf5L>_GkF;`c3H=c=C ztOsFS0aqdxOG0!6Q6xfbRTb($yBM*m+`g&uc||8nS9)C})ROoLIi(*kisA}-D+9Z7 zb_+B6!bp`jjVUWgD+7|DtISKfTPzFbWK^c6VbhqzdSt+d!xct+tFZ8)h~b`TYkHOC z1B8w+|U51-uMlBZji_G4v87e2Q9 zwd<1yJZW_>IMoJa_*ux0LR-E2{5h>{c>mcK{5>nICm~ki)yu!`MeZG?g9v@C%<)kh zbmwW$aR%W+n2L7|JxgLau22hZu9Uyhnug!ooidxv!-1TQ1QtIY?vxij=n}zp-tHJ} zU<6CNx|fGVg>`?=*5LoPAQP|dS*c05cX{P+-Yope67cJ#mx`zhD-%u7W1tjb4^UNA zrSh*bT+M;3D$ku&+e>k4JA<%VF5^1qUG8pHCUk9=;MNN4YQU~c7(*@CKy1yk5(s0{ zuyk$JkVv>OV8Ne%^k`NssX84*39bN?=S#~LUDK}r6%}I?f?g&T(`j2tma?$Ov7&ZP zB^~AvD+;%=c;rv5%&GfWik5PW8v%zg&Rzt=G!RWIE82nV6JkL_-{Yf!D!ub==tdUE z^eLU9Ll0|&YqSi9!x0ZH9O85exbFi-8%8>?a3t4V`x|gYI4OHa7BXHO*Kom*uVv7muMOZh7tLii_pXYAU>mPT~NnGNj2AlPDY6C2bGYSc_IRlJR-*bym}MtQtqh;7OK z6ZbpkeD}`Cv6tm7NoC2_jK+Dd{Bh2?=ew5&re1^ui<>iW+S!0l~7>Sbq->|H0FQV7F*34V#L)}`Jt*sB09ymu-Is= zTqMa|H-*2nN~k$fde7YB>`xvNESbRy5myzxAvPThxS}n*oC;iK6R|Kju2@MO<5VE1 zu1*-m8IN60O*_i6fT(Flu@&c`k1oC5KyCF8?DuY@8XSkk!l8Uzt$=a^r8RbiAiPyv=o?(f_TdVb~MmCGswS7GDLJxV^z>p6TPl6huX#w+uPDe(lAC0uC$(ZrSn z7CsDK-!vY!UO-gd!dPVwJkqN3yk!twc;#_*u?qIE$+`?^(<)B>ct&3ZyVzV@X}x!! zNK>hAhA1ZPBo;{pb6Ba^p!q?X!YMPXxO)Rcmha{VhDln{Dx!Gh)^Mb891KFMku{XW z>JOo{e6_GYk|(_4ffQH9tI_M@*T-RzkjP^A-UYkVZ+LsC$-+a979w^>_;@@}8vD$Ww_1zst`V&sk{!-e{yufi&!Ho;QIooj_2y8nIE7Fb`y zRE{bQE1AJ}tS@}NXVslcgttnvTv|a{tyOUsswlD6*UQaP{dT}=!6Yj~nnhlD0)Imp zRl1fUr%X&qTfr3;#1t;}l+inhRS-uYRf?bVjIfID`MfMrmLJHkVuIzvBHaSkhqm&n z(-3SWTvbf#gaJI#cY6ki8JZH3ijoUUh9FkWR}vIfp6eFrR$V_7TCq^7;#TDy`SvVg ztH|XabqKq35ud6&wCP)N%r}W>vaZlU_45-QRcLc5-+E8~#{j+>dmW2mmJVH19w{oy!=vbl3)C`om3 z@hTog_=<+`BB-p@K^P}ot=tj%$TPg)DiG_oQCeIXRDz}0{XSAFsVo;tKB)Urk_vN{~=RY0x5|it>7)1gj9hTvx?c8h}+y z_ziIu!}xS&&XDVe4y*#1)jZNmK5ZDNHJ6!Ru{kEqh7TvPpL@Acsu z$c+6tz{F<|Sj1Fdl_qxndKvb_>Wmp>#TJ%-90gjbILgE8ha}nYU^K+Spjuh@hLoMe z>W_FR1y8egVhwnR&Oi+Zq*z@wNZ-C?j@6~edgDulI=Ei#(Pymu0D-mpB(J>M&^~x# zKMWGe55}H57YDt9C4qHu9!ppxmSU>|ChrWhJi!XB20<(8E51HEuAsHvIkbWwjKs1V zh^)K2d-=oV^>PhRA=5Hc5n1-JH0CU_n{1OAt|s=o5UY$`>jikFl)W@ml|>1Ah};T) z$LD53dch2q0b3;iB}^5ww3v}s__I;UDK;tO3Cnp(hiD(0`L;WpfAR;3|IW37IG-zj zPe`$}{^0aV)XPe8Llm1)}YON}7ykY`EwL^L5RU2c?&FRDBE7(Gs#JbA2 zh$U7{eYc2lY-)wlXtg!mchZ%Pe;SF2k;I@MVfY#;(G0LwG?+h#0>$kO=pTD}mKhC5|f2B@`*D>7?o zdMYz%bz?U-fmymT%Yw$r3|ED6_X1rk1nBHh001BWNkldUz0xa4E=LtE zK-(Pf!uRb`mF3Hb^oXB$m+A>wb>ak@E5!;6h-r-DiLTm#<-!Y3VFw*q_{CQ< zgYFDDj2K;EyR5~TX^*@fi@I8RtBJLyqMUJy^s7$uRs~h3Cz}0ZkUt$aC5Rxk{NzNv zr!KwxBn|tHjgN6YEdEbiD7438)EBUFcp1RNk12pP?T}afKGju+MbZu{qP@td70F(kMHl zjl8;7fCWc*?*%OG)Zn0ks%lmU*~4-}xDKm?YsFa0O~x3@P-Pd>RfLrP0Ab*iJ!F{0 z04pPx&Zxjhs7Vl2#iVGz?CFd@c+DiTN+~QzEP!fO2w3)>^OpC8F0I$uobC|p;!hG5 z4SDxLm)eQt+ybCdzoPUYm6aQ{{4Nga>)*}P`zmHH}HRJEGu z{|L^|EA^U9jL>QWOfu^|K?XX(0P;)?M)52*R9qDtD}Z-{I3}sEW=LJd^+CeQydb9v zJB-`$)l)5mS8)`2`-;q~4t@Xj(M_&8>4r9-Ip@j7!>@%u8M)#DrQ(*CW{z|O|-xZnrA*1NN zV)7pL>}$qy@WJQN530<-YWuBbo^Ra-zPoozxRxsvuNY(jScDZQ<<}dEtHlzFgBd;z zPJkEXRe6&sy&|^C#lr01qRiOEk{Qfo56g(CNkmn+%=~WVcb}xXW(1RD-U-6QQe0+CR+hl%($w$PM*M$5v;Br zlU%1ws1=hh?adrFx2d%!gj>LtzKTb|`pnL_{p6Gai#~F!O2b&_;~Qx6)v+kH{P?foP%Q^yDqK~+YDNoHbLXeM)WE`G;js#&1K)5){!pXPJV~e9 z#e^YSS!N1<^P_dJRQL>*KmB_75MG#sHn!Z=!CDhrB$cld(hxGfT8dgA zmf?!b$`%XzPBpbyWRvhNwMK{!bQ~6034SerDG;ml%u0kZa>*r5O8Gyhls#}@`Gc8V zDX$7$XO1R%MLd|7isn!Fp2;4bxV}08uxJDgUnlZ{R8=Xl^(9)vq(!dq%oP^Vl>}?} z;8M3i*5cK#U#j}Qc*LsRMXi*BsSx2i*@R7Pww4^L=pFg5yo6Ona7|rnG5#9E0wS@3 zqN+l*!M-}gv{=~bjM;5xiq)qz?4aT9MN-7>K-3X#jx-QG)P`9?71s=T1_fX>9I4)L z%;iDW-4VQB^$z18^c6_OP5q#)j8{Ew_ul1lA+~RLVFEp^gcvLKltLso_G~@m+=7WB2=){XNY6ZE0r0}Q5$WxmT_7+yo4*BPk+n& zDl7~73$$8?%lfWe8l?vehH&jx5Esa+CCgVCgjP0jSC~O_Ij>AZO-cksy>2R2^ zBSCc}boKkgqoX5}RYwZpG5XB1`#>XwBMn1i*M?s2Slx!#)L1&Af&+$K?Tsa3*)Q5y zTrgzvu7MqsSkK`3)4alK=jG$8gW9?8F+aE;Pn_6q?SmD!l@YC|uP*##dhfUUsS^-Z z=UgNFx!DJ6<;^R^SO-2vcpmq0{}(Hx8YjG6-8Kq~G1lk%unm?lbr)uyqqI`7;d&h^ zSm2h+E3OkRNhU5Y@<#*H7>+MphgJR(jZirS1oL}r48sxn+xm7V8&I1lS+Jjy7)h$@C!k#5xuuQsAr!>oCjLJ#NF>$3@V)%1id zV3nJ{dHve`i!zObh^8MIMvk_rHQ~m^m-Z#|l7}Vxr?q5wtzBVD_UfP}D^yj<`F+dl zz7!Tt%YHwW2VGe8y||&z{v7x~Q&?jhj8uHasSPZ07-`SKSrlQBS&&!5Vd^XF?U7?m zi7V=?fzIXzX#r&jDY4Y5a|Vg^OrGx}*3%m6i-w#xUm8Lpiz|eZS1(^jr!%4}@=9Yy zyCd8^ch@#Km+iSSK4#QF^`AS=m0>SoC@juI_RgGGB>eYZtzyw6vLvicQW~ zhnB+9THynw6h4Qx6U65>XOabYiBvi1MCS)t71t{essO4AIzj%H3tWBzpB!4-Mr^Gm zvf={5YsyODSHW(VSAg>^^Sl7THi{HsPW{>V?GgMs7 zQlzEg_dVy4_F`*_>EP^aKOJbL(0t)Lh^*n@-4I3hK0{OIxSl658wgFc+j*liE zPp#@Myxb9{iY-l>_aCLeer=qh0f>Fi%-KulRq4E932C{ET?$1n7(?%g-i`X&?yGp6k`Eg0g{^YqFm`!UA?sZ52bigYm5=mxbz zvnXr$yh`|e5!SaetPZg{0t=N4o%KP7mFBmfa?6QR)-+s2QG<_Y@D)P(!PXKXH>QWa zx(0l@Xivg4pdpZzDjFcGTwu8id_3~y3hT35K{tdCO0EuO1lca&-&jtX9Gl;3ZN~SV>e7UqyI9i7qOw6_EsNZ98JBpwI%al0yua$XDfxEYmIA zpbFXs&~CCULai*KEPS%LRuQwrt4zl5qP1|?&E@NsEHZNFxt#tACMl8_onY0bzj2`m7shu`)?414eOCd{yU`<|+@ zU=5MMv$O%V4bCc1>)r5~Jm00UzE#iQn-PY>di%8}e3`PVG@-#a%2D8cs`QE#4JYrr zxDu$|Uxvc^iLE#uUHwc_UH;rI7?m4rSB-*Ncb;TDrkc^TLU>FaIgKZzx-v<{8)&P; z?E#7VN*W6x7QCO(6;g|=@&}YnE1iu_&{bP0syr+qL>2|rdRwduxkIosI~(h=$}lEcNnvGYGj zp%x6~4vkd(=qu!ih9%Yt`zjpu5{K(?|95a|jPRXKP_vRpKyZEt%`ecH^sI6W(@?*!I2mk87DsSd2Sttq3g zo4SUsz~brkiN3FV$JAF>irkYQ6tq0Qy5wGjTpEnAGMAbxb9vXDEfcT1zuM~R@vm4a zbXd_3J|2%DvLbf>lb44FwdC0G*1oic#wr7n-5n1rzU*|H^9r=e;ReAnT)EZr^I;W~ z!cRrI=2H@>SVM*39Ixg|*F~F96|vQ%T}gCh3184&kX5F$wpB%jRTq?5a*G!qE`+d) zN|C%g;yj=whnQf6%T4w~sztjfV7Xyz>Q3D|5>6@QQdNAcFV-E+RfMqL<`mUs z?TyyuP7jc4EjKB@Lf~Fs-|v>S>#F*ikh1s4Wfg-gW>~O@6jStvOxi~~FUJ~R_qp>I z>fI5;i(0;9cs?18#i_ARZa{(sjA@lHz4pT?E3>$n{d77*iZunZ2I_&H4vkpTfx;}7 zlDfh&clZpRAJvc3-g~00u-?3ES2OT^lIpNdVyeumE03|7#Qo|@)mJEKNIirH`p8>Cjy zQil~2cfu;qO@ggt3SC^`G8dYPJic2#DJZLoBBvPywD_Z4ul-a&X3`l>~%v_{CntIJe@)qXjvB(Z{8kEsZ&ffkc1RyBCF=;xGRabJ2;%ZnNQ zWZZ6)qAfIuWlXXgS6Hh0&$11HXdZ=ZjTCW%U3S9OF6+lJ7<-oeIr-r4qVX6Y9+!8`<8L2Mx z%~BBGv4^g^8g^9#SKTd{_a((vGvdZk)}~hM-!qSxey+MvQ&sa$+fNzj60)uhSf0q& zErYlz?{~6=^=_&1Q4g`)A!@!mVCI9eL@lZ>iYyW9ToqY7{*DQxhAB4epvnPXtPK)b z69H?F)j^HKVwa)ap3kCB2lWkTeP&%&&&#oTUe>T5Xz(bk;9&5MlV=!cJ>%tvD6AJ9 zUbX75-n@2VrFsTeSTSRiT{-N=IXzKNPWVB7e&YI|w-L$|YL{nEvc7u7@}NSiI}h9+ zQ=xkh>zG1!;)>VDaD`z8p{}?z$nyhl3{VG{Lis*~RR?M)GRt6ekgVd_J_R4j6S}~{ z9f>80MJ_>V@hZ;?$*CfM^y;CXvjJBDWi=aWaJKf0aI5JSTcoNAoML%-3t2p zU@B|~oz-0)Y*)Ce220fp4lT(lAqz1(K3XC?Ai{#Ex)reis@rsx$3aF=M1s(AODJnt ze4^XSbDbfg;#3euPAs8|57sWU)_;UwEO5Cl^nmvZLFgkrA=p&l8J-rz)FS?(!n;x? zzc5zeLvP692LP*5>K^9{$CcPM&r+(@s(h%-0(v_Cbt+%Sh^?07Y8A_OU7{L%BCoGE zo5U;+zX=CwsL)6InA4-}eqIDlkmC5hFMSESa7=3pVcLf3N)8kNL4@p{qsbcF9y$*6ZegH!GW zFT3(eqU!EWY5Uz>f|c_ssC9IGg%cU|cuZvtDsJaOq5X957mVQTf%0m#(jgf_(P|Zo zg1B*DeKLu)5~&IgwDM1qSN3v;C}~v$uL`G`{fkdJ16d))04seyuA!;^a6R@B4@9Sh zFy)GB!P|vXYr$NLu~xQ_L4+GzkX%9)!z?9P@`wgAhn09$`Eg!X;7~SyI@hYxP{8C2 zllE#N`DO$})1X-TU5U#w70WjZiM8L~)YM&K)=eo)u@au5YPTzI;0|w)Y1Nu9Lpt5} zleA)z)!&61gv|OMduQ+3#3HK(&b0?mgTZD_jO-Nx$3@-9FywU>eHAdZl zrre4@ST z2b$l&tqM=0FjU*~DW_vmTX`&Nc=jGn7K=nWSb8Dt?weA4zVp$^ckIt$A`3%ieq$^v zjQ1B{{X}5Bed@U%`ukPDDu#?6q>wvzdY(iEYZ5{CG_D~$tVoRd=|i{e1jFuMli42r z)$QMTJt$no7l*xTEFnv)gx%}Ebg@CTyQ3H<))RN%^Ts5gyY@Q__n&iVLN4|B* zb)9}_pMlF)5=Yl<*IKO^TrD?zC84|~q_4FSv$%6L>?^Mfy#?C+D_n1tz>0(e3c(xq zuc*2}EC#Q*Sv@lhoZQDz@2m(<6S8n%+yQZS#C>m?o{~kW!Ida!K)aB^=yssFjff<(&Rp68N4jyNExG*Hust+h@}NW zhD9N;E>IZ0Q&co)^-ga4#fNWFSl_b9=xqc?cam5ST_2&tYWI+sRX{$s_5WmJjfOypWR zs7S1$)>9RZC1^CIs?v2SfGzDw87L#i3|G)t1%ws2RmAe)%n9{{D~P$h70e=^nzo_d zGWEs#k=7GCL*5^CQtSW5POno|D;HYH+EQ0yq)>^mx#X3sc#~Nx&9PYtVh~)$qWPTl zBHtueVC!ak>4sL=?KkJKU^w9LhD+g!M!WC-#k9l8*}!T;N-MDHUq&m4u2b4rK4?aB zvCb4A)w-c1mQPLQ4y#9~2&uEuQsFV#lgisobn#%<{7rzS-#=d(5;d_9Rl4QZ?Al)w_QQrGi^t1Q)n7x~P-e1%Xh)@_y>y-h=9 zgsWXz9VDq9Vu3JT$T!?mTqXa?cogvR8c?q_1=jsu_%d8ogp>W?H`SG?q)KJrvd^q4 zzpMOE8MSJEglDDQ3R8ADla@*smHk>7s+NYL(w-JVnw=koEWJ%=O$nt`5EjTmh*t#G znBbZy43Pi)&TY4K(ia9 zvd%QmkIRHNrvtvvPB^uJw_8uzd4yE<^Gr5Hb z>77yPGcxb&CIr4-=<*{%@6T9;%oQ4RXt=-4Q=_l4Vo)tPss_WqdaXc%!zxB#z4IWJ zM$4cp=R_Qus;;W<39LH(Ua2qyhL&|H+e*9wv1;QJAJ=>aP?^LsV)4!h zW{hGvSkDM5BiCc1*0iXLq6l0i8=l;PpH&p$XxZNoX1rN6v+8M3Qm4i@Pu(7;F2Wkse7NOm@bDAXZh`cVYao8{RGXhTO_DRV7ws*b>=5rx02=K2l#T zH_};kT~)P^W>U-ECavtgz%9UKoT{O=B&|xr6kzp8K=El|YRmqX#i41hrc{;aONlVH ztRQr9u^be+dJ?O%;hPLuRuj^Q$2C_Kza%fd5x}m;eP-E%Y-uryLl0|p2?*_hF&|xr zz`CA~+LcDh^T{<41(u;Gr0I@Y5O*fC=5{!rdowf{HBY?S`p_9_D%OWA`e0>2S~1r! zaD@fI#R#ck>*R!PJG1U*8s&G&aeiJE{(0tCLytEMd(gt{1}qku)G~Q>_wl2#3j=13 zj#V0J|N3K$oO$8R58;)FHp)iAp3n+Rb*!R^Wykw9 ziA6kJb)dp$O?DAcrmXJwG_AlY>MVS!yaKGM3|9fKiloW_#)1%+{M7YE;;LS5DhMt- z!Y@3Q_}eMoc2(5&S=v=;gfh`Jb#hH<$d?OaRY6NDd(9}Uil!-N&MVyUIHoP%xS^GJ z)e~9`T&;00{gAx(l$0Ok+0&i@f1OdQ9c9zD;yl;>J#i+)R;I98&43WC=HL}1m(gmz z-OlB>qbxKo!Ohyv&pQL_{H7}iqZ68<3d@88pPMXPU21zm+VJRvrfr2@LdY!ISSSrO zc=S)_)q7W1Xx(`~?D`9j`2GA5^`L30qoerR9T;_d=M%EPuovL`AYdJKJ%rudJ_JQw zVQGH*0R>j>VWpj(IabE?)$2*N*E0mxManZwCX+0M^+8i*E`nCyD6Bex1>=2Z7x3S| zrY^!Bu=bhl4nq0S(e*%B^*yYRR&HC7QtN7MU#KjBipuJWqRM_=->)UCj8|(4t|}*0 zwRU_xE|>p-pmJi_X%iO)C5bFxX<2W8E0bCFsfoA^9+&(rJg&NQ!>gPcuBL?8bXw0I zVZ<+qtH%QTnwBMOErZsy!&R{;16(>&VmZ5bgxZQ$!%Sawg<;cpZ5UG@8X55kQamB% zKxH)^J=^<&URJvufp$O$YKCrgnyN|E{tUy!0yVzVQ2bu47v*H4xNv`b{9u_|5 zTYlS>SB0wq!tUFfNWObT7{CIk)J5ohITBb*kDkKEI>o-wH=LBLPUxWkHuQNjhO98) z5hj(wN)ghCWZm82aOCA7-aZ@aSQR1R^#Yt9#H$Wi8Lxn-!!)QN4ZyK2`qcB??Ee7gHEmvSL99QM_g={B9udF6L_j2 zsYt78vsqRf)P);;H}-Eg_=h!cWq7hbsHavfLSmKmRQM`OEEyV<^uSnEpgNouxgfD-iB^0lc#Q$ESrAoZyZ`_o07*naRMCvHhd8K99M|qzL3}OoOpL0Q>5T8cRr_rus49QH0e?1L z}$~4;La#k>ou$W&Mr(;Z8lSiF#^m`W$c2V1$se!nFfQEg(FJD zDL%8ZY?8}pq55w1Wk604Q31yappkOK-u<*#lAHxYRsr1+@A>XK8k zxWnov?4tu8>kKP}2)&=M=lSe^?48YP8(9{`+p%op%rNa<#5;jESqKyG#%*YQU_>*2 z!7Q?vg$>c$G}#qcTS*uk3I(bfTo_f#3SP(qF$Cp9)#qk08GdZ#xgkt>{Ymr#Q zs=#7SC2~X*Sc{i2^%gkA$}oOO*%cKpO**21}wWK6j&Yo z)QOZ>Ng_A$i|VbzP$4GClA{%H zHf3B3ru@LFLS(T(GU3&fG7ILFU~4c1u4cpOKvmW2Kr9_yZ7&nT?lw(WXXJgj|05eD zBRX1V$eqsB-kzzf=XA1K#;aWhNSoGcW(xwVg|#@Ad*8N1mez#ZmdHA@B$mz-q9XhY zSidK*7!oas#apki)WR~2wGz6@tXM~xM{2iIVy)^9UlnAjz&f_fs9%}Gdhp0L_PPr7 zAndA3HLWzu@VT~OqbA4PW(P-dz7D_O$J~2ZUSYit(DH>K4)x&2H5u!*bsIT;y~uBJ zGp=$~SIVm~)fT=Qo2t@M(2WgV1@#mVrZ~%U{R~bCf>O}S$y0p?vx+5QOi8tfV-GDq zt9H| z)69aG)gIt`fD6-x@UcW&4Fp(tqbPjceLH1Y$Qi=vZ~%ezb~t?djFW>}7}9pH`vp4e zm)sm$*JMPobiXfModagIT21e~?{boGH*B#=>%B$eeV+kRMn^G8$Uqj3vmJnId%Mw) zH-W|QC{`H$LH{3LZ~TvO{b~O3%dh8uLWNZV3-^^s!^*8LqhVQ&Dy-wxN*DLlps;KY zLS`C3s^d@(9?{3rMbA1*cohVeUzWoO!V0kDZeD5JcU`NFJlI#bPD)_06r9`yYRQ+A zF=$o!Tl^xUDyn$N`^GAhSD+O25=ud*nn^yVV;&Gsz*oOWi$d>7eWx zcw+mD4b+MUxS+1415KF@{A3|7U1mtt$Fj-7Dg5{PGZk3Fa(YnjZH3Z$ynpOaH$ zm5%2AUYTy#eXh_Vv9>HbDiTY|zyoh#Z6A~qhU#IRp&;DZ`ROU*4Ukyqk+t)!faSS0 z|MKQf04t^%L|pwX^y%}!DtjXPT!Z#<=YpI^x>HU_HmK!JY^_#P4ae36>nOY~b=C7F zBv(j`9vQAidQtOg^zKrDCF%-e<0HJQbDb?zU~L$5`oz_FaNGr16XTUZD~C-bY?@GE zt*gl58^4fNdCqx2oelKBvOP${->CrpB*5{U(3xqhBWapyoS!Is03B1 z@J1e#lK?42$(T`T(Y&J80Rs6wi~1@e)nvjhHRXHYR}m3kV_q15i1Iv& zSRD53>_-&r_XtAk@YSotPaP&yU*6J6e#?#zbBEAXGX}ZJ23wZJGKrPk(>>m|hW8z7 zd`U>1#he4`Kp__T01nzH1JO91DoZhC(}e?FtAi3z#1(@MEC_$@T5)KZ2Dt6IMyKAj z`9eRyEkxbxx{mO+{P5))1Mju zmQEHn8s8XL_!ocU`s1622&1phGuW`zH!Ee6hOi`Ovy@jWl}@ATx35_b_toPy6or9P zMk_3KK2lzNe{|$`ow)P{7Ivo(>z%7TWkz`6`k&8L83l!&qY z35UE$E8N`VP+0on@rxH%xyMr;F1d-T47{SoQgMY_NG;J)IV6^pdmxl(sD74bPQ;W@ z%Yjfa&*Md*I?DA^(OkF_h*5LN9|C78t7yi@rmYtKb5WG1B4>q&`jW&#$vEyEE`(Ka z1XnAOHxQL&XICCpGFc0x>^Cf8kMRh3)`D#S_yh<|o;DNm=ezu0}$ zvgJD`O0JpuT7svxPzu)*tp!gk_|6RJKo!=Bt%2qYp#~jL3|cm;tBpygKG1Z@s9(YCj29Vqn|eZuW{{04^TUO6|UTu>NsCgSd}(dYs)3!%8K7~;;}Vxhlgc* zJeRpSI-Nr9vyjqy*oNs)I*hZ7_6*dZXMpmRpMh0NeDam>M&$W%dF|r z#Nn*$zI-yX&ZXXmf2~C!6jqxltk*M5V=)0gU?Piotl3nf4RSxE!WvGy)<0R))myK) z>S|)q$LeZywAn1B7Wbgot2b3r8L@blYLLhRs&>!3p5k)CgT|Tgs&#PS(+!OS?54BL zqL2#9BBV@>?lg$3Z(S0W$oletkhS^U*8^+5^q=8YR_^TgyjkfeQy#u`->RkDSq`q+ zw)CrI2ut^PX3AaekQTl4O|WzeLUr4(E(5rj7qxZIBM7a}Wz{F+qX6stoxYcWHPMxX z=RVZ%CLjw6E2qrLwJyx_vHz=eR)#1Q1Fri0Mft0Y8q9JbR>t2PgqF*)oJC=Zmyk;C zA*a&CI87atR_Z2Mk&;%0NUO03E0?9t8NUkFhr}2@<5FZ<6<2rxP-)TsP<$wY(xUJ> z6;2gibU|auSp=56Vk1}7k9d({QQ1Y4OJrBC7nIgL$buIiB_Up#_%2&X#~boV#f2|t z68+3!m^Jh*A1VomGVgGEopdM>XFddvs&T;GECyI|I8%AmRbnyWz&XRAhDi~07;40! z8`7g(o3lR*!7N^BWSNHrRrLa~Q4kAP0PC!^x5vT|xB{&9n8QNXQTXcn`#$5owckR2 zEGhrESK)T+$(abOCu(AGt`J>jc7QD|%+ZE^4+U6ISr3d?n_uN$-2qmKtZEmmHNX7X zcN+D(P0+nUgV8m=L(XICL15M9 zbg!6exC1PDSntWIi7yLT3*Ll^5U{!+u-3ipj>3?JyCMsxxaNNV(AN7(tSrl%fT>^T z$x&8~1yRnCS$$DXpcjc0y9{)40xRk%`6l~Sh^1mno>)L?@kyx!@rObse4;C#DwpsT zK6ncZy2^lcYFEPRR1NqT$cjv8MLoTZy!0ZaAh&|Tip+Yi3`8N+-%_!a=yINp4?T1` zNmXfuHl`sAG1KhBvc3w*_}hCT&cbG5xad+HB8z!Ze&Ea@DnYpL$Tf7;!~&(Xg#+da z*>#3_(R#oZ5cSM2(Sf>R8f*ULnG;BX4g#|-vK6)?(A))m(yjocTR_!*hzB6EL zE^kE`3PRg>f{y!|X56hwgE?5=>q0`REOP4y-%{r42OMRehH_QT=pF7g;y&UmVZ~bK zEFs4o4{M^1yPYS>tMlMt5mysV2QHU{H7yBqGuUy7gSo{=GCEjJT`Y$))s;g<=;V+B zQ1F#yeQ?TwNn>az@`o?u)Q6Oo6+Q^A=BfH~Z6KKyu-WjrOL_iy%g=LTNqCdebvM7QAt=f8FL2Ii>1qLw& zl|jXzKM_cv9y)^1)zd|PySeAw`(Bk~rISq>MV6{crOGlt&OPtk`&__5rPdEGeQ_un zYd<`!Jrh~SpH*1L$Dc0=OAc7M#A0gnxa631Xd`7X1B-pn2f5dtd+u);7uDH)j5I7X zfwgG*0M^2*ED>1$wK1bTEeLz`uoPKPTEAKI^XN&ep;MUCFhz91MH|Lo)L3aH=)%{@ zz?<&GQm3Q9!g)OAuZ7>is$|AO5Lzmk2$e)MfmO&YfKj5S@M9czsHS3rRL5VFV|I$2 zuSL^c?*LudEVTQm6Qh|fERGYASTV}N0GJ8{TG=dhz#2qZ%bg>7S}YgAEvzJ})S~!m zduUyo;A%TBtL1YJRu&q%lw1leg;gP{HT*>4VY_!{ICRrYKe_AlufOK$hAxUhW!NQK zp>h2{L}^1b`k!#1yUZr_dD>C4TZ^OID}+Yx&unzVUMVd6Z~F5a@!bDPVQm$J zSR;H^Ds4=aDV-da+&ZDgu*|_aP--3cyyy#UCPZbZIV@`-Y}zi*i}wW!tLHii&Aj^H zb68$tJqNI$u|`O=Zvrb(Qccahf_XI+g*By(H6gQXxllcI?8$1zB@@LQJD*~kAG>rp!D%D$$ z<2Vim@ne$4sk6P}mv*K57`!Jgmze2|}RMpDX5p}2ohs`iX z3Lndd8(0!DjU~LAbIwfBx_V`+h3{Mg^o3s`1fjGTeCH;OilnMmt^cN4sn+Va*Z61M zHc=H|omyd7tJBINur!2K#v67!H5Sg8*iZ+yXlT{<3RrmkzBk1B!VK1@6jrIUX<`Z&(QtP$to3*-I%_;(VK|}CG7rmFg-74XorJ|;Vy63%{dQ!)3e~>C!D%b% zC1PquiIt>;mvT#sz&LSK3JqCl$cOA6{zaVV!vPgo7FdZWPYS*SWP+>|ccNerfM|m# zwn8ufrm{ggi(tJ+u2AG}Bv*@;eAKdtDaLKFQk-edRNp+c**o1xDdcYw?7BBssLYQ3-grqjdAUC45SOxdghes%r3i=8S6u*RCKCLLkBl7=YC2X z3o;9pVf|huR#{0^E^AS!&bwLfaIy9cSo=b(FUyO{w=IRG0jvV9N`+nO{X(ISVLelI zrHRqQgSUsddu1It&cAB9Nmx1#>wVKF8hk~#&?yZ@E$z$cu_W9C7UwjK@ZMHfABm|E z6_z)$z$t+i6c(?AR|2kZ%ca5+pg=20glEYl^R*)1z*r)>s$=Efzv;H?0-^kqggg?7 zl>^HadHE{@sxnt95>Ns0l|DX#Oh6U&6@Q4+*gYkmfH&mHN@ome-4~u&1%Id>H?qL_Q+{R*H zm4zR4yw;BjtKqhzpUz!))R#+}VYArbhRB6H;8&B9&nbIM%?xwA{dFn=i*Lo1=CC$`qaYQSHCpfVur$mt)hlC^2rbc8s1_q5Kg-3B?pprA}0sg?uGi0xGGfm?*V8sPJgwzZNKlvM^qT zluaN~rZftHE%Iuq+)7g5DS*Htzfdh^k#bEQm`QCI3!?&p3i*e~ocUIyw9 zJgZe$K5SXYRE>D1PV-it?c_r~e_45T?Od%wpR`Q}beo5%&~g{-)ZrYhjjo-%yKpt< za^ZY6pDVhw%@Ekqgo94@d+3_^4q_qNfMRfySY7k4m}k&bgT}FJCYFWWtF>C~LT6)P z=qMRhy|8guY|F70=!)+pgvio4eo_<)piWg?p)%yCWC*R7UT0Bi?W4kaz9&A`XQ#8}8ZfkmNch(e^&T#j$Mo|x%?cSuq zTI4gZdaAA%Y3Nzlz4!5t;vyk{g?S7k9JUqKR0Wo%uPCd=Yu15+DV)}mu?eh6XCpBC z=Xfkq30W)rlyovrGM<2=j=JiGtFRM0Mx_ZY_mCPYG%4lKqzFrI<9?j=WBdhuyO7Ie zw#?*=FQT88@UHkKu$CsT(uCqF#SyQ;QV1v41J;UZ6o}A@@nMmerVv$LVnw!ssNA9< zFXvgS6}3IOJi^*mAzo_>qVj4-R_n@HTUSML6`@s_?vT#_Tn%-;gU(*Iy~M6|>=ecr z15_0k4_8_tT1klRoo+W*SW*~rzlyo`6s~U6#Cn(mOb%C^GV|`$xrQ5lvhz73Sngb9 zMR;CyyVO@8u<(tshQ@uZg1QhQ3u4Q)KMSR5jeB}oBCpCdt`y$?P(MRaXu1lGg>{WL zd^Lr&1*~ar>ouKbfBg0-Vm*E{`f9r*d>*8qYqgS{OJ>jM?mS`O>&=I6C3t1(JJ)l+(g zyaK@}uJTtWkGCfxu0Sl*hDkE;_2Ll~R)-R5=B=wZc{Eu?b4#r(lT+StS8;V00!hG? zfJv@1K^71tbjtd22@F9k;kuvRrTqXEAE_0f^aGu=NR)HtWK|IBLlK0RewoP!sFDYx zC{1TGdRZEMXk{%JTv8E|S`b?1%p+IoeE7CoM|99?6;~0rnU&M(`ZI$7uZEso#Wv|n zm(%j4;m|@^)@R6TE*hc%T6=bUMTmYwrX8dV1gmhK+bF+>uFp5z+<0+yo`2brSe!5e zT3JudD>r9G(1dfP+E9gsMM5I$LhC~Huo^53&uaAB1z2UusYV%FK&!yIr;7!}_4fel zNx+JGU^T;?%=+$^-Zvw#b}FpnrwYp^xnoB1iJDlPD}$==Py-D_wSBS0~uR2Lqj68_KN<5iDQ&@@dD&^humgOB;1^Ts^GjUG7R@0~=O9&EIj83bV6RV9i+wa{TDIMcprSeuG;sR5y$M6>|-u zuc}p4h#2KpsW9+PP?1wO>DJFM-5WIB8*0C6P5APx3^ditoG#TRzQqLEH~WoF%K)u6_)BN9B!Sc>Qhqn6!;vUiU&n0 zfm#7XmfY<_O7)k)o8V2h41h9u%jJ@iN|O(PX)t_})QCo-OVA|-?hK-jY~D?{4Kv>-u`Qi7O8*b=zHyh=_w(TEjwj^lGCx z{E^Dax^-Lx-h3>@7K_3Mg_DS@6`iabWmQ)Pk$U@zl$yIqel}R<{9Gr?aPu6U)nFP6 zE|vhR%6tQs3SU>MqO@LP%1lES2|2JqWfq!sP8;YVEW^bTSmA)TZ3F$%7ldbDZ-Cz~ zUkEHg)-Jniy6?RD3x#!DaNBKipAK`^N$xJy;Fk%tlaN(mAvVhCqEuKf-s&VQw>tQb zVqZ?v&lv65t`kg+I#l&I#QjOEK^4|$OJN-)Ys+9+=Q9e!k(Pse;k4FTa6G2CQlT|@ z1iiT2*9n;n?f6x~BYwhMTQSPOl|JgM+vJu7V4pY4sxk#7=n+=kq0A$#GJ(>a$SshH zZ}|xVOYZlxH*%Ecdxjhu`~csN^ zr#M)vQ{kj72d@BE;YDmf&2c!NX0=G{M(e{!l+<>V4qUC7YOKRqx4_w1g<1Eo!0GSZ z)qxJq!_p}Z7?IU94@;K{Q4~(NMyTVHp{yvfKHB(X&USB6VyVJ%6S4NVUrsi!GAm05 z3yXxX-1qYNd^j9SBo<(m(}hBA@g)^vE}gSgLbO0*g;2^u&5q)M?VmH|Uj6bn6t$jzvV+x&4ecak1GMcukthYNAT0kJ2HanphjsDB zuti{*h1J&BsGy1-7J^u9r?LjgRl)&wptu}dCOxcQ;kS=j3y$US?Q%4}WQ>88AQuTQ zM@p&DXh?9O7CarPZzZo#SoEuwsaVuKLM!lUt+x0!9QT!U`=^#cIwFV*?;R|?yGo9j{?m;XdyC4!@=YAiCU$3}AJR6181ccXxO9)sfpQ=RdkW_-}QwsIaaQ9u^c< z`}YTv?&C{!+-;Rmh1IvgNXx*>F`O)_Dhew&SHu1(9V|Vu!)7SJ+6+3QH&dHY^Gbl# z2e0a`7@ZEJ-v9t007*naRIKBskO?lN)|rM3ulvaOKtOwYpqR zaV~mtlG}1!#K*y;B869}ROH1}K56O|Rdf|`DKwiFYhOt#-04AX(Zuf*mz|(MRH;=Y zvrf#*I_aEs&eYX9JH=2yb>WXsB6e0KZ050n@$SNS)r}R2Zf}bZ-DIq^8*|LbmoJokCV<^C>Y7W<&N4aFzRVtt~A1z=eUE0?#kj>kfLG<~p>F()gN$(Zxb)O*lS z7*Oj^_OR4}AFL2-{>Z17$9Ic)d~E5Oaa!Y>*zx$v<9+;-%TLj25Poj_pT4+Be5c5M z&j6M>SQ{6^yE%t|ZrS_0Y-c%zF7L)Gn;F0vO zq)gOR!j&A>*d?$8T4TWKa_=k~aidb>fUrBf?5h zU%oF_Q;$!2TaaAvwM13gjKG&km2_(_LRoGP+%3B1xKw(Fvh_i zf7ga+%BzWX=rrkJ$y==k<0P& z`qC9bPQ{W^a3At2lvp_(*pL>9cCf=`!c00X;M$hD5KD!+T6jQWadN}k{~@rRrLbPT zs;+buKG+65#-DmBl_cCE@ddBOiH|=j*S>?6QE8R@<_{lj-8?m#Z-2QlUaXC&EqV!J zeYP3yE`8-v?$t#!SG8q5f?GGkfKdoHJOC^Uj$W=!x@#*TLB%-3==3%=L>cUX)Eb|{ zR^K#-3P=C6Kg7Sw-3uFY0wc=~xt!OCDPN_Or{!Ob@bZ8t>L>~-Raowrvfu-($SiMq zy=*kdrUnUC^BO=@2~x`|O#w0in!ZClC?{c+yi#42sIWv>$;Gr+j2u!ZPO+G%@2Itu zT1DjI{WI&D_Je8>`7E%ja$>krGd^58jH1gXJsgMo9O_K?s0n`*8SL<(+YKjYg)c5s z3VMB+%~%$KS%NG=zHNz6&AwpOa7s*n2Mb}-!@77f~p|+Z2b-qmg zT=#-**>2GJ-K>plkn8vAxZALXT@Gy6Q;n750--&Lt6WZSl@mz0MM9m}Al0A>tW0L- zfQy52!z~m35GA1yYsJTU05IdlI$H6Mc79)e&jMBu!{R8cm-rR7 zQtPKx^dhjLef2rm)JxlO%5U2D^XTRe5jS0Q*0LQ~S8a9O<>hL1mGE+{hjls_41`q! z;!5km+hD5+izqBm3ywu%^&<1I(3*pTz>0S4ghgR0M3(%os$%s|VAP|y0<)w5L_H@} zUX4t`y?V{};s@(NunCqG5Y+&x?0$*&p{f*Ho|3AhaHG1y8{WiY>P^Wka7jK$lgruh z02%Igq%rCJ|;`4YxSHSu86 z9lCC2X>!VPFxpRR!`Y;3YlXrmm{tYt;K6o;b4i z=aXj@pvU4blvG~@P+A?<>x~AqmOQWZSt7b{tJI+6;*BLPSr$r_=l}+UO$AR=sH!5g zSJ738AQw|xKvw9)Pc55uX0sk#!*tNZQ?Zi)%RjD!mb?-RsdyLCigxfEvozG1f3aZc z+Ud%SJm9K;#lk~dJB)@K+-$$5#vCFFivnvlYetS4V1?&7a-`pEmG%$5yj!miotGulxw{~- z%E3b6YfQv?qtt5Oq_(zF4!|KCtUnsn&qMU;jCf>ti&gu`AIbNK51@Ee!;FNk-j$Vz1)_$t5u4|r^g4aqe zJvWq6@^OXLvawWT0brC{tQtjAkzDYzgkgSt>eqaqMPez;Jov&e#aPiNvWT(HGz3@V zs6>zzV5?(s(&OWbTQ;;wTBfrqD~*Psq2=uNqd2v?k!^O4SO&_i0+tNb(6U6M=U`wct%-$rV3)0~P^TlvjLhG$^{jB@#;Rh|DUH^wz^^C&WCWP9af1}9MZ?al)qU)t#>O4XFMymY^-0z z$ug;>-g|QvWE?c^&g{GK>K)UgS-EWOwp_3Q5^Il>`?A?x-LD>3`$2pZq~g2=MV2xv zosTRPs;)}s$SkP~|FMIOa}Kc2mwH&+OgLb(oShw%g>Qd(`@;aMoHU}#-w`lfL#)9= zHQ~cy)aO=&&sA6yST8qT$ghxk5?J^ZKD$UmIovo^j?;PSQF&$0`PlL5N?%uVSTwL! zlJ38bI9Wzr_wnE+oM)w6S};0#I_z^IOl-OgJgmL|YjZQ$cp?>$DwVL^0W2-@oV2RD znlCH>8{w^nKCj6uRaqbw{q}#=8=fl$<+S{*p)}*IdYw1}zkVyJ+5)t+NaU+$2E7!D z#Fpr+5^@k&K4h85%c9v@dO~IB!@qJBVnSu1QVbNa+mL)e?}i+nS7Q`t)=Z)(^M2 z|Glkm;gu+<$sJYZ?YCEi`IhIeJSF_Qo)A9pPbm4hpv##n245d)uz`;Is&wyd)9ymN z3p22^D9q=uCS(D#yxSdB@nsX(ihn%*aOGu^#sRVw)t!i>UF z4-2GfA-m8?c~zY}ujrxo21+D_)F2|dqJeU$7sIb2pz!vf7wUDaK&!Qx$!ip36mUr z*C*kVWR`kaZnW~q*;?JqJor67B5Rauiq;v*qq^Geu2H9+N@b}P@6C7kRW97%0uBpQ zg!|5aKW3Pem7yrC)EqBDHSdbtx)NHA ze;<$GV98@Edlootw**-37%+val0O?vDJ-Rw5UDdrSml8gDW=G#KzS7n6ieijy}~UT zMEXKV72vaQ5a0*QdUro3I!r_sR2C#w9HVx`i-yx%KxPA}2P!SmR`CJBbTr|}H)!4+xNt!WhmD25>}bBhrY1vDabSZ#B78|`m0z+R)G2=Dv$O3prW>|il#y-F04W0RL>874 zzIZwcE9W`o0CTnZ_?u5Ke0kho;&DHg@ap^Tzcz=31H!`xd6jJ9+FYJOT3N_lE5g%d z>7kojmbzK`3|UUIw`2Kx-p2|81i`du6ZYJupV@{qRhg@L5^6axQ6uL?e2S}-@jLVb?xn}VU}6l zH$I!ywN}Hf4y4JCgU`;P$($IDl39NOEhSdn<|w0Ar>@jeM+;eZZH7M9T@_jps`p-9 z=&YG4%&V$1;e87p9xVuHg9@ahQxYptj7@ZNSqkV$Su@4Mpf@If=Z zKn*@TDMG;YcwjxFe=MDwI ztH|V)6oSB1AOMnUJ`Yq(S?woR0Y2{qtG+z&9Yxa!0`S1LB- zS;Ur?SdB)AgoK*)D!1me<;~?nK5MQghiv4zcKyB~-0t4TSsFNBGKy%bZl~ipkMhjgC92!dI!j z91dyV^7@x%x@!~kR#_vYXDYAshHW`NZ~euwhHp_=c?wMK&OFHf=#}*lP6~!<&5Cr{ zT|;ZKzr56X7*}7Tu%21My>+j?O35q(#mZUkwm0?5V|cac_jzr!K7O32z*1KAsacPOuL4nnH3>hX*<5eb~RpPj-t6Y4cwC=ZiV4)GP?G;wL<5gAU zt|Guo*cC-WB!O5UWCE3fc%YP$_d{Ovd;LIutf%rS3`3ABMqL=homjP&yon1z7HUIE zvJfxgj;6L~!S{NNlqZii#CVPhu>oi`D7(O_>$Jo&>s{)?Oj+2yPFq=B@av6FXr+MV z7PIz;GR;+XsCW7?ljAKgm`UdgS< zz*=6dT7bjKb?RieGO;#74Kz#&0JXgNf=1)>+s}F59Uo3Gr|%;*RvuWNKDnAO2Q0*| zkZNcxy@90}tmPE6nu1x=*$mveIQLsrwY|A5pWph{!p|G21Hz3B-$wXZKL(-Nz7CYz z(SY?IzVu0014$)Ukq|5h1`%i#5m-UYYutjc7n-6viWEzsgP1(YbrdVbNHe7rh!yr! zRE{ZD8MYbS7ep)3Q7yODtn2AdC5O+Ju!uq8!eTTaBH20sp!HT^B!h}HDT*v>+HeV zf!@mEW5HfR`S=-Dd*O@niVoI#LAYF9K7alC^>g0Omz(QFq2Ee>d3br1r`5*Q^wKT$ z`eU+Ms_CBmmW^9eSRW^U-mEDs;wm3&fQL1kO)|VvVl7)^>Z_@PmLTgq6N2B6iV%}x zFk+$A9(PtLnI)fglBl|Js-us3J{WQALg0l}KvMNoMM+^8fK*UfkXZIidIdo!1nc*s zpf9gQWC@}AVUKquS7;?7uS26&sN4!8NG^K=Rib)fu(<{ecbnTYkVTQjVKmnXv4;NG za85sK$W-YXwcgkiEjOst%PgJfK>Nzipz$lh{6%VS1?Xj*8rk!I-N39}F1p`EiWJ9% zS{}-!8d=A66<19gM#_=zwoZpbu|6c`dleZ6=U`QoS0|MZCa>H~_Y)*e+<-$CN|u;mr&cCpFMMNhUXAi>+^FiIl|o!?OUyR>SN!PbGV*pSbn+W ztkF~4Pn}P-nfUf1(Ntlr_YyMWUZk*Eh&4= z7>K7Fum(yea;l@vG;O{*>IjkK;^?;yL8T%~g;k(We2fPonF4$ROsD}v`9z+gqo6Nu z^#x>Ma3mK(ETI;N)erGz7zQf3Vk1^yS_?H|9P^qfEu$6krE{8FVIy51Hk`=PfR^PQ zQc(wil+=nt4U`tDtYMb}w1zk}6h;kGg(1W6ei>`B)394G2i|Sk(a~6`Hk~~?E9CU# zMQTUIXz?H0WDjID7ftG`rq0A#uoP@kZu#@Vh5A=02AfE|qxJd2Nws1#NR!Pulvl5Q zBA=MVI;k<(@T-fDRyft2`3ARy0yQAqtFi)12g{Uo6SN|#%*1HfG**oZDbT7TUrz~G ztHNAE-Y_a^V_uv0Fe~_tg<J&Ivb5x2KrXH~Did=}r$zS32iQLQz;3(`ANM z$}1XM@;D{7+Cr^W)^s0ZHt3Z4s@-`vTV-MlR9LX7+8SPuP!9^HjymL3+!3wQ5w*iw z5CvaP3qF*Bpj1Q~OS!~Cun$y$SOTR!ITZu|6(5CJ;2K_s{XXH}5#tVnML({|`Opj9Wa>XyfX-Hwv**sS-aMoDS4f8ZmZtv=juB0VY< zV^t7Vwa({#oioFOLSdJn2{P+{%rgL67Glu89F3H^siQAh8ge35G7C#L=P)^1b5Zv) zJD*V#QfJk+wzh4`3^W!6)|2wE#>Gz5&0Wnm8Dd=(bs`=<9Cp9?nlr*Qs-E$_rm&Lv zSL`1wbg-5aRD%C_?kYkq%2~@T%)G#w<@MD>ScQu4(q>>G&_3SG81EvnV6BVB`naaB zW)qFH&vMPryrtg*lc=xMXcwT#!#mMe7wu%t1i{sYzG{oiYPZMl#_t9x`(1uS#gz&y z7KFe3pSi1fX)AA|uTxv8-MGeYtYZ&K~rZ!hJ z^ZV|bM>N0lysnv@m{?h|AL&*Zsma43&Kxf+kEvtHJ}U46(Sm4IV{us9m4VcuRB23V zwNWZllMb1drOWJTjp}DJGWbzwMl!7OL+R~+F7^nmC}ig7vUg!=LWeT@s+qCa zD_mN!UVgc(~ zi|}-Q-a!;Ms2ab*k?YybUU`fASyqI4K)l*Iix=f|nT*_>CXzetqth?au pztHGD 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 erh3 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�(8fGpI15~Xf z?2KE?bjcmL6Atciwfj~2&h$nRgcuU`QZjnxjJ?>*I`;LPFDMBA4Z}LwhFMx6oHQq_ z=)qum^{#ODD>f%!6|a8vutGuDw;T{_8Etn06br&tGsGfpIaZ}!R%mF&7?#vnGcASS z1LBn9S3s(Tsqz#F6_5)WtXdfzcb$AXU2}+)E|)YSOi|jv*onNut6ZuS_MUSDD#%7D zb4Nkw&`WS-?#O$r4xgN8qgcSItaJ?(pY*lgzG$daLM<@MD(172tBES9_^8>}ldm7#U&%_5TOslqCnxlD1oSjbIJ7g8ixBv;%d zya&XhS;OYK-z9wf7}^Fb<{X%y0Sh^jxnntpC84UqTTr^cpwNA5>n{W?(~Gi+g>R^6 zxMOY&4Zs!ZLx)>+Q#H&Qx0+?o-4QJI+(+soRp3>fctv3YLFe67g(?Qsu^JkM z(dcv8jW(6*1;83;(!Ec!LfyJdZ%|J(-3w^CqbkI|YhLp1+uO_T6$))N;h)|neN70gqM3T7(vDXr z&V?wiSfLkJDtu-d_|dl+^OrFJR>k`?&<-n;G%t5;6Pn@Z6?L#KvEwegQ98>c!X6T6=soJ~3VovY(y%&2NRGq&DhIRgTz>4G5ry17CsELL12Y0EHMOT^0 zAZgGC$Qn=-c6)-wHddfkyZwSI$FTY%QA3|e-B&{;*nWI9DC`Q0Ik6$(O#E#e3k2(d zb*`pFv@|TNaX^UqV69fumqRVI-P7r)AWWyxcef#704z$}6N809f@4DWPN0iLcC|+@ z_rxAStKA>@{gZtmmKYWWg-7kyGw&;>L%3IqNpcV{1Q*gu%mn#UVs}X(G9mj*aOG84 z6^R`Qh6RST zD=*fb5_N-o*W*UuVJ;hxY)$$iPgow1Gx^&=}rX;bK%@S zIS&6eR>}}A>sAho?#qE%sS@ioEThoc{n)dpR`RwEKU^T361RfE!Q7+B<8VdD zY)&Tg6IoTBc7`s$MVL=WR&$Vwi~f-c6vW@X98D!l-)5JzTt|Hio5w4Ty{^Z?q+NtSdnDGdo{SxZohKGitWft zY2#=DSf*kHsM0+6h{gsJ;OpjaxF^8Uvs9}0l-A7Ez~63~utvBdEa}j5DVB|nv8SQJ z7~vSLSlNmID~prQG5K6PE4JQ#6nB2giO@nZg%2MmqI;9#<3cS0mjjk-T7Cn%mhMaz zeATQ0D~aaFe3Mc0kGi8G+sP59-N3vFr{4~(309RNN?kG%% zbA+H+ENTF|YV0-cyQSfIpjY8#O`|Zn6Rp^fjNtR`g0h4cIzfSX@Dx|-j}{EFF4i>< z0=1eafGfI2DPzHlg*+iUuylL^P(`AJ@ZiB;msyaEO80q2a!}wmCy#r8t7SG|!7obB zs2N9P#IkFILMfg1Ldu!02Hql^ox-;+>g@Dk%~HgY1tNru&#lCe533GV@!_R*+{VGMQmfCGtOYXul(E8cMcj{P=>;54XUWQSlSOKSC z!V147o~Q4*XNo)DJtd-6vLvM3KH`xaXjt%!Qp76zmarILi%Y`r_{0f{x45I4%S|Iz z`0dA)$?xKpPd9D~wbWU`bcu{t^~KWnn%?O!Pr-{uIbag6=xWHh3v0R;0m2;I_+VEO z-r4Y6bbeK#=3ce~s?@KZ>iz`B!Mzb4pdeuFa7!2{R)bv)qFK*56P`B^e0~)^R-T=o z6R*zA=zhArKnvEz1w%O~Yq$W_`ir@+Bwn#*RL?`18m!ZuZmg!I3E9`6C}E&ku(}@{ zEHBT^-R05e%?ES5@%8Jkmrnxfm{tZ{Yjkuf zud&cZzkGhmtPFnec_8oqBu<2}w{NB^FPxHgmDeQrU0e|I%Wc=(`~REa=l?Cl>i9In z(m0r6S(h~|H#4};y^lUDN$!%{!LVp(aC$}gN^W<)2W1-tT)o(mpCLUKrpeXPCCo}0 zM~!9SJiQSr9}OSdOgIdR#pPf!6Rwr&mzaQX6$#|Hh@Gr+9YitttQzp5poJ1r4b zOQV0Ww(MYu&7JDi zVbkymJHpk2W};rv=6*n$WhQsD%Gkx{z^%}J<&rzm>cKcV{A9tJPt}Z$Q@@fGOQRsj zRR)lSCihwU%uiH+n)YmYO+|0Sd znUI3JUN^4rDh*j3pRtV!t~xp?VVPr;6QL~#zjxXFA%V-bgeGAh9WA)UU{?gjC^A!<4UvVa=MPqrr;%%;a7tY!SSwwj!(= zWKHlkeRy{>_iQp&)_quJbFXAYtth$U^Nh7Jxgrb>Z-4t$Khp&}Eg$aD%rT?^LMWggzC0W9py0B=yZ?RLN=nShoZI>sk3#%eqgI!P^srbR? zkrA(S->XW)dcId(+Y?^hw;T1SbBBR++mbnt9-RxX0?Q)9f`)}tISZ$vRxmcOzmGi) zCoj!2%7JhdLt(s{(Q%oe){QH?a_^|dL8Dp;dWl(ed}1V|3CnXidfxmV>`FGQhkZk| zVsS~>_a}!w8?PEsFj}g!WTf6 znXkfQvQE*x#3f;Pm}&H0$rSf)=zqoKyW#Cn$ET&fTi}SkzFxAG6P_YG~*Lg^oRgV670WkRse& zfqVs514`Y|EF+Wqg-?V>l&+54*|5Ie45-x%aMfhy8A_J5jW$(|d~g7Ig`p6Db$3%{ z_b>-8`-1Qvb6OF~HA>Z8I@WB|uF#L1w7DZqsB_Qyq0A0`6<`W|GMU-eRNHB7_(?}5 z_AwSx$Qm&Fs2Q&Eev8oUSI)5li@GI`C=!DfA{@ALtN%uL6SHpJ=%*d)3a=6yRzk6^ zeY_xSH)7d+dMj&)Lm{;*)isb{y&+yXS`FD?_@{(cZN0InaEm5)8wLl{t_Gh8+ZKee z1#2U^v6g%S1Xe9gl4!+o@Ns=|^6{`Xgk)I5;#ZspOQq;>SN<6}!k$v8+ZdL*+)c&e zt*ObeE^jl$EQUzpuT#wwN6je1xb_DXPH?QkYE zcD1(_&}t12lr=P-Z#TBlhV^Vk?J^t%w^#lQ@CtafpdH~UsTDm9M~D9k?;kEMVsGCe zyBbc`p|-C!*YQc?D8UN0(dOn8dfYcT69TWEn4f`~J2b3$K$qW9)s~Q#C!k}&=x*^G zUlES`xt!PTa}PMRpQoo`6g10@JZJoDs&dXd`rQY7ySL|=s*@=Kiw|VUO zmI+#z1|eE8_iQ3o|Be1DyfVH0^WM?4fc2YXNl4K>mNk%G-88s*=+PW#SO!^`3B|6W z(S1mv9BEh^TgJ04EeR!J*>rfBWYIM0h*j5@x=Zd6v=r5$adb_hdr7v@QmI}i%Tmv1 z)hJeXX@V<4z!eG_0>fh4D5|im9hn5Hl9hnPfv{LMw1N<%pVpTn)_bc2y&jW)rn$#) zu#Hcp?N_x}Nt1N^73_cx$3cE*KNx+2|&X&#&`GMV!PQ=wWKWE^FNkgn0Ymd(*H$Z{E+P!(Pw>5TTi zaU6bDj&MFI?uJ;ird~w}OR76eq@yx7puIf<&pTVNGW!bQM7>?1oY;Kj>Xk?q$d`1i z8LO4?(kmTKwVqK{BM%r{-R}RtWLW>%g7xYAb1M1VaVef-ZKM9vCvw%PRiW^z&uV38 z!Wyzp8Nt<1YDZ{}22-+3a^HH9GLJ4L`J9cV=owAMah*?NIgG^2I1mqg=fiTPDGsnRZCI}s|%3&&0@VTgJ zWSk|0yP@^r%XF-7-zh;@NR@<&9bGTPUYSdXWsU9Wf`$aatS-xhF3~H4tXjO6gHjpg za+D$j!wQq_u^g~)H6Z#-2No?2#H*dk&Qt1FI`1{Y6BNu5;$RNctG%_gXKU(4eg*NJ zv1fM6tUP*ljuj!b_T62&upqf3N+<=39xOx%k$et#^}~tvU?D|#a#)eNMx?w?lqN{5#{5eC*cf+&HVg)+GN(H{SXmLQFdjm6KMQzuRy=Jy>!!a40Mn zkHHjC-FI9mPfR?03cHykcOq7WZSIoWy%!lKcb!m0max${Uu*b0xQ#E{zihuc7i5_a zi-5%-;YuJ_N2eD@+!4|^%C3eZZ*ynMsC{F1pDsRYOV~8TYO2b8aWj4Od2{(-Zq8f# zR44;>#c&Rngld_gd^NB9pgTtO_&0mk^BQHE2KVA2f}v?U9h&Y<(uVwy1Onz_AeS6w zK}kqVP_U6v5ybdwNHUR-U<{Z=J5FC3!U!v}VYCs3IfTB*;vctfRXxx9yZzxms+ZpHwPdx=vjM|qW12hs?a1dd__BU_Yso1LjTpBol+~VUCC`1? zY^WkakSlek_F7KE(EJFNgIX4z@BQvOnA}GOzn!#(KbNomU_qFh26F<|=~$l1QIOvQ zo`&U74R-hpSHplEK0p2C-Y@r_Dqcng(z>Gio-3_kn`sTyuWr`` zZYAR=pb9Jt)eZrWTTEdI#s{A!yBi>u}}zRnMvaClJfDc5Df4CcG^}gTk=P(?D0lfLslND_KTO zy)w%?Y*=3#84wUu4{9 zMK&xN+{07n&HyZV8YZWwL9SFvNRpKu5f+_aF}_b@VIWvAW|saGvQ($K+)0GTaEydp%X3~zFPRYlf&9V%*cN~Teq z<*Ytl9qWI#YBY=4GIWjVG-r>MIcC9PO+AY!G!(u*rezcqD`3?wJ?#; zfQ7_9428HNTqn6|9O?2o;8yq?#q*q_CC^9Jp))H8XIZ35$-Qruf0_0L7SwAys7oBC zBx@w(wR2WNL4w8R31e7Z>qQsopunq_XU`+^(BHo`hV|w4tCRZGXNNgwMYL3wV^oV8 zR`Le7qKakd$bOh}E`OE-|CJ4b^?FS1%ggSOT1B1}kDpC-&rWkZTjq|AaW=6WTzN>r zeRFh_-q9!Hn_>0~zmJDs6)~zUVZ|i(D7?#uWhSg50Sq4Z>B)YX+(ETy8P!dWrD2g^ zQFt#gp<#G9-}059)rU{a@uL~NTFtKi&e-8iHHTLo(q8rO_AD{kt5q{Wi(2~`qG3{> zs!H5X^?p3U$l*m^}~hrVnK0OFQSM=yyDgKp2zp??V>VA zN6*K8OSrMWtD!KAgg2Xe*xob@X^F1zc|;ETgxLrjYds{uyUNOG{!6`{Q_ z`cZZ-93ehNkupmbhdcqB`>c>En%(9qH`~^5QaLz<5^I)ZUSaqoF442t9BbMT2 z46o{L9tBKYqw0PwiEG$iOWD=h!|1;XueEDBA6&e%=pJ{?guKRi!YnL$8X{uZSx&zV zh2zX?Fq&l^EXK=Bk4{fA6N?n9sE}j^H59oVEVAE=Z~&UcY~;?Tk0(Iu!+$;ov?8P| zEBeJSD=Uvk0Vqr8tHwS;Z2}X(%3VxTzp7fId$l7AR+avC-V-twIi3(skzdXEf&j2U zPrndZ?o)?wjq==?1K}#uu%4|lXA}hM>MGdP_yYUAAiD>G#iN|7Y^cXTxbj+fwFh#g zY?%$p?cd`O7*_XPdmrOqH?9d)K%rb@Mq#lq2WZ9MKAh%+VX*nzg8*19WHtDvPzmKxTZN)5}%mJNlL)UdQvFv%V6tBLzB`z9vJ z0la4UN1P2BQYFhmGq{_@y=+MhLw55VLuIbBD#v83nW6K&GmMs@2@7a7!uMZ*)$_YI zggqy32@|xs?T3V?rC#L~46W`t z(5uPt4Td!>ik0CN%Tq1C55K_gJ~s@P6MG3eJbFI-WF(8yO42ww)8UI2?x0kDLcF4K}xaYi?m2B)w|wxX(S>8FpwP-7)LvuNnx~J;`0G zK~98-8Ev?;LH9T|8)givU<7Mo$-~`2tyno&roH{81&o$wH3}9A_xWQd&x*cs5vzO& z$aKj(SY@}nU(X7kXJlw#eQJQM^Sy)fKh1~NUjcqju|DTmnQ8RYABHt#=`sTzi8T;s zLch&9=QCjzgcZ$LCSmc7s+_0K)2xQI6OB11%%joO9+PEO66lIL7LxnmZBXQ>RQJk? ztq0+5sCb_Hg4A|Rgcjd72AjKwHGp1WW%zztIapNQ?T~QTdUM$MT*A+kSA1o!n#aDF z!@ybyYtc0oJy`L!ITq&RoeLf|Y6`nHh5k>_->CHmy`z z-`t_r2#=ZR&a)h=_qsfZj`~$ZH7o?cg6K|$(>WiFx)-Z-Sx(2 z9X@Yt9KWOL4ypwk*7xlj-JiSd^e(6U_U@~<9)<;i72dG9%hSL#nJ^JPAYegx-)Uv~ zl?C{LUCBJU)3Aw<&IX{C*%=ygG&FRPV|qK7mgTskp)i>Ut${ExHiU5y`c+}pqL2&T zLTDtb&ua;(Uiobf)b>EIq+wYKmbDSmdo`oqWgMB=I2M|N4{!svfuFh+y96g z{li^hPQf~rVAXA174Y@=-X>X&v^sh~lXqI;1a zP%Nwm--oa1=^|?yB3^M(NX1=nH3#JCu$*vC(h=dSR+8&Hz!xB^B#I@!dM!D=$#)WZ zMsn^(Cu?_h30@?NK{7O8@gxU7AXZkAV`a|(tkPU5X(T*^=ss1XaWp)!Ae@qVh5WwB zeuj;P{}&eAM}`HL`wN{vA1pkvK0+Bs4~_%N3gjv#VQn1mLvnvdpn4Zz>qd9KeS@EF zo?->OdZkbqx*GW2%I*kTO>nGcQ_(Wko4Vr?meZ_%*q7uhe_f!0b<=$AfU70h8Y~dG zA(nL%Dc0Z3>ArLyNmv4`f`^PMu`dZiR<=xEUo5Ei@(CT{_-~i|matr=TeR#$p=QGK z(%NYl#Y7mMgM(iy!|M6+7s*vm?uf7_pM@0_tdl0J(@O8V9m{g0V!7h3TSA6n-I9id zXLkLZCM3%?YPEzeV?D1YUiTQ_chc10iu+o|ui}ObSfr>S3!=_+UJGTI0O&3Yf8YbqNFIS33HjEBvbmFuskHnRi~2x8eHxjqN2)j(AHx|IkLHH9xP2M zYt+(4xgW_Oz5~C)T=))fg~g!rD_I-VKmpL&dIR(5n>Sk&-SK{;28w30*?RB*u2E@N7!9p~ zqRHdu09iK~>3#(^cPj513pEllz7LS4l+gfN4p$dW_!;6PxHNGzf%`$-<%ncif$CAA zj}d--7KFvAP~gQ;aEOP4aRlru+f3+L?t0E}Dx49w!iiykDLe;92ESGf>&v0)R6?%q#YmZs_YfLl(SpTeZOZON#Wc|9j>2aPrO=x2 zS@^+BI3@!YUYH3NT*H#u&O*WiS{inljttNWn034%mW8Vv+T6QfSzX#j+dur=?zX#` z;*Oxvwz)+uAoD&9O#cm?57Dz$@1X+XSGHoz)py{Q%^bIFXO#3`l9^k&9} z-rjhU0}odC0J6Sue&vW2{q8w4R;st>*Mw)YV?rMab@x1QcEFEvOnATL$2m_u9ohA( zx~0m<>Tb@4r^z&UG9NjO8{Jmn^R`%4Y|L5lZ%;-x*~(@?5iC_e(}ERGpXF*GV4*y< zLPJCUxMCVAmH)DLbuVqFY4pn7R%i)nJ_r#_4NX!a1k8;sbK}JhC=p#nL0On71H)8X ziysw9X)9FltGN*dvmmmeH8)-bSt#3oZr^jx^S-}d>g+=2vNMTEOow4QH;40_=RD^q zxlc>NvWF|GSeIk$oB-Lv4>hcmEeY{SdNmm&EH(k6hC)70y05e)v_3DtDO7K>tqgeT%t@8gmx8C4_**lCR@E3v~xf9lJr$mV|^XVAU2R_fte9o8&I5`vn(- zXK445A0uW&`UoS7<2 zS%9DQ5Yphz!<>hfHu|9P7;yDR2CNvtilp~}+x_0r!C3jkK)j?Lj)r@dh9wu)kNpgb z7OW5CS5&a%$NJLIAg8;(AY@IB?CyPtwG?Uzm%Mq3Mo~cfaM4l_JW!T#jvPj5v5GSs;ep|$rD1mB~GQ1Mclrm zq+ksRus9RWr`V&KC;ySVU2ZAD6)tn)Dao;NXXT38iC{j;#0qzXcVu)J(zDymGiUS; zkqVdP#W-z^m3p>->CM(a4wwPt4qV74DbAXjoSOZ{-tl zOP?KB)z;zWumTDsVX5vJp3#|^w+A$0u`UO9IS0oU-A7l$%a_M{$L-#m-cRi}z4m^u zjV0mMmJV}1QorIo;psk~UdB2(HQk*vAyeIV&v(zy&yg;3!hWxCLx^#(^-6)G&yN^1 zdh|*!AJriB3Jnym#uYV6&*&y=RHeGZ+deLpeZ^+NxvS3AmEGec%-oO&f_o>O?)akT zYPy=p@FwT5;PGnJ3|UhNi)qL($(^eELwXsejA0S32xOTM;m42$Ij|bm@ip?Gf!`Z{ zT)_HGhIM-&x-A?W=s(FBxZ!Dtd9a?y)(}D(bd&SJS5Vkk_}YwEp)cotlr`G4Q$k}` zfn(txZ3K$N&xrt6&&0a=G%V$fZcI?R!ZRrD3ndJN{#&#rq-QjzHKAJSQACK02G%{- z;k$BgAXsCLcrnSnJUu3&Rg=@bSTn>j4J&1l4MMDxm)++LvzSvXh6R_D>F$nniDB8f z;Emv`yxrgAMY8V1(Me}Lmh#{kR$jW5xfxjC>i+XZ^yEy+>~8exS6dR+P*cx-dO+3~ z3+gcdquz@@aAB2A#X4X^J@9I0hd~V-2p6q=qStePx7AWB;qx25(N~cX>wD9$R%|51FH*6_ zH@(r_P6!$44$Q(4p)sthtLXH(6U~M0J#$Eddxt|`l}7ipSeC=6DZbLCwuj6H@54%~ zi{6ax%fKummRTE?P04yBx9D906&<6E#{0%MD!Tt3iWRqD-M;B^|AJpV@kOe!O2T{I z>OQQYaMUns_ye;Vtm{h})@U>lGRoaZ*6XI38e#(>Y*}V(SlWmeQA7zd%??j4xsE{gSXq3wQGuuR*04R2@}eRJIt!$K04<5c@*aR2$*zth-oapG-Qc;9xI zMWEtjsG}SVgjSa0p3<+Rx<40OVI=(fk#2HUg77}>#zO4}b(gc!;qlb64|KURt|3(ASeUyZ*1P+jW|^S@ z)=~3e#TJDd&A6dq$=-lh6PyYspkhq~(DIS)vNwQaky9=3j!@(Zw}d;hQTK#2teh|l zPAm+8LM+Ah;Vvi3EUaX??nc67vR=PruFTk_0Tyqcd6*Ne2*s>yQHVfdP%PpHaAUrk z%42_ryW~98rhL>=pASV{$~VsYlw=QML5#QLD~Vn5p~9D%w;DpVr}|zm3TfO9#%~By zSP-HrhvT3WEDVHvPQ!Xu#*&cCY8qw+^m`pRf<*_G#mgMepx|pSdi2_e8D&z#R+~;N zn%wPyC@iV&5U}=jNJ!0{mxRc3KU1oVoD3}{V(qq6_S`xG!J>kN94ufK^{bfC{d+$X zaw61zFxnGtax-X|SkSF-gu@|_)r6tp%NMCu&F)^EORFZQ1DktdmDW)atJOr>3|Sf9 z=!G?5UscW&DAttS5wc2Eg@hakAE|hPTf)2MWY8Vq!;uH?8xF6&)zh4>qgVqza`bk8 z7*?z{=SHHtPM)9iGpu0?8`U`>RQJ)*Sbm=sQ79P8jPCE0hUJa!O?j~Hd!&l@PQzyutZUKw;dthbfc5^38UWI5KBzv zNlw?ov7$wx#r4g5YBmJ9Ysjw%hp3p@T!_B`LfpIElvU+8oJvh5i<32#5z^N%J)J}@ zvh}CpG>3);QY=TZW@eDw2gq^^Ytb51xgR8C(bWLu-OYnAx})TaOG4yfnSw>Uat!Ml zs{5&2qi!7h8Ee8bhfZg^XRM&mE#XDW9?X|%tsP-WxVE-NrUgrbCAs^N&^)6*ut{}O z)`m^bu(T>1U$J43dOMw1o$>f~uoDBVRccvP?h31k^jtM@n4xx6wUywiPiJ6kOstEL zErj@xc7^f@xf_yHm+pbYCTBX${$|l}}hRJ+v#x&!0af%bEv4 zvA{(x>BB-Jp_>SkcA!JYDC1=exQgD`K+zpUYrd;9LctZ6gOuGEAM{h@vOo6ygyH@F&7HCqxAvTD2~#8pl$DyXOEj-XLu)7^V5gzwm`nu<>_P#ilgRHF=TSTmnFRl^S;BRsqZV|682v}C1 zy2~J}3(~7?&V;S)qcu*2a54z75H@;bHmo4J^Zc2yeNng!!0HE*Ds2j{u5?LAoZ>0r zT&K@Ax~e##P$+j{D4S~WdJA6(DfxS?8DC2?y zut!Qr);W$Z%i&8ttj0)VL2(zfQ zPx!nB8w!7k%ne~ZXvfdZX1{TC$x3tlIM^ge$?d)r!Wt&*ec_o;Yrq%cl#we3R~!l* ze9?wQ$7rQucR3ZKSUE?#vNSf-xg=DkdwI-yRL4I5<<_S$UFX!9)!=5rOKT&<9My%E zWq?(5P}X-z=pK1l8)z9-L>2MM2aS?u8Gq8BnfxA_zw(i(l$X)OIa?uiX>PasoFRE8 zqI&uisaCf*sa)hDeeNjuq6-V%6ZB!J?s;8xIqTEw$b^QWf#JwcjbhCl(1_(A>)*Hj zY7A@7&InPL!=wh-Mql>)B_V?Qct_~4s(1b31s8-{*IU{Vnu>LOy?c$oQ5Mvn?kc$N zf@g#vS$;)GQ-cGn?IS5zm<^#}siXdg>3uXctf=cb1k2cq%@ZpM8kOuW>D|$&Rgft% zD*QgzsjhauTTRSGNevFU(jDIBB$zX*6X-;G%Ipjo-#QTn!G{I1ER=gqF$Jq&w)VRP z&!~cHR1%heOTJO2xi=oe)G+cVU=74WlK*e{#FsN6Vap3xKi&(q&-c{sHL7T2L#tt< zSbi=HdqNpTn;x>fYxIj+Lb9r*jc`Y}5!((@$s%l(7UH#p;U$C&pjsq6$nRV2NJcS#e*(9ly&dy4U^t;`b(9$%-}3nUI@7`mU}L62>q zGjv?$b}j}7ZS)J@g}HE~!#kfn(%nrB#H*epoPn9h&b3&NV+nrUf~=T?)!ls@Ne$Q* ze&L|Bbhzp9?%Mz}mNaN7m({wV>Hd-TI0kLqh5=O$B1-esqhikM(xawyQb@FiiL+e6pdqX8=?-1)?SzUc==&Rwwk4PG(5{*Ix$Wk zmgv-X9l9Je7Z#q`tSj$^T1-V|3YOC=0v24OsU_i&9)?*3!;_ z^#4-7HNCm<>cHm#)<s$nW*OfoNXnq2NKVwtOf zJ}e>@zl7IU>2ddRuT;aAR)a#SLLyx4v18#Ul-vC>$7~HK%8`YXiCFG&=rqjI72!#h z5n3amm*yB=39;HcJ8Q!#_%gier+w6-8v1MPvW~{9oJ>D0p_5`+*cMKj-JL(K=O*R! zjDC0Ur+PG$n#4}V{L0GMmGR@P5#alvbBz;jRBkTFpk`O+uAxiFYH9VQ2 z1FQYj!DhgkQM1>LMf-AjamU^Z9P5{8!eajf#=>pDm0dk=o2vnFqh@Ki-3SB=My&O9 z297q?8ylrYX`NU_VkJWZ!ey`?+?3*8S>Z%zl{q(`vnmHA6e}WE3oFIMHd<5(g=`IO za^Kq0YA^s6j&a5XSzB9GK4P?tPln%(JnX1e%hvA&?oNY6i_&|! z4b*BxayuPZF{Hsdy_)U_&)N%)g@IN*Kd1%*yuzV~;6jqo6SD(>?wMwvpnh@G8I-0IN(NmK#RPRftys!@^7$D3<5=Wu>-5wW_vNJF+$)2B7K~af&q(@XC_h z?Rt=a)nk5!BNjK><5xLn{gChoDHh!B0j#=Baqm{P%(<__hxPQphXIQ!)|*c) z1&FFo+R8A&E;-)~v2sqZ@{_57kY&%B4A19dF7o;F%PIi?X9EaO?m8AOJ~3K~(#X6{aKOxqz$&_qi`LIkAch*bo-sYfyaO z!kLIy)jKA%BMggn28+T9f0o_WP<}|hg+m<9ggVSY-^Abu65Zh!9bt-lS&~&pLa|0H z%zdQ88Yi+E20fsm;|gHw$`u*0Jg6Za6mwNp;r`LJbe3FFKn`-!) zkJk2i=U0WgIqY8i^UbQL@A|of3Vj_f9jA*d12F5fX3rp=2JbRu&FJX9|n3;K>0<0U0 z)=0?0=l4w#*E^4v*;aNR#zA@;up``_o4apeqjvTj9_w?sBGgA11sm%Ds{&qamgE|h z+|Dl*ruZcb!XKG9x}v)rmV5=wLKc?E?phFe)60xXFZ(3E9&940>LV~&0QK6Fli)~)c2%vWqN!b zwDadcsHC``!XSumA7424wL~QU?ZAf_mZrkbW>|YeW&C3gV!b%euXf@Q zAtZMMjVf2>{_i`#2E6*=nNFS`APh?>4KL@EHp&%Y1LDA59*wCNtKHHlbj z=4+q_3y#q>cBrmd8rBN^42DyHtvhx|Sj4JuYvNAvKU?xNU?42pJXkFk6)97+c!qQ; za=Ds%tt|I!6&db>hF7W@Y|Bb)hqT_t5io0B2HoRyn4dvl1+|?)4J@Cy;+SP#2At)f z*GrDk;}>+969`uKba~{cY3}{?B-7oVIcivjEN*V#*>f(bqR8dqAx_S(p4AEMf$w%{*eaT4 zVGkf!IV$b^M7XSU!k~*i6EPPV_c&HVnDx{?F)W@GUhx3;ZaPR&_)L@gIRI4v zsUsQ*@%@Fre;t;qH~TRxJRD!X`JXkcn2+52aClrwO@!BvM*XVGTI$X5-jxJ3+!Mv> zODZU)!y8oGl{Py6f#kj^2w78R8?~vhK|x?YUgtPYG2ZudI23%Rzduo?#rs zUCv6wH8$kW`Db>Z~mYPj#O=$LuR*BlifSj=SW3 zs#{j~$6p7-`eywj3@g&F4_iq;DPjE?vEHOd!t1f6zRPc)y_4{oT@!ZMX-;&x-|I_B zSuVQwTF+N+x{+|oKz^}JGM)U zSd$7jO6Hti$39VODQ} z77fH_I2jv0hT~e6EDVa=Xs@E%C3(PHQx*t{SG2h6-`>-w-doWFp_L;azNYAIgE>npTT3b%-C0=JT3Fy^NC7LHeOm@t zrBcbGIiOa0ESxiT6@Jz%^9<`Kg3m`-d;YPa=pdOD4Gopi(YmoL6eOE*0Wy4mrOK-` z9|$=|4+}djS$*m7k$023ZxF^6LQ$-HY4ctMN;OE$YVfuqI-bfI?KRt|--P(QD1i0v zZ!xR{u>SI08rCU#WpH)rEMUECO+Mc+#a+o93+D82e8S2`P0315LbHvon{D)E3s#-! zM_zqO&@#9CMAG0F{*m8SdZ8iW6F_5Ct#vx!V#&KpvS! z@lKfKFD3x>Zm73F)3OYiu9?vxs`FVhxOWTjk|+-1)f&sm+EtnbsS>f8>{O0$(%X@( zyRU%lRDB1?Dhv;|09HY(6KLxLzhbe>Z^SF26e`_o%b$o=QEm_a`F-AhSp8IehX+FC zbI^kYf`x;Sx8U({_#FVNTrMA?udlqf0qW6;{bqq`T`EK97DrdgTW9d`dmZpjp$mQk7I5 zZc%zf)hsGMgN@O*!+{kyQ`6T+`||E^=d@Q#l}xWU$|#d#i5$!2P;`HzEaBhfvgB!quY_Ih}>Mz_BiW5wDWhJ#o5^H=Jj6`nM9$hE(o$2ZHdC z5S>_A^I&zFN0b_teRj8yDpTB*aE^&WjaFnW%_Cz(b|!1heK$}Kjt+PJ z&vqx?GZOiJEZl=*W42FUc+|?U)P*%%BfT17vrM3+wc_%|M$t-Tw&}qlUZGPaP_WP8 z8r*;Pj#Z<$2cI8TVQ2Wj3?V5N+0`*D4ZG!k?(L!rOEsf(HtfLH0QG8R$5nSU_bt)b zK;fNZIdHg_-j=pX79?C$Ps194idJ{&SpM~+zY$_9Cme;9O86a+Yg$#K^`m^94~7u1 zI6lE~oVul&)2JPlsO9E%7B<*WYAT5mjsn8^@NU?5ogRjCGLl2Td)iH;F1cHsd#`%k zNv>>%;(`Izf6uU5s@%`;tFIq~r%uAe(h%qsXH<0x@(>i!61|EVmM+10@4*tm^6Yc} z37U1^lY~kW&U#X9?yXFT`l3zLNUl5_kdW`gW$yMsujAEWp(ox zaH^BSJM)B1AN{fxtnOsg*{PN9eMyq{u~a@bva3b~qqqpOHk8v8pF?Y3GVRrp%Ym&y zxttErtAdI~30Z|gApxuaRl_xc6(p?Ma*gH4e{3N5T%1~V#9H28-p4cH_I^ODk8N!a zs{7SXAX%TpugI{Vx1$7WlZv}sqvgFa0IO`{6R(wfM)Y}w&xA{muRyK5AQ?}DOysO> z{hh-(rMD5W)YQOBP-b`gHk_*1kCkBonjp9fuqqO;bRY(;5Vj)vT0vC83|56tTQg<}t29Bna6hK$cK56!?o}?gcA!Z?J5X%nFK-im{l?8PH_TK#OP8Xck=!ot#pgVHA2MYhEma zDsyFJok>M4YbI*#BwEcGtM{Yt^qL#50>$c#HKQnpK+!1Nq63qfsGqctN!S?%q+nT( zJDsDnj8eyXa#F*3Q5)tEAzTe~Hq>g{Q&Ujf17)?)^YSxvxodv{5?0%1)cCBM{^{&yBRC|wJ0B! z=LqK(OLcQ#&1pV$t`3S-nP%zeQC(0qotPU4R~pN47imgQg!xp;?m?2Pd^&Bd$nANq zs_-#L)?p-~EZuwo?ar3jX9CEYK_zjk9?=A@|i4-!{M?a@fg{U=?Z5p`}(Go=I;ER2tRJbD5 zlEZ->QJj^!12LRRu9fs6^Z&KkAY`@7=>lRw$O3fn9;|IF2fQj`DQA0Q{~07LE~xJRi-5JsbMRBOddzYe8=s(dnkzw>uGxg+ImLs%&WIhw_tOc3{mQ`9XCqqCjw>FeigcZIK$|=pY6k!Fh zs?;@>6aFS%(I_ert73n*PglI7fv&4t)42D@uTuG+>1OXst7nv3gcW+;+tuKnPfLBL zt)UNNUeV-!PyEV?`+nl>*QZ7-0Fz7(gsJPjwxN1^@c)ZpeQTor%9S%MSXaNA&AD-c zVO@<$Lha@B_(8}<_a4`;dTvIz5?0;B6Jh^)($=uvB40(onoSrL;cND363{U_1MKb) zv0?(+E0W2qB(x7bw%v)L2v%qtothenXCZa>;@vg?mNhkCJC#1HfLpl?RIK4~^trQm zlougqpF8}EfHhzt=m1=(#iCbK{m28!VVIS5G^@ift9e3b@6fWkQSL4|3nc5B7m%9v z-lTqY%`=Ahr&-DH&2DE{S^Y~D#PMR}Nz9FDCx_#ylX}6V!CfgrAE+ODLf9(g#)(!> zo+KL9Fa#`gjgnfa%spI#HLMYC*KFF$ayf*n?dSVH5U`#<`v)BjG`fF~&3*Gjb$7SA z8|y~P$H!LLfO}AHga>;oaJV0;Xmsbm%}Bbp~_Lgaseg zT1!2$myPO$5OobK?wgyg1e7{D60dp{m=>->SKL+OM|%TQDoqd817hLu1IwzkbGxhE zYuxjuxLZpD%?zpD!M?bbb5DUBZVjb)?b9Lx#O#gnjW zoVQ_)FjZiQpVKVcBxC|QP^?bb-fibgb)%fAr<%kpAsUOjv&1b{88@kBv9w{v4D2zI zGZW=@ug&sddyGbN(6FV!o#Uz5PK*9DWf%4Avym%&b~FM~X@BCq0TvAnV`ER;=8m67 z$w@ezp`U?QVT}tEcL`PiElf~YpZm64?wBQf&i_^(JjaNt>Ft}|EMtm0plVkSguB?L z$F`SzSOKvPoMNpU9LR-ru%Kr`tkbK+Z!NwKu9ddtRMxOnVm7Drb`Dro@>XPil^m+9 zzmEp@X=(2j8XPLvpFj`RG|K#L396`8-GWl}D$ND@X|u7j%N@E_${q_Vi0aV3kdl6t z?n~wKdFyEKnH;HCgMUlpD{sZJuR&QEuHQDaLNw=syb}I(_kUqnrG{4r&^2qK(GK<7=9j6?zs!&UODSY&W&e8 zupnY(lA90+g~?}|prD!+7*+?H-Bmnl(dTBfAy1UTIoP9^;X%p!X4V8{+^UGt= zGuASr1_ygU%xa24{s)|n)+a+vztilZO?S96^E@fzDBEuk&q0)k^olt`T!i5m9HUzl zKPc{NeI8Pad(q@0IX;G+qA7c*ymbK6)Rs-u~3A? z!JOl2Sw#)yz_Jd@0kO(u^)wvrGL!Qf<6f9ig>w{L?kl(qxt_X1utM&6%f<-(BwU+& zThf3ktfO;t#;_KxTjt2L_6S!z3C(^Lz-n}~ex%E=UFD;xyb^=q;;RFT{zKliwZxTX z(P>Dk>={ysmy(R)m9~;JAL{EQ0A=Hz^R zp*ynmbFa;(Z@NlIn}%L>9Ca0z5bnq&T+`qj&gQHskL46t%%H&M$v_f?k5_900#XA| zl43q*UWWyoWi24cX3gO%*2^7RE;MGl(R1Exb&7jN_THz?X8q%Wd#1dhLuJKX&+3kc@ zP&nv>^A%0j;hNwT##T@pkEB%GUP0~zYc)GZNUSmll_uRz9o9HPGdTEcz^ctRYM2nk zsC0#~=M%A5%m=LX^*NE%qA4Wfj(METl@(K6ZR!jm=Lk(ZxO4oGLils_a$i!m{mc|w z`{rXo7_2i(Vo`@BgMdeFPaO zrTlvwSrl=n7>&}juM&Ky+@C$tro2IYKjK6Anb+Z7VK__;4~f9#sV zfuwKeuIq!3m_9Mj*=Ni@KU%bNga)mKm2$tYW>|FWyK1#q!=SE)uR6%;;_p^QZITUQ zT@z;+pq5&?1Gq-a6*xuZ=+FqHSm*`Y6tZs8tif*vT?PdztPY`*y6NDDA`6-WW(jsf zL)t;m(s7+>)iCtf{*Wf6JxDbKCEvqLuWl|7g1DlhUS@ObU{H_nSZXSxexm}eu#_QG z30B=~15^oO#gI+^JT?*lthx2|F6QMho*sy0Izlvr0IcH`=&(dM`f^9llyi0N`?vte z65x^&>uf>ta?Xw{b9Kg1Lcy!IxPrg3S7+zGx9ut{k&U9lvL+2dN2~8Fyi=P;ZH@A+91(PCL^9OBD@LVKJ5-ZpaaiJge;$ zAuH0?&)`&ND07{wgK|R!mWmlf+VIUJ11JQoSCgHAdHE-FhG3z-ht>EI= zLrxU}u*~KHbM8O%`@w5aHjr;O-*Z(Z?>ZERmQYp%4P=RKl;(Y-&|rz;z0Fiwl1iwF zgsR69BP?heoS(ZZuG-RYcE^Oy5LFFn*vxcHYmFt=$f9u|LP3e;I4Ya6D$9l(z#+TE z|Ln0)b)}mX)->y?o@r>WsG~?j->&h4)@W49z?%@c%Qz8b?&9t>ar1O^1pJkOEHs4A zgR6wr2Me-MadclnUJjj+xh*dn&^kWek;vyl$O6{!672f~u%5um-BeghbQ#1tr#$b@7|hg+d^f=YhYP>hw4REoN9Exax%XO1eQT2a>bG*t6G4%mPuRno(zd zMea&ytavoSWkT_8cZe0ye6NVuG(;kkyR5RfOsI91fvbP)zWIXAps!P@lhmuv*=0ud zNxh!=9V)ELf#eBAt5>g2PEseYY8>7F?CPv`&B|%eVd+#(dop!!aFAN-b>lgMI!cHN zON|-^Ro3u5p(>eLTAE!-C6#+Oh{bM@RMtS!@>sf9=(AU(-WQc_mnv&<40i6&h=P3w zi?w`wF58YzUa5PZLf5d24oXD5wX{G>Xxbia2f@6Pdyk>MGUz05HK9e8PCg5bb;`LM zt+0f47k?RG)KFSypw+++p*d7wrE!a{um{dqJ%?4qw_#o^$fA{8I(aGW!QP+xVZAJ&l5G*}syEDk=OJ2yMPyDt`#_=%DA0O<}1*1E#g zI?_`&ckW>#hf9PzD6ZuG<<5p3nrl?t#T}hVEP=6g|UJXV^y-md|6U7Z$iI(KLK`ka+OyPT6dCrO@(F zV403kN-Xgj^)UGCh6z0jTwb)l6Id0$9_<85#Th{#H~%79DO^cI$WD+}4V=VLz#{D) zr}~PMgc>^`$aOuUzI_5wx8Gpq*?dJTW$5NE9M z<;$txc$M&SAcxRkRoQ>CmQ1$%szyLspZHu`VaYtsTG@HaU&BYUFv{UCJ>tgzl& z(6ZZ7A@9su!ui4iRamI2lyx5vq*~Z0Zpg<*QSKLWwmSDo4h2t$eD03(8x^U$xxrk{-JCrB4Luc8IE4^zG=PpsNKwLfkRR9FVC;&II(b0)y@A6zsNX-o&`Uda*kQeQ(}aU-c7ZTi2-iPlxIFK>BM&&md+qn-gvXL$ z!m(n&{xiG0s4mG0TJsNo%7z-=RAom+Sav>#dWQ4hw`NAWHqR@;@P!J^8cMZ~HP_b0 zez5NAr6FsN+@W~YQEF+nmBi6q8aUCtOZ0QlJ>4FX(jkqL(~Maq%cTp1@cYwPLqRDm z)d*VSl}zK?KLm(k{23F3LpD5B5*2S&>-M-&F_0ygH5Vk^W8y9I-TJ+I_v{bm1~4EG z4r|9cVf~Z~KH8I|<&d&Y6^08(1Yg%Qd{== zL9A!)$9SV9bB6^Mn!*<-u*!`GB$O{C#8Fg?8dzRUSrSW%toS>kmlutDA`{(;%6g$h zKeu7FtY82DAOJ~3K~yS2c^df4%8F$dV!V8;iux>8+zQ<_GAD}s2^EfNs+XTes0#N< zuvpR}N_q7qDy;IQrswM~LRRr}_nG|_tAtkJe!&aOoYXlax4YEm+6rqe*JSVP>p?e{ zqxlm=EfiPDLa5nOhI4)-;eb|I$y`2D3s_{Y>Q37Yb?+1I%G@qxo4%)($`7z=xXPq@ zgH~f>rP`MguGAxGWmGg+v1$#98NiyrfX=Bwx8NR?Q|jHtV}^YDP_26y>(+t+Wsk}8Bm5#9fuTefz|9UoL;#s`=q_jFX+RufXzWsa=c389< z)vZu-LWE%}^K|<~-6@p~)K_LJH$S{B;q2Xncwr@oQwf(!Pk))XDYCr3na*#j^_`5} z&|F4Ktk$Vcop{DwXMcYy6rvWi`un4H5IXAc%7*3Kg43uj65jF+{CrUZbPeLqAllJg z@$M5L*6rUJu1fbCFVm+;&~Y_vw!K>kV`-3@kq=O5U-DX&&cX|?>& z+>}0bOk0-DB=K4B>TLh#gZ;n{C~r3Z?O)1KFVY{%5=4FH|l; z9hUG|iEQBA<+H&jFn=YPLh<2U0JFRxZoM-FmLL>~c2Mn|s=~5igmEh#jWUs*8g~Tc z;6nBa%28b(L_-Lx(LM&Kic(ZVQ`H445>fq?0jqC!`zGI@#QHL;cjiyUt3UnatFO$L zQm!B=T);{I^DI4lB|!i_mGPG+=8^pnAIO&pTzWerI@K=yzp$-T1U3QdSBX1vuK4jaV&^vv`9s* zGTKfBVf~`Rd>B7WAw^MBDpYW{Pzar9m8>{Or85NutD{itT4iP$7)m5mC^RPVSN^zp z&bjwK@7wrecV|a7)--7vP4vylz2}~L&JLX#z+-i#?FmE*J8C*Q5)djSS6~HuIk3R` zH>YAZ-TQj#5t|bLR*#prBYa}ZV?p>~8V=7_vYqXrKbxx+0{jg|wnJnXEe3zoyH*kCV(7!J1% zLtx6uVDF4PfU76n-9LS{ODIkaE8HU-_OlAtZcBCb!~D+9TH!wetfU4|Y#v4Z+t&f3 zCo-9Ur6~R!s;+o~pdlZsu%@OKPvcc}VQgY??4J{K?Xxcy0dMsIfBxO?rj-Aa@A| zNV(Sz)N0)Gmy(`}Z9)snSsxP60-JTYEur`N%)Pr(Wuo+|s-@fo=u>rc)_tz~La6Xx zE8VNk7mi+AQgF;Kh4lR!4_=%hAumY8m!|`g%w)L>Fo80b=;{rUoi(-noKCh?)thf zo1}pf1n}d*eFw$5k5YHvBu2Ipvb3Xw74zo2FLlz z)7(A{W~jgl-d{E|nQeEPenv}oP8nhPo{cPgER#Aht7xbJMgTi5>m z4Z2aN8eHMz+tBDg097&=bU@`Ur1riM`YNUC&*%wJDXC-M-IQnA<eF*6jUxUl~^0Jlg_M6C8Oa(n+ZJ$AT z*{|vGIX4vkGNt<$*X)6mDm7Sk0Bq}C&b6~wb7~s!1xgfPnQFB4tyc&v>6B1HzL-G~ z;8o!{iz``ye$jF3mOadpa#-jM)02`(IGzsxt3O@RcDYn4*=wRS-S1!xI;<|Of};Nt zv{L2hNb{N=pV48a)Q?cmK-UId@>4>l4fFZT$MEw0G63G&?vdH*Iv~T zY8x;o?98fSv{TfhTk_(yM2dujs)kE1^@d5P8p}W?N(KwU2ALAZbSem-N+hzo;>`eE zyQ|iYJ#g;Qo&g?MEwRDQvO!CkgnLY=cCc8zzJ-jIduMw3WG@F|EPSow`#*gSSSyra zQPl8q<>7GvSeOq^&r^aWQmh{hb510qUJ~kg&hQD?BF`o5fQW8xCpRlP#6H$>QR_<|28V`HHAXK4v3si3CG4J><#QFq{6~3;pja(Qt$mP*aWaL z$5CEwiVIlLxE+cGhd+{5U+0;3R9ErZ_Bw78ikg8N&n&LmYyGlw9M?Dyq|9ByQ&DcU zx!S6IK(+_LSmDBua9CvB*CpReDy+-ouuA6@QrE4pxq3?9uzen0RaIStSbwU*@{xr{ zr=_EM%hmU`pHt&0_b}-Wpga(NnO5d0dtL~- z!pV?!6e6r~|K!Kh>1iCE`8iimL3(w-gY`)owxV4Rru%pF)%T-%H9Y8gAR_k>L#*O$ zjtQHo8uh(lAZuXovp4T!P(2DPxQ*8L=-2p4I4qhrG*g9DZ%2PwXm=YDil;lS6R@JO z7=34u4dI{$8dAfnvRF2V&kU!49(=guEY|P4)(R?SCEz9l_A1N2{ar-w-ZCg*h_TMB zl~GZ#Xy~OOP8LDW$3cBH(<>$oJw1Rd7L?@*z(Q$dpDUiODpKS=|6pDWN3oU@2CN^(mVDy)q~e4pIWD*39# zXGQ4pPj#kmzxCHPp$lRK@{3KCJb{~8^ZYY6q5ouPGqY?aG}92OpK$s9+` zTc)AaGk3ERRgd5tHN<*tMW@)y=sMvGahK7|;o>u+Cwib8{T?+|v=XrB z+c&HWIVYhCYi&pJQ+Ehh?$ZG4=+kV-x^Hd}U!-Vog_dx1V($ZFqkHn}JlYfcJ}IwW z?a_2Jo@#X0sdxt@rS7KgHma*=V_XIA8uARK6}%c6+g0RFp50y3X0WMA6rwU9Y@%co zCDx;M38Qy_HK3D07FZ6dP+vLN8j^S~*A1dE99sY7(ptjn7hunos>fD@R0tJ{XaBRF za_7}$7fuPQ&IK&JVe_o59F1R%zCV>p7y>N!ZSz4&y_$`>TFahBQCauaj#j}dQ&mON zT+ey>B4pF>{FX6QIr?FZi|HtKpC{9=1Hf|F6aYS%$wDq|g}mKKE_sN7BMjQU7Vhfo-gFRjvuu*6T{eD{G)P%xpoP0Y z8lfwM_84F>3Wq9ch~=K|p$9C9_ZsF3 zA(sdru6V#&TT`LCoMZRdS6F{vraiJ*jdC$ZRHOTzn|<>Jh?T_V^8#0L;N|YwUg-zX z5H3tjO)V^LtVRP4E2nscmFLyPv5)SyqS(v8%U%EDJqe%yV5P7DO@o=#1aB>*_FnA~ zv0RC@_p1FB7YS1ivqs~uz-!fsW8a;2$)p!`L)=$c5QZXk0=$*P<18r>s1MR|G>4;DYto84P)F7E=4ZmC-VEMXc>B3u&&McJ9nFYQ(w<-Kn6_zEe zK0b2|T92fonwnGl&%PzhRp*Rv58V6Q*&APC>Dsfnx(5W-fp>KWT6J`2{DkMX%oS@g zEiv`uA;2ogtkB`rIN-{i=c=D@B?o^Lx{D8jP(nd0Y!j~OD|T3Aqa)2haE<{My^(1; zI^0cDneJ|)mAlXv02VncKPVLMK3^);Q-+mg#FzLaa|0Q#jhxxKgT$gURsb;!%GqTZ z1&1rDMfKZ7S`rdkC=H<&RW}(Ro#hpAZMR}+%Y8#+Uoff1VxIj2JVeWiXfjF~eBOLn z@T%TDUl3T`H?aSF0`}emmTItY8WyJp4_Gv8c*&g{Sh+jQn%fCl!ey(k_GK@}HG?d% ztko|j_qXBazAfcdk{(!@%#po?5v`=enwlc*9`zj7x9;w%w)H%*I`(lf?>a)5_Kl70 zjcM=cX5{qp)0r$JAnc#-h=`xB_w-1&a=482Agadrw-&)qlG*R zlZ9CNT1}d0<3`~lCQjS|g9W->6j(s00Xp{as>Rc{iSi1uUW6+ZkbZrME#cBd9C^T1 zUHz;UvZCy4kh|^+uwVaIKP*DjTRm3JjwRGXsaUc29CjQ%0DQFd#2(mZ3jQ@O_VA+LVr@RC>~>;F*zI%a!&_|6e(r1lyrxbp-wJ*6OUVk zrNS(Fx5w*5$&eywp(&)EU4`vUHY9BK+J*rUHE5YNFyK&Y{kt|z$&uJ+2~Ra^8J_=t z3M`Lj)o;&az0Q-N+WXPDEg{edd>23QSBU$ntgsX`^JfFrd%f5Dno2{g1_P{obnjuKy+KbdBB%HqLq>!W|W9$S*^q+#L|Ezl?Ez@rS+ek)%dh z!JvD)1Y#fCM8uH9RY>sW7Z%*Dq}_t<#bIC|$Y!#s{r=Y)_?3Ine*vHJ zn(dw^#k#@phGJg->DApFNV_|9cj+bUFu=l0*zeVLv0!zOX1T{;p^~sQ6iBcNt)gM= zJ@9m(wKZs0v|!PA_0c>Hp+cuz_6|)6$dc=2dK=hQcsc9;SSnee$&iiFG8<;-Xpl;r zgahj{f6d=|m;>Q3n^Vp1^%Ro3+~l;57{PMGAi6a;4?ZBxS{YecxtB^;f`)~_KKHUJ zENk_Lz_3{DwIMNByWzH7#5d=v$ON_Xd~QN`(+k_`&1xUC?xdBedr}zl%Ubg zbb?~3t6>HzRsgIYQ|a0aPoFiZp|sT4r~D3+`_le#z`Ciy$jFwt`44;}BN#dM9LxQz zEsh+Oa_@`&?tXbG#uL6#>#JwobEIcE4!XEQjN2s1eKHcqs5DP>YtrbXq+qdgVyL}a zOX-KYhb|5&!Mdsu?$^7#;J&3l71e#~#n!pq5CTBui6fVQoFxTV>mM|<`5BjJE zHx zl_X*@UuG~d67nI%Ij}Yq7%Rid93WN#un1KJ9SQgL25nC$QGU4$)c3uz5Uo8zQ**NN z3*huQ5G;m}ivPV_R^dH6<~gTc6Gi zoJV607KIM4-f>Zgu)cXyuo?{S+j%7-)^ndLx5Nn)Uh;d0m^3b&GsKANtmy(43p3qhXb z1oV^OE4(nEfh8Ejc82|t8rD;kR@+2aLAXqT5mL<_a7C-siRCq{s9?S z>!S}h5`aYkYjt;FV?!ELca32k%nM>cad)q?T1q(Ozag3tFe99idpS_{tD0g!f&QaS-7$Tj!OB<;hahpS~QhY@2uR2dl^Q$zS*2iy791kcFju zyy=v1WCg+f!}KbtVWsPu=k8P8eQ8ebm3`Y2$}~v8^54Jn%RQ=LE&Gt<9;qd~?f)Wm z?V;%5OqdYe*PviQz(STgRd;=(hBfY&g!|*9Rr&GaeYVpx9N9g+TZ3cZjZW*U4;t2B zKUMb*k64u33nII_A+eG?%?Zv1?g|I|*8pH~AZ*R~ih4manFz}gk_9)G{&6elf*wQO zjH6vVhlVr-05ejQ9g_$xw(QV7I_Bfsvl=iO3=&yEDM`Pg?w)JS3=f!yCG3iTW%Oxa z#1P8?6$e8%68812*xlU+i0>b8>0`80G8|s7j_pGFc~HomOXYHy_%ifnF7hG zg^BR_bB9=16GC%;C40i{SBu-5o^x-iYjhDa;gh8RSSc~Pvogn_7R^^B_jprfF0%hl z1ly{XY$SBARi=&Jj4SDin%wz}qbg8JCc!osu%b4k%s`crgweLpHo;gd71_~67zuR2 z<`Ah{)ZaV@f+h7{K4nx~qrU7JM>%LvWqzM3S*)M@2N$RLH6Bf82d3`{iCA{MqYJ@b;Q;{H-iJLw;O94YiogFd9*_0 zsKcsvYdiC^zs%aa7qXG3uplI8y^>5BKWud5vMCTYR1m!SYzJbC$*x0P8Q$ z(r2-<1Pg1Nye0fHhNWSn&+LTegxco|E&4}nYPoP!#4^BonP{Q7B3hQVsJ^tNf=cew z|C=`Uq{E;ONPes&iwDoPHsVY;p)6~{0IS|Caqf;{O|Y_UG{qRSzxXV$F`yruW4GP8T%n#CvHRwLbVGt#%eXWN9tH1&Z=}-mDvY8NwVWeHEFoLBi7`rHQ6Nte{}^Nxzp6tb35%%~<+jeZ9Y5yC>E+c$)L@*M#V9B?D()xd!eU?rOS;_tsL+MW=0_Zffv{3K{twRD3L zR!LWcrIHjr6R~bB{jFjDcU8oSIS(pa!QlR{bTi~Dco|~GA;&jgx5pq=WLPmtRupq4 z>~6m#WfQ!?K^`(zgiIcl;?$^3%IPI)6w!U{Iuu6Ioaz&>XeAv2#R6_YcGo!f>s^+M zECkDsgwWj2YfHF)7Fl|EoM9cDEn$U=!ulU<3BQD4QDSdGDonjrdv+qlN~{SFnHmCM zHF>!DH|Ie~>0P#^g13(LPTM`8Rn<>xr2Dd_jUxWa0}g}SA58$Z+`A31Qv0Y< zWiz2J3X7~HWMBRLab6NOSLz>Yd2Ld~)u8r#b>_!E*mVwUqd+SkJQ|FngDm+HX9LYw z1B4AsKIuG4zR>diYbqF1)vrD4VMF8 zWiB&XIU^CsDzh8CD(8aLzFhVSmiw)SPw7K@-#FHfdnU&XM#dG`3u z$psX0k7Fm!htMjqC9M16XSFn#f7A_y-pbzyHY^(eBz3e$m3LpALxOeNzKI`^U`bv5 zgaKAP{oY6TCFCpa3JF;E@2>5Nhcqvy1~^8?J3+AkTQ}a@;KxN_XTPafL3AJNP^-Jx z-M#D%!0J0T5(Wti7lq#E`4sQW32bp7+^Z*T?%G=~b0QwNY?clkYzkpi5F2U6&Iv17 zxt5j^uS`ZjMZDGaA;ZUjewnNJxHlm&ecYe7k#uVX-df-IRK;W~cN!{;zcw5>7qGD}7iy>cT<{ zmNBHwZ4X&bW@fgRJYZGoONv+}X1bS_$gz0%Omllko~i$ME7%!sIfO!4j$>4{N|lXX zad%Y%8Z-~fp;UVm(>W@BD>)mCISInmASHw`z^hH|>=dxN0bTSqL=rkW+3vI5wRgfo z`y4_Ig(gBfdIqzS+Gh)vabw|m0oEP=U2ytmynKGpsMRY?jbrlE!I#)2ju;!hO2azr zWccP7VtJN$bV+DFtXdcdMRLDGCl)j;L#KTWmT?cWI(UZFlc@L-39ILkNAi>ogcHnb zFu+QucPG4t1-H9cu@t?EDEBJzLI)*Z^fQRyPA?W9N(n{t4LQicHQ_P9>g*SOMfvLg z%w26un`s(lVXC%;P@+b{mhmOjbQi%7`C{jrAEuyGYAgr_gboW2Vx5YJBD&gv3R$xi zi(ALgb_=CMLWP1h#+Ulz_CDvj?)$l)n6!3xUG}ln^v!u`=ghgzb*^(5*ucX}KotJ~ z03ZNKL_t*NzBn?me9?V4Y^pCYvLO{QySHIY7?;3?Qj6H!HK{>H!@a>4XLAS05Vn9r ze-tIlzcehf#EZmij1~wIt1(N}K;j%-BPz-$$Rq52^O6bf4zS{JQQU|7?Jqh4Altg< zVZ$q*rGZxXnht$fdA-UJl4UrRcbc<^tDJ>{g~D2~I6q%JFkhT&K>-Vv23wXhJL_Wm z4mk``cE{UhfP~Q{Nf}*QY6?Xx60A*he81LDY;150G&JkemMjQ`Vy!g!nYO>? zc$X8}8gPvBkp}mDEC&s->Qepc*67fX__5UEPQyDDs%d$H(*b@_9zD|_N-u+CxNF8J zN5RB|608Y1dB$Q;)`Oif-405QyMZNFp^D4FPNi3v2<5pFg7s~K!XIv4XEdL87~S$M zCj_4#>Rv!!c1w88XIKq8RHF>*O+z0RHTN6ZNoa-lR$*92K41~DUOGJ;U?tJ+ULB#9 z5?aGm%S&-!q4n8NEcc6>Fb@*0z^LfPnwc4J{stfx7#5a<2DP+IHOVSM^X0Dotv4r= z8Y`338p5O-2?17A+%tMj*ay=nWg`>@VbIhN@C*W5bLa#Qmx+BbTF64Pm zrKTIC%z#mA(V|E?F-P?+Y>`#YRB-0 zMIom`rXee4B_`N2agR79uF;swap!t42F?ABEhA)d-yL{jfbX^ov5-+o= zr-XnnwWbI-@;2*t%#T$l;B5(u3%nzQ+FmHGo411+4Qm@_ ztU&GvgY6)290|)olB?Y%gH@tmz1w{I7Sg+06CM(*R#^DFxe_w0l_wio?v>rh%A#<~ zUJ@ezD!YGlq0i-hjvlO07N}Bd&qZ`Aoa10ENQrCuefu<+md!|p>x%jnSr^S#f?GHnb4t7U`ilMR)k#wSmt5XvwnS{*)nD%#H*`fSjU%;qZ+AGEzd6n zSk*?igqQMRMZ~NI?a$w4SpR^8^-JXX*NVLh&PPC{3MI@9;s26uMO z&reRyknG;v+!O*95Y6@u-j+cyHD+lSkkI~Ax+!EDOnINoe6|+P)*w@1+~#|oNCFl^ z8q&ZjkgK%Z4tlqQJbFeGA=ZS81<%${3~dbtvJ5hrxiDl{bdAo#(Llu74rXVaZM3Bt z?An14%R)INGz{x4JD*+j#|9k@D~yv^sTE(~(g|$Pev6D)T?e+1 zj$vtF!$q`u{`>B6wNfd&BE^?C8rd5D={40WRLMYSzG45O&5mJJ!^>wOSZMv~cJkG- zeryh7{9waEG}idsqywy~;?=k~v8c7r$$?HUOLHDQg1Nnyr#Zb4-NCF1ud3CnXrCUPl!vbWT`$5TK#A=K0$pY`pyk?*u zuKYl;oDHJvFr~>A=eds-u*O8aQidh(q(fQ?rQHfJ0#JXh+la)Y9LnzQ7pdSr%(e}K zSfEyELRR`D)UaGo!*7Mfk;TQ3VVwc6*37$gGOTqo6t2&Q8WsU7kWHb4HGB>M>y#l4 z?}E1hlq_gi!RF?+t;%sx$xqbQu(AZ}Xb4yv(64fEjpo?xWx#49XTxOVsaK+8Fbl$! z!7VNe_o-je$pB(CnivwLU1jsGztO=iYr&x|Tn^sCo{;>BUU#HlC8Xb3eu>-=S|h`R z1~d?|B+2idJ;;&PRF{h!>ty(qL9ILC9U<`Q#TE4u-aP$!&BRyp{=N=aH!F1kE0Wf5 zIj8$|Dfx0Rb!=ejuw17N>CKIXd03nXe{|kaqE?SUSJekB7UsD9A0>C35^7q5xZEz>>=xL95;w9SRk+09FfyFXkWVtlV6u^9s4{?#V!Ww|{p@ zp;&5j&qx+lM~1i0QPEu~mUT6xXvVTLp)^33BpOSI*Lh0Q-8D!dRMao=oZxV$%^{UF zGuS%m+lHB4{*#r((-0r-AC3anQ^hOJgwN9a=rb(lxQ~n!XlpP}-X95h_FPbkwN_kT zKk)LfW@qOGwU{$X5zE>6jWny+$Yl<^E;R{LUfZ>L$5MpDY`?fXOKjShBjFN*EDFPy%`Z(%1W z2RQ8--Hs1pY5+26I)ge#4IJIW6Qj{x%?v-i=u}UGsPAfK(9>s$YA}HH;HpG-$FTnU zfEDJ%H_pSl9K$m7>hbe8+ou)mDrkd~R_kb3t&uI^vbQ6YHDT+IY8>tH0Bcq9 zk)0Vr)T`C*DT`LTd=`qeyxi;sHh^7CjxU?x&@rr+<6>(NC)SL+fF@c2tctI`7%~+t z3$&JH^761UC9z>q!Lp|Jv#>me@qOZTZx#bO zkjgq5{0z`Rkt*|9T%#(v`+)UsTQsZyF83vbx^LnI36-k{ z*+5J(PM^W3oQ74Qr{M`itPL3lSGGQxN$`_QgSni3IIUZc)ch-ODkt13tjrPr6*0>Y zE5owhCq52Ay$Wv##fSx8!vupxhuXDlg7SM;0+9{S+O5r9X2S`IX^5eD!gf7}7A*CR z#>6=)b0KJz)vpY}`uR#3*7uBr$Cm;uXLUbnoH%+pAJ+Bjb$S3`HVTOCcZImaLth?ZkmAy^rP

t? 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 { - if (!selectedOrg) return; - - const currentParams = new URLSearchParams(searchParams.toString()); - const queryString = currentParams.toString() ? `?${currentParams.toString()}` : ''; - - return router.replace(`/notebook/${selectedOrg.slug}${queryString}`); - }, [selectedOrg, router, searchParams]); - - // Loading state — defer to NoteEditorLayout (sibling in the layout) to avoid a - // redundant document-outline flash while the org loads / redirect happens. - if (isLoadingOrg) { - return null; - } - - // Error state - if (orgError) { - return ( -

-
-
⚠️
-

Something went wrong

-

{orgError.message}

- -
-
- ); - } - - // This should never render as we redirect in the useEffect - return null; -} diff --git a/app/org/join/[token]/page.tsx b/app/org/join/[token]/page.tsx deleted file mode 100644 index f1e0a68a1..000000000 --- a/app/org/join/[token]/page.tsx +++ /dev/null @@ -1,148 +0,0 @@ -'use client'; - -import { useEffect } from 'react'; -import { useParams, useRouter } from 'next/navigation'; -import { Button } from '@/components/ui/Button'; -import { Loader2 } from 'lucide-react'; -import { toast } from 'react-hot-toast'; -import { useAcceptOrgInvite, useFetchOrgByInviteToken } from '@/hooks/useOrganization'; -import { useSession } from 'next-auth/react'; -import Image from 'next/image'; -import Link from 'next/link'; -import { PageLayout } from '@/app/layouts/PageLayout'; -import { PageHeader } from '@/components/ui/PageHeader'; -import { useAuthenticatedAction } from '@/contexts/AuthModalContext'; -import { useTransition } from 'react'; -import { Avatar } from '@/components/ui/Avatar'; - -export default function JoinOrganizationPage() { - const params = useParams(); - const router = useRouter(); - const { data: session, status } = useSession(); - const [{ isLoading: isAccepting }, acceptOrgInvite] = useAcceptOrgInvite(); - const [{ data: organization, isLoading: isFetching, error }, fetchOrgByInviteToken] = - useFetchOrgByInviteToken(); - const { executeAuthenticatedAction } = useAuthenticatedAction(); - const [isPending, startTransition] = useTransition(); - - const token = params?.token as string; - - useEffect(() => { - const fetchOrganization = async () => { - try { - await fetchOrgByInviteToken(token); - } catch (error) { - console.log( - 'Failed to fetch organization details. The invitation may be invalid or expired.' - ); - } - }; - - if (token && status !== 'loading') { - fetchOrganization(); - } - }, [token, status, fetchOrgByInviteToken]); - - const handleJoinOrg = async () => { - if (!organization) return; - - try { - await acceptOrgInvite(token); - toast.success(`Successfully joined ${organization.name}`); - - // Use startTransition for the navigation - startTransition(() => { - router.push(`/notebook/${organization.slug}`); - }); - } catch (error) { - toast.error('Failed to join organization. The invitation may be invalid or expired.'); - } - }; - - if (status === 'loading' || isFetching) { - return ( - -
- -

Loading...

-
-
- ); - } - - if (error || !organization) { - return ( - -
-
- - - -
-

Invalid Invitation

-

- This invitation link is invalid or has expired. Please contact the organization - administrator for a new invitation. -

- - - -
-
- ); - } - - return ( - - -
-
- -
- -

Join {organization.name}

-

- You have been invited to join {organization.name}. - {status === 'authenticated' && <>Click the button below to accept the invitation.} -

- - {status === 'authenticated' ? ( - - ) : ( -
-

- You need to sign in to join this organization -

- -
- )} -
-
- ); -} diff --git a/app/robots.ts b/app/robots.ts index b9fd87fe3..61d1a8077 100644 --- a/app/robots.ts +++ b/app/robots.ts @@ -11,12 +11,9 @@ export default function robots(): MetadataRoute.Robots { '/auth/', '/verify/', '/reset/', - '/org/join/', - '/note/join/', '/notifications/', '/activity/', '/my-funding', - '/notebook/', '/moderators/', '/expert-finder/', '/settings', diff --git a/components/AIMode/start/ConciergeCard.tsx b/components/AIMode/start/ConciergeCard.tsx index 9b5c21216..224650acf 100644 --- a/components/AIMode/start/ConciergeCard.tsx +++ b/components/AIMode/start/ConciergeCard.tsx @@ -1,10 +1,12 @@ 'use client'; import { ArrowUpRight } from 'lucide-react'; -import { WHITE_GLOVE_BOOKING_URL } from '@/components/Funding/OpenFundingOpportunityModal'; import { Avatar } from '@/components/ui/Avatar'; import { cn } from '@/utils/styles'; +/** Where a funder books time with the ResearchHub team to shape an RFP together. */ +const WHITE_GLOVE_BOOKING_URL = 'https://cal.com/tyler-diorio/15min'; + /** The PhD on the team who takes funders' calls. */ const CONCIERGE_AVATAR_URL = 'https://storage.prod.researchhub.com/uploads/author_profile_images/2022/08/09/blob_im4Dh4d'; diff --git a/components/AgentChat/ActivityFeed.tsx b/components/AgentChat/ActivityFeed.tsx index cdd33c4be..6c139b2ca 100644 --- a/components/AgentChat/ActivityFeed.tsx +++ b/components/AgentChat/ActivityFeed.tsx @@ -61,7 +61,7 @@ export function humanizeLabel(label: string): string { return label.replaceAll(/([a-z0-9])_(?=[a-z0-9])/g, '$1 '); } -export function hostnameOf(url: string): string { +function hostnameOf(url: string): string { try { return new URL(url).hostname.replace(/^www\./, ''); } catch { @@ -462,16 +462,3 @@ export function ActivityFeed({ ); } - -/** Unique sources across a whole turn, for the Sources tab. */ -export function collectSources(items: ChatFeedItem[]): ChatActivitySource[] { - const byUrl = new Map(); - for (const item of items) { - if (item.type === 'tool_call' && item.sources) { - for (const source of item.sources) { - if (!byUrl.has(source.url)) byUrl.set(source.url, source); - } - } - } - return Array.from(byUrl.values()); -} diff --git a/components/AgentChat/ChatEmptyState.tsx b/components/AgentChat/ChatEmptyState.tsx deleted file mode 100644 index f1e3af237..000000000 --- a/components/AgentChat/ChatEmptyState.tsx +++ /dev/null @@ -1,51 +0,0 @@ -'use client'; - -import { Logo } from '@/components/ui/Logo'; -import { ChatPresets } from './ChatPresets'; - -interface ChatEmptyStateProps { - readonly noteIsEmpty: boolean; - readonly noteIsRfp: boolean; - readonly onSelectPreset: (message: string) => void; - readonly presetsDisabled: boolean; - /** What the help line calls the thing being written: the notebook's "note", the workspace's "document". */ - readonly noun?: string; -} - -/** - * A chat on a document before its first message: who the assistant is, what - * it can do, and a few ways to start, chosen by what the document is and - * whether anything is written in it yet. - */ -export function ChatEmptyState({ - noteIsEmpty, - noteIsRfp, - onSelectPreset, - presetsDisabled, - noun = 'note', -}: ChatEmptyStateProps) { - return ( -
-
-
- -
-
-

- Research assistant -

-

- Ask questions about this {noun}, search the web and scholarly literature, or have the - assistant edit the draft for you. -

-
-
- -
- ); -} diff --git a/components/AgentChat/ChatPresets.tsx b/components/AgentChat/ChatPresets.tsx deleted file mode 100644 index 260ffefce..000000000 --- a/components/AgentChat/ChatPresets.tsx +++ /dev/null @@ -1,141 +0,0 @@ -'use client'; - -import type { ComponentType } from 'react'; -import { HandCoins, PenLine, SquarePen, Telescope } from 'lucide-react'; -import { cn } from '@/utils/styles'; - -interface ChatPreset { - readonly id: string; - readonly label: string; - readonly icon: ComponentType<{ className?: string }>; - /** Loaded into the composer as an editable starting point, not sent. */ - readonly message: string; -} - -/** - * An RFP is the funder's own call, so it takes one writing preset in both - * states — worded to work whether the note is blank or half-written, since the - * assistant reads the note either way. - */ -const DRAFT_RFP: ChatPreset = { - id: 'draft-rfp', - label: 'Draft RFP', - icon: PenLine, - message: - 'Help me draft this RFP. Ask me for anything you still need to know about the work I want to ' + - 'fund, then write the draft into the note.', -}; - -const DRAFT_PROPOSAL: ChatPreset = { - id: 'draft-proposal', - label: 'Draft proposal', - icon: PenLine, - message: - 'Help me draft this proposal. Ask me for anything you still need to know about the work, ' + - 'then generate me three hypotheses to start.', -}; - -const EDIT_PROPOSAL: ChatPreset = { - id: 'edit-proposal', - label: 'Edit proposal', - icon: SquarePen, - message: - 'Review the proposal in this note and make it stronger — tighten the writing, fill in what ' + - 'is missing, and flag anything a reviewer would push back on.', -}; - -/** - * The two searches, each in a note-shaped and an author-shaped form. Both have - * to match on something: a written note is the better brief, and an empty one - * is no brief at all, so the search falls back to the person doing it. A pair - * shares its id, since the two never appear together. - */ -const RESEARCH_FROM_NOTE: ChatPreset = { - id: 'research', - label: 'Help me research', - icon: Telescope, - message: - 'Help me research this. Search the web and the scholarly literature for the work most ' + - 'relevant to this note, and summarise what I should know, with sources.', -}; - -const RESEARCH_FROM_EXPERTISE: ChatPreset = { - id: 'research', - label: 'Help me research', - icon: Telescope, - message: - 'Help me research. Search the web and the scholarly literature for the work most relevant ' + - 'to my expertise, and summarise what I should know, with sources.', -}; - -const FUNDING_FROM_NOTE: ChatPreset = { - id: 'funding', - label: 'Find me funding', - icon: HandCoins, - message: - 'Find open RFPs I could apply to that fit this work, and tell me why each one is a match.', -}; - -const FUNDING_FROM_EXPERTISE: ChatPreset = { - id: 'funding', - label: 'Find me funding', - icon: HandCoins, - message: - 'Find open RFPs I could apply to based on my expertise, and tell me why each one is a match.', -}; - -/** - * An RFP note is written by the side handing out the money, so it gets neither - * the funding search nor the proposal-shaped review — only the call itself and - * the field it is calling into. A proposal note takes all three, its writing - * preset turning on whether there is a draft to improve yet. - */ -function presetsFor(noteIsEmpty: boolean, isRfp: boolean): ChatPreset[] { - const research = noteIsEmpty ? RESEARCH_FROM_EXPERTISE : RESEARCH_FROM_NOTE; - if (isRfp) return [DRAFT_RFP, research]; - return [ - noteIsEmpty ? DRAFT_PROPOSAL : EDIT_PROPOSAL, - research, - noteIsEmpty ? FUNDING_FROM_EXPERTISE : FUNDING_FROM_NOTE, - ]; -} - -interface ChatPresetsProps { - readonly noteIsEmpty: boolean; - readonly isRfp: boolean; - readonly onSelect: (message: string) => void; - readonly disabled: boolean; -} - -/** - * Opening moves offered on the empty chat screen. Picking one writes its - * message into the composer for the user to edit and send, so the specifics a - * generic instruction can't carry go in before the assistant sees it. - */ -export function ChatPresets({ noteIsEmpty, isRfp, onSelect, disabled }: ChatPresetsProps) { - return ( - // Stacked, not the grid this pattern usually wears: the panel is 360px at - // its narrowest, where side-by-side cards would wrap every label. -
- {presetsFor(noteIsEmpty, isRfp).map((preset) => ( - - ))} -
- ); -} diff --git a/components/AgentChat/ChatSources.tsx b/components/AgentChat/ChatSources.tsx deleted file mode 100644 index b9ede9e1d..000000000 --- a/components/AgentChat/ChatSources.tsx +++ /dev/null @@ -1,69 +0,0 @@ -'use client'; - -import { ExternalLink, Globe } from 'lucide-react'; -import type { ChatActivitySource, AgentChat } from '@/types/agentChat'; -import { collectSources, hostnameOf } from './ActivityFeed'; - -/** - * Every citation the assistant produced in one chat, deduplicated by URL and - * ordered oldest turn first. Derived from the activity feed rather than fetched - * — the transcript already carries the sources, they're just buried per tool - * call, which makes them hard to use once a chat runs long. - */ -export function collectChatSources(chat: AgentChat | null): ChatActivitySource[] { - const byUrl = new Map(); - for (const execution of chat?.executions ?? []) { - for (const source of collectSources(execution.activity ?? [])) { - if (!byUrl.has(source.url)) byUrl.set(source.url, source); - } - } - return Array.from(byUrl.values()); -} - -interface ChatSourcesProps { - readonly sources: ChatActivitySource[]; -} - -export function ChatSources({ sources }: ChatSourcesProps) { - if (sources.length === 0) { - return ( -
-
- ); - } - - return ( - - ); -} diff --git a/components/AgentChat/CreditMeter.tsx b/components/AgentChat/CreditMeter.tsx deleted file mode 100644 index 3cf65fd1c..000000000 --- a/components/AgentChat/CreditMeter.tsx +++ /dev/null @@ -1,67 +0,0 @@ -'use client'; - -import type { ResearchAIState } from '@/store/researchAI'; -import { formatBudgetReset, formatCredits, isBudgetExhausted } from '@/types/researchAI'; - -export function CreditMeter({ - budget, - budgetStatus, - limitResetAt, - onRefresh, -}: Pick & { onRefresh: () => void }) { - if (budget?.tier === 'blocked') { - return ( - - Research AI is unavailable for this account. - - ); - } - if (!budget) { - return ( - - {budgetStatus === 'loading' ? 'Loading AI credits…' : 'Couldn’t load AI credits.'} - {budgetStatus === 'unavailable' && ( - - )} - - ); - } - const exhausted = isBudgetExhausted(budget) || limitResetAt !== null; - const { remaining, daily_limit: limit } = budget.credits; - const reset = formatBudgetReset(budget.resets_at); - let balanceLabel = 'Credits unavailable'; - if (limit === null) { - balanceLabel = 'Unlimited credits'; - } else if (remaining !== null) { - balanceLabel = `${formatCredits(remaining)} credits remaining`; - } - return ( -
-
- - {balanceLabel} - - -
- {exhausted && ( - - Daily AI usage limit reached. Available again at {reset}. - - )} - {budgetStatus === 'unavailable' && ( -

- Credits may be out of date.{' '} - -

- )} -
- ); -} diff --git a/components/Editor/components/BlockEditor/BlockEditor.tsx b/components/Editor/components/BlockEditor/BlockEditor.tsx index 5d27e335a..07027415d 100644 --- a/components/Editor/components/BlockEditor/BlockEditor.tsx +++ b/components/Editor/components/BlockEditor/BlockEditor.tsx @@ -10,7 +10,6 @@ import ColumnsMenu from '../../extensions/MultiColumn/menus/ColumnsMenu'; import TableRowMenu from '../../extensions/Table/menus/TableRow'; import ImageBlockMenu from '../../extensions/ImageBlock/components/ImageBlockMenu'; import TableColumnMenu from '../../extensions/Table/menus/TableColumn'; -import { useNotebookContext } from '@/contexts/NotebookContext'; export interface BlockEditorProps { content?: string; diff --git a/components/Editor/lib/convert.ts b/components/Editor/lib/convert.ts deleted file mode 100644 index 0d94a0d03..000000000 --- a/components/Editor/lib/convert.ts +++ /dev/null @@ -1,243 +0,0 @@ -'use client'; - -import { Editor, JSONContent } from '@tiptap/core'; -import type { AnyExtension } from '@tiptap/core'; -import { UndoRedo } from '@tiptap/extensions'; -import { Import } from '@tiptap-pro/extension-import'; - -import { getDocumentTitle } from '@/components/Editor/lib/utils/documentTitle'; - -/** - * Supported source formats for the Tiptap Cloud Convert import flow. - * Mirrors the legacy `@tiptap-pro/extension-import` `formatMap`: - * - docx: Microsoft Word (routes to the `/import-docx` endpoint via the - * `experimentalDocxImport` flag). - * - odt: OpenDocument Text (LibreOffice, Google Docs export). - * - md: CommonMark / GitHub Flavored Markdown. We pass `format: 'gfm'` - * for any `.md` file so tables, task lists, and strikethrough parse - * correctly — the GFM superset is backward-compatible with CommonMark - * for everything else, so there's no downside. - */ -export type SupportedImportFormat = 'docx' | 'odt' | 'md'; - -const DOCX_MIME = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; -const ODT_MIME = 'application/vnd.oasis.opendocument.text'; -const MD_MIMES = new Set(['text/markdown', 'text/x-markdown']); - -/** - * Server-enforced upload size cap (25 MB). The modal's file picker also - * blocks uploads larger than this, but we re-check here so the limit holds - * even if `importDocumentToTiptap` is called from another caller that - * doesn't run the modal's validation. - */ -const MAX_IMPORT_SIZE = 25 * 1024 * 1024; - -/** - * Resolve a file to one of our supported import formats, preferring MIME - * type when the OS provided one and falling back to the filename extension. - * Returns null for unsupported inputs so callers can produce a clear error. - */ -export const detectImportFormat = (file: File): SupportedImportFormat | null => { - const name = file.name.toLowerCase(); - - if (file.type === DOCX_MIME || name.endsWith('.docx')) return 'docx'; - if (file.type === ODT_MIME || name.endsWith('.odt')) return 'odt'; - if (MD_MIMES.has(file.type) || name.endsWith('.md') || name.endsWith('.markdown')) return 'md'; - - return null; -}; - -/** - * Strip the source-format extension from a filename so it can be used as a - * fallback note title. Only strips the extensions we actually accept so we - * don't accidentally mangle filenames like `data.archive.docx`. - */ -const stripImportExtension = (filename: string): string => - filename.replace(/\.(docx|odt|md|markdown)$/i, '').trim(); - -/** - * Fetch a fresh convert JWT for each import. Tokens expire after 15 minutes - * (see `/notebook/api/convert`), so a single fetch per import is the - * simplest correct behavior. Caching would force us to manage expiry - * client-side; not worth it given each import already pays the round-trip. - */ -const fetchConvertToken = async (): Promise => { - const response = await fetch('/notebook/api/convert', { method: 'POST' }); - if (!response.ok) { - throw new Error( - `Failed to fetch convert token (${response.status}). Is TIPTAP_CONVERT_SECRET set?` - ); - } - const body = (await response.json()) as { token?: string; error?: string }; - if (!body.token) { - throw new Error(body.error || 'Convert token response did not include a token.'); - } - return body.token; -}; - -export interface DocumentImportResult { - /** TipTap JSON document the live editor can render directly. */ - json: JSONContent; - /** Serialized HTML for the legacy `content` field on the note record. */ - html: string; - /** Plain text for search indexing and excerpts. */ - plainText: string; - /** Heuristic title pulled from the document (first heading, falls back to filename). */ - title: string; - /** The format the source file was detected as. */ - format: SupportedImportFormat; -} - -/** - * Convert a supported document (.docx, .odt, .md) to TipTap content by - * spinning up a headless editor that uses the same extension kit as the - * live note editor. The throwaway editor is destroyed before the function - * returns. - * - * Image handling: this v1 does not pass `imageUploadCallbackUrl` to the - * Import extension, so embedded images are stripped on import. Wiring image - * upload requires a public Next.js callback route plus either a server-side - * AWS SDK or a shared-secret Django endpoint. Tracked as a follow-up. - */ -export const importDocumentToTiptap = async ( - file: File, - options: { fallbackTitle?: string } = {} -): Promise => { - // The Tiptap Cloud App ID is account-wide and shared across products - // (Content AI, Convert, Collab); each product has its own JWT secret on - // the server. - const appId = process.env.NEXT_PUBLIC_TIPTAP_APP_ID; - if (!appId) { - throw new Error( - 'NEXT_PUBLIC_TIPTAP_APP_ID is not set. Add it to your environment to enable document import.' - ); - } - - const format = detectImportFormat(file); - if (!format) { - throw new Error('Unsupported file type. Please upload a .docx, .odt, or .md document.'); - } - - if (file.size > MAX_IMPORT_SIZE) { - throw new Error( - `Document is too large (${(file.size / 1024 / 1024).toFixed(1)} MB). The maximum is ${MAX_IMPORT_SIZE / 1024 / 1024} MB.` - ); - } - - const token = await fetchConvertToken(); - - const { ExtensionKit } = await import('@/components/Editor/extensions/extension-kit'); - - // The headless import editor uses the *default* Document node (which - // accepts `block+`) rather than the live editor's `heading block+` custom - // document. Two reasons: - // 1) Many imported documents don't start with a heading (especially - // markdown). Forcing `heading block+` during import would cause - // ProseMirror to coerce or drop the leading content, silently - // corrupting the imported document. - // 2) The live editor's schema is enforced at the editing layer; the - // stored JSON just needs to be coercible into it. We handle that - // coercion explicitly below by prepending a title heading if needed. - const extensions: AnyExtension[] = [ - ...ExtensionKit({}), - UndoRedo.configure({ depth: 100 }), - Import.configure({ - appId, - token, - // experimentalDocxImport is required on legacy 2.x to opt into the - // DOCX-specific endpoint. It's a no-op for ODT/Markdown (the - // extension only takes the docx branch when the file MIME matches), - // so we can safely leave it on for all imports. - experimentalDocxImport: true, - }), - ]; - - // Initial content is a single paragraph rather than `{ content: [] }`. - // The TrailingNode plugin's state.init reads doc.lastChild, which is null - // for a truly empty doc and crashes the plugin. A single paragraph is the - // simplest valid seed that satisfies every plugin's invariants. - const editor = new Editor({ - extensions, - editable: false, - content: { type: 'doc', content: [{ type: 'paragraph' }] }, - }); - - try { - const json = await new Promise((resolve, reject) => { - let settled = false; - - // Safety net: surface a timeout rather than hanging the UI if onImport - // never fires (network outage, hung extension, etc). - const timeoutId = setTimeout(() => { - if (settled) return; - settled = true; - reject(new Error('Document import timed out after 60 seconds.')); - }, 60_000); - - editor - .chain() - .import({ - file, - // `format: 'gfm'` only matters for markdown (it flips a query - // flag on the Convert endpoint enabling GFM extensions). For - // docx/odt the extension ignores it. - ...(format === 'md' ? ({ format: 'gfm' } as const) : {}), - onImport(context) { - if (settled) return; - settled = true; - clearTimeout(timeoutId); - if (context.error) { - reject(context.error); - return; - } - // setEditorContent writes the normalized content into the - // throwaway editor; reading getJSON afterwards captures it - // shaped against our local schema (unknown nodes filtered). - context.setEditorContent(); - resolve(editor.getJSON()); - }, - }) - .run(); - }); - - // The live editor requires `heading block+`. If the imported doc doesn't - // start with a heading, prepend one derived from the filename so the - // result is loadable in the live editor without ProseMirror dropping or - // mangling the leading content. - const fallbackTitle = stripImportExtension(file.name) || options.fallbackTitle || 'Untitled'; - const normalizedJson = ensureLeadingHeading(json, fallbackTitle); - - const html = editor.getHTML(); - const plainText = editor.getText(); - const headingTitle = getDocumentTitle(normalizedJson); - const title = (headingTitle && headingTitle.trim()) || fallbackTitle; - - return { json: normalizedJson, html, plainText, title, format }; - } finally { - editor.destroy(); - } -}; - -/** - * Ensure the imported document starts with a level-1 heading. If the first - * block is already a heading we leave it alone. Otherwise we synthesize one - * from `fallbackTitle` so the resulting JSON satisfies the live editor's - * `heading block+` schema constraint. - */ -const ensureLeadingHeading = (doc: JSONContent, fallbackTitle: string): JSONContent => { - const firstBlock = doc.content?.[0]; - if (firstBlock?.type === 'heading') { - return doc; - } - return { - ...doc, - content: [ - { - type: 'heading', - attrs: { textAlign: 'left', level: 1 }, - content: [{ type: 'text', text: fallbackTitle }], - }, - ...(doc.content ?? []), - ], - }; -}; diff --git a/components/Editor/lib/data/grantTemplate.tsx b/components/Editor/lib/data/grantTemplate.tsx deleted file mode 100644 index a18427946..000000000 --- a/components/Editor/lib/data/grantTemplate.tsx +++ /dev/null @@ -1,301 +0,0 @@ -interface DocumentContent { - type: string; - attrs?: { - textAlign?: string; - level?: number; - class?: string | null; - }; - content?: Array<{ - type: string; - text?: string; - marks?: Array<{ type: string; [key: string]: any }>; - content?: DocumentContent[]; - }>; -} - -interface Template { - type: 'doc'; - content: DocumentContent[]; -} - -const grantTemplate: Template = { - type: 'doc', - content: [ - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 1, - }, - content: [ - { - type: 'text', - text: '[Topic/Theme]', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: 'About this funding', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: "Briefly introduce your organization and explain why you are issuing this RFP now, including the overarching problem or topic you\'re targeting.", - marks: [{ type: 'italic' }], - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: '[Insert background and rationale here]', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: 'Topics of interest', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'State your overall goal briefly, then list a few high‐level "areas of interest" that applicants may address. These should be broad, non‐exhaustive topics.', - marks: [{ type: 'italic' }], - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Overall goal:', - marks: [{ type: 'bold' }], - }, - { - type: 'text', - text: ' [Insert one‐sentence goal]', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Specific areas of interest (not exhaustive):', - marks: [{ type: 'bold' }], - }, - ], - }, - { - type: 'bulletList', - content: [ - { - type: 'listItem', - content: [ - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: '[Area of interest 1]', - }, - ], - }, - ], - }, - { - type: 'listItem', - content: [ - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: '[Area of interest 2]', - }, - ], - }, - ], - }, - { - type: 'listItem', - content: [ - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: '…', - }, - ], - }, - ], - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: 'Funding details', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'State the total budget available for this RFP and the award range per project. Indicate whether multiple projects will be funded.', - marks: [{ type: 'italic' }], - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Total budget:', - marks: [{ type: 'bold' }], - }, - { - type: 'text', - text: ' [Insert total amount]', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Individual award range:', - marks: [{ type: 'bold' }], - }, - { - type: 'text', - text: ' [Insert minimum] – [Insert maximum]', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: '[Optional: Indicate number of projects expected to be funded]', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: 'Additional details', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Optionally include any additional details to guide submissions or generate discussion.', - marks: [{ type: 'italic' }], - }, - ], - }, - ], -}; - -export default grantTemplate; diff --git a/components/Editor/lib/data/proposalTemplate.tsx b/components/Editor/lib/data/proposalTemplate.tsx deleted file mode 100644 index 833c434ce..000000000 --- a/components/Editor/lib/data/proposalTemplate.tsx +++ /dev/null @@ -1,311 +0,0 @@ -interface DocumentContent { - type: string; - attrs?: { - textAlign?: string; - level?: number; - class?: string | null; - }; - content?: Array<{ - type: string; - text?: string; - }>; -} - -interface Template { - type: 'doc'; - content: DocumentContent[]; -} - -const proposalTemplate: Template = { - type: 'doc', - content: [ - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 1, - }, - content: [ - { - type: 'text', - text: 'Proposal Template', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: '1. Abstract', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Provide a concise abstract (max 200 words) describing (1) scientific rationale, importance and research plan, (2) description of team/facilities/ethics approvals, (3) estimated timeline, and (4) data sharing commitment.', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: '2. Introduction', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Summarize theoretical background, key literature, and rationale for the proposal.', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 3, - }, - content: [ - { - type: 'text', - text: 'Hypotheses', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'State numbered hypotheses (H1, H2, etc.) as labeled subheadings. Designate primary vs. secondary outcomes.', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: '3. Methods', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 3, - }, - content: [ - { - type: 'text', - text: 'Participants/Sample', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Define target sample, inclusion/exclusion criteria, recruitment strategy, and sample size justification (including power analysis).', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 3, - }, - content: [ - { - type: 'text', - text: 'Materials and Procedures', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Describe experimental/observational procedures, stimuli, tasks, equipment, and data collection settings with sufficient detail for replication.', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 3, - }, - content: [ - { - type: 'text', - text: 'Planned Analyses', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Outline analysis pipeline, preprocessing steps, statistical tests, and hypothesis-specific predictions. Describe how results will be interpreted regardless of outcome. Describe how deviations from the planned sample will be handled.', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 3, - }, - content: [ - { - type: 'text', - text: 'Ethics and Data Management', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'State ethical approval status or plan, confidentiality measures, and data sharing/archiving plan.', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: '4. Pilot Data (Optional)', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Summarize any pilot data or simulations that demonstrate method feasibility and inform power analysis. Clearly distinguish from main study.', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: '5. Budget', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'Provide an itemized list of anticipated costs (materials, personnel, etc.). These are not binding and are able to be adjusted based on the results of the pilot data.', - }, - ], - }, - { - type: 'heading', - attrs: { - textAlign: 'left', - level: 2, - }, - content: [ - { - type: 'text', - text: '6. References', - }, - ], - }, - { - type: 'paragraph', - attrs: { - class: null, - textAlign: 'left', - }, - content: [ - { - type: 'text', - text: 'List all references used in the manuscript using Nature style (e.g. numbered in-text citations and alphabetical references at the end of the manuscript).', - }, - ], - }, - ], -}; - -export default proposalTemplate; diff --git a/components/Funding/DocumentUploadStep.tsx b/components/Funding/DocumentUploadStep.tsx deleted file mode 100644 index 46c2aed11..000000000 --- a/components/Funding/DocumentUploadStep.tsx +++ /dev/null @@ -1,181 +0,0 @@ -'use client'; - -import { useRef, useState } from 'react'; -import { useRouter } from 'next/navigation'; -import toast from 'react-hot-toast'; -import { ArrowLeft, Loader2, Upload } from 'lucide-react'; -import { useOrganizationContext } from '@/contexts/OrganizationContext'; -import { useCreateNote, useNoteContent } from '@/hooks/useNote'; -import { detectImportFormat, importDocumentToTiptap } from '@/components/Editor/lib/convert'; -import { cn } from '@/utils/styles'; - -// Accepted import formats for the document upload flow. -const UPLOAD_ACCEPT_ATTR = [ - '.docx', - '.odt', - '.md', - '.markdown', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'application/vnd.oasis.opendocument.text', - 'text/markdown', -].join(','); - -const MAX_UPLOAD_SIZE = 25 * 1024 * 1024; - -interface DocumentUploadStepProps { - /** Heading shown above the dropzone. */ - title: string; - /** Supporting copy shown under the heading. */ - description: string; - /** Note document type to create, e.g. 'GRANT' or 'PREREGISTRATION'. */ - documentType: string; - /** Invoked when the user wants to return to the previous step. */ - onBack: () => void; - /** Invoked once a note is created (used to close the host modal). */ - onClose: () => void; -} - -/** - * In-modal "upload a document" step shared by the funding-opportunity and - * proposal modals. Imports a Word/OpenDocument/Markdown file, creates a note - * from it, and navigates to the new note in the notebook. - */ -export const DocumentUploadStep = ({ - title, - description, - documentType, - onBack, - onClose, -}: DocumentUploadStepProps) => { - const router = useRouter(); - const { selectedOrg } = useOrganizationContext(); - const [, createNote] = useCreateNote(); - const [, updateNoteContent] = useNoteContent(); - const [isImporting, setIsImporting] = useState(false); - const [uploadError, setUploadError] = useState(null); - const [isDragging, setIsDragging] = useState(false); - const fileInputRef = useRef(null); - - const importDocument = async (file: File) => { - if (!selectedOrg || isImporting) return; - setIsImporting(true); - try { - const result = await importDocumentToTiptap(file); - const newNote = await createNote({ - organizationSlug: selectedOrg.slug, - title: result.title, - grouping: 'WORKSPACE', - documentType, - }); - await updateNoteContent({ - note: newNote.id, - fullSrc: result.html, - fullJson: JSON.stringify(result.json), - plainText: result.plainText, - }); - onClose(); - router.push(`/notebook/${selectedOrg.slug}/${newNote.id}`); - } catch (error) { - const message = - error instanceof Error - ? error.message - : 'Failed to import document. Please try a different file.'; - toast.error(message, { style: { width: '320px' } }); - setIsImporting(false); - } - }; - - const validateAndImport = (file: File | null) => { - if (!file) return; - if (!detectImportFormat(file)) { - setUploadError('Only .docx, .odt, and .md files are supported.'); - return; - } - if (file.size > MAX_UPLOAD_SIZE) { - setUploadError('That file is larger than 25 MB. Try a smaller document.'); - return; - } - setUploadError(null); - void importDocument(file); - }; - - const handleFileChange = (event: React.ChangeEvent) => { - const picked = event.target.files?.[0] ?? null; - event.target.value = ''; // allow re-selecting the same file - validateAndImport(picked); - }; - - const handleDrop = (event: React.DragEvent) => { - event.preventDefault(); - setIsDragging(false); - if (isImporting) return; - validateAndImport(event.dataTransfer.files?.[0] ?? null); - }; - - return ( - <> - - -
-

{title}

-

{description}

-
- - - - {uploadError && ( -

- {uploadError} -

- )} - - - - ); -}; diff --git a/components/Funding/OpenFundingOpportunityModal.tsx b/components/Funding/OpenFundingOpportunityModal.tsx deleted file mode 100644 index f6bf9bf1e..000000000 --- a/components/Funding/OpenFundingOpportunityModal.tsx +++ /dev/null @@ -1,341 +0,0 @@ -'use client'; - -import { useEffect, useState, useTransition } from 'react'; -import Link from 'next/link'; -import { Dialog } from '@headlessui/react'; -import { - ArrowLeft, - ArrowRight, - ArrowUpRight, - Award, - FileText, - Sparkles, - Upload, - Users, - X, -} from 'lucide-react'; -import { BaseModal } from '@/components/ui/BaseModal'; -import { Button, buttonVariants } from '@/components/ui/Button'; -import Icon from '@/components/ui/icons/Icon'; -import { ResearchCoinIcon } from '@/components/ui/icons/ResearchCoinIcon'; -import dynamic from 'next/dynamic'; -import AnimatedGlobe from '@/components/Globe/AnimatedGlobe'; -import { cn } from '@/utils/styles'; - -const DocumentUploadStep = dynamic( - () => import('@/components/Funding/DocumentUploadStep').then((mod) => mod.DocumentUploadStep), - { ssr: false } -); - -export type FundingOpportunityCreationMethod = 'template' | 'upload' | 'blank'; - -interface OpenFundingOpportunityModalProps { - isOpen: boolean; - onClose: () => void; - onConfirm: (method: FundingOpportunityCreationMethod) => void; - /** - * Render a compact, single-column modal that jumps straight to the creation - * method picker — no benefits step and no decorative left rail. Used by entry - * points (e.g. the notebook) where the user has already committed to opening - * a funding opportunity. - */ - minimal?: boolean; -} - -interface Benefit { - id: string; - title: string; - description: string; - icon: React.ReactNode; - learnMoreHref?: string; -} - -const BENEFITS: Benefit[] = [ - { - id: 'scientists', - title: 'The best scientists within reach', - description: - 'We source the best scientists in the world to apply for your request for proposal.', - icon: , - learnMoreHref: '/give', - }, - { - id: 'turnaround', - title: 'Fastest turnaround', - description: 'Quality proposals and peer-reviews delivered in days, not months.', - icon: , - }, - { - id: 'community', - title: 'Community matching', - description: 'With our community, every dollar you put in is stretched further.', - icon: , - }, - { - id: 'credits', - title: 'Use your Funding Credits', - description: 'Earned by holding ResearchCoin or peer reviewing.', - icon: , - learnMoreHref: '/endowments', - }, -]; - -interface CreationOption { - id: FundingOpportunityCreationMethod; - title: string; - description: string; - icon: React.ReactNode; -} - -const CREATION_OPTIONS: CreationOption[] = [ - { - id: 'template', - title: 'From a template', - description: 'Start with our RFP template', - icon: , - }, - { - id: 'upload', - title: 'Upload a document', - description: 'Import a Word, Markdown, or OpenDocument file', - icon: , - }, -]; - -/** Where a funder books time with the ResearchHub team to shape an RFP together. */ -export const WHITE_GLOVE_BOOKING_URL = 'https://cal.com/tyler-diorio/15min'; - -type Step = 'benefits' | 'method' | 'upload'; - -export const OpenFundingOpportunityModal = ({ - isOpen, - onClose, - onConfirm, - minimal = false, -}: OpenFundingOpportunityModalProps) => { - const initialStep: Step = minimal ? 'method' : 'benefits'; - const [step, setStep] = useState(initialStep); - const [pendingMethod, setPendingMethod] = useState(null); - const [isPending, startTransition] = useTransition(); - - const handleClose = () => { - if (isPending) return; - onClose(); - }; - - const handleConfirmMethod = (method: FundingOpportunityCreationMethod) => { - setPendingMethod(method); - startTransition(() => { - onConfirm(method); - }); - }; - - // Reset to the first step whenever the modal is reopened so a returning user - // always starts from the configured entry step rather than a stale step. - // Skip while a route transition is pending so the method step doesn't flash - // back to the initial step before navigation completes. - useEffect(() => { - if (!isOpen && !isPending) { - setStep(initialStep); - setPendingMethod(null); - } - }, [isOpen, initialStep, isPending]); - - return ( - -
- {/* Left gradient rail */} - {!minimal && ( -
- {/* Mobile close button (lives in the title section on small screens) */} - - {/* Soft glow blobs */} -
-
-
-
- -
- - Open a request for proposal - -

- The most efficient way to fund science. -

-
-
- )} - - {/* Right content */} -
- - - {step === 'benefits' ? ( - <> -
-

- Why fund on ResearchHub -

-
- -
- {BENEFITS.map((benefit) => ( -
-
- {benefit.icon} -
-
-
- {benefit.title} -
-
- {benefit.description} -
-
-
- ))} -
- -
-
- - Learn more - - -
-
- - ) : step === 'method' ? ( - <> - {!minimal && ( - - )} - -
-

How do you want to start?

-
- -
- {CREATION_OPTIONS.map((option) => ( - - ))} -
- -
- - or - -
- - -
- -
-
-
- White-glove setup -
-
- Book a 15-minute call and our team will set it up with you. -
-
- -
- - ) : ( - setStep('method')} - onClose={handleClose} - /> - )} -
-
- - ); -}; diff --git a/components/Funding/OpenProposalModal.tsx b/components/Funding/OpenProposalModal.tsx deleted file mode 100644 index dc29084c3..000000000 --- a/components/Funding/OpenProposalModal.tsx +++ /dev/null @@ -1,270 +0,0 @@ -'use client'; - -import { useEffect, useState } from 'react'; -import { Dialog } from '@headlessui/react'; -import { ArrowLeft, ArrowRight, File, FileText, Globe, Lock, Upload, Users, X } from 'lucide-react'; -import { BaseModal } from '@/components/ui/BaseModal'; -import { Button } from '@/components/ui/Button'; -import dynamic from 'next/dynamic'; -import AnimatedProposal from '@/components/Proposal/AnimatedProposal'; -import { cn } from '@/utils/styles'; - -const DocumentUploadStep = dynamic( - () => import('@/components/Funding/DocumentUploadStep').then((mod) => mod.DocumentUploadStep), - { ssr: false } -); - -export type ProposalCreationMethod = 'template' | 'upload' | 'blank'; - -interface OpenProposalModalProps { - isOpen: boolean; - onClose: () => void; - onConfirm: (method: ProposalCreationMethod) => void; - /** - * Render a compact, single-column modal that jumps straight to the creation - * method picker — no benefits step and no decorative left rail. Used by entry - * points (e.g. the notebook) where the user has already committed to creating - * a proposal. - */ - minimal?: boolean; -} - -interface Benefit { - id: string; - title: string; - description: string; - icon: React.ReactNode; -} - -const BENEFITS: Benefit[] = [ - { - id: 'community', - title: 'Reach a global community', - description: 'Put your proposal in front of thousands of funders who care about your field.', - icon: , - }, - { - id: 'matching', - title: 'Community matching', - description: 'Your proposal is eligible for funding from institutions or community members.', - icon: , - }, - { - id: 'open', - title: 'Stay open & in control', - description: 'You can control whether your proposal is public or visible to funders only.', - icon: , - }, -]; - -interface CreationOption { - id: ProposalCreationMethod; - title: string; - description: string; - icon: React.ReactNode; -} - -const CREATION_OPTIONS: CreationOption[] = [ - { - id: 'template', - title: 'From a template', - description: 'Start with our guided proposal template', - icon: , - }, - { - id: 'upload', - title: 'Upload a document', - description: 'Import a Word, Markdown, or OpenDocument file', - icon: , - }, - { - id: 'blank', - title: 'Start blank', - description: 'Begin with an empty page', - icon: , - }, -]; - -type Step = 'benefits' | 'method' | 'upload'; - -export const OpenProposalModal = ({ - isOpen, - onClose, - onConfirm, - minimal = false, -}: OpenProposalModalProps) => { - const initialStep: Step = minimal ? 'method' : 'benefits'; - const [step, setStep] = useState(initialStep); - - // Reset to the first step whenever the modal is reopened so a returning user - // always starts from the configured entry step rather than a stale step. - useEffect(() => { - if (!isOpen) setStep(initialStep); - }, [isOpen, initialStep]); - - return ( - -
- {/* Left visual rail */} - {!minimal && ( -
- {/* Mobile close button */} - - {/* Soft glow blobs */} -
-
- -
- {/* AnimatedProposal scales via CSS transform, which keeps its full - natural layout height (~367px) reserved. We pin the container to - the *visual* height so the left rail doesn't tower over the - right column and leave whitespace below the CTA. */} -
- -
- - Open a Proposal - -

- Turn your proposal into funded science. -

-
-
- )} - - {/* Right content */} -
- - - {step === 'benefits' ? ( - <> -
-

- Why publish on ResearchHub -

-
- -
- {BENEFITS.map((benefit) => ( -
-
- {benefit.icon} -
-
-
- {benefit.title} -
-
- {benefit.description} -
-
-
- ))} -
- -
-
- -
-
- - ) : step === 'method' ? ( - <> - {!minimal && ( - - )} - -
-

- How do you want to start your proposal? -

-
- -
- {CREATION_OPTIONS.map((option) => ( - - ))} -
- - ) : ( - setStep('method')} - onClose={onClose} - /> - )} -
-
- - ); -}; diff --git a/components/Funding/fundingDraftOptions.tsx b/components/Funding/fundingDraftOptions.tsx index 47ddb2114..6cc1010f6 100644 --- a/components/Funding/fundingDraftOptions.tsx +++ b/components/Funding/fundingDraftOptions.tsx @@ -42,7 +42,11 @@ export const FUNDING_DRAFT_OPTIONS: readonly FundingDraftOption[] = [ ]; /** One option's face: its icon in a tile, its name and what it is for. */ -export function FundingDraftOptionContent({ option }: { readonly option: FundingDraftOption }) { +export function FundingDraftOptionContent({ + option, +}: { + readonly option: Pick; +}) { return (
diff --git a/components/LegacyNoteBanner.tsx b/components/LegacyNoteBanner.tsx deleted file mode 100644 index 67bf1f46f..000000000 --- a/components/LegacyNoteBanner.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { AlertTriangle, ExternalLink } from 'lucide-react'; -import { isProduction } from '@/utils/featureFlags'; - -interface LegacyNoteBannerProps { - orgSlug: string; - noteId: string; -} - -/** - * Banner component that displays a warning for legacy notes - * and provides a link to view/edit them in the original notebook system - */ -export const LegacyNoteBanner = ({ orgSlug, noteId }: LegacyNoteBannerProps) => { - // Determine the correct URL based on environment - const baseUrl = isProduction() - ? 'https://old.researchhub.com' - : 'https://old.staging.researchhub.com'; - - const legacyNoteUrl = `${baseUrl}/${orgSlug}/notebook/${noteId}`; - - return ( -
-
-
- -
-
-

- - This note was created in our previous notebook system and needs to be edited there. - - - View and edit in original notebook - - -

-
-
-
- ); -}; diff --git a/components/Notebook/AgentChatPanel.tsx b/components/Notebook/AgentChatPanel.tsx deleted file mode 100644 index cd1dd9911..000000000 --- a/components/Notebook/AgentChatPanel.tsx +++ /dev/null @@ -1,644 +0,0 @@ -'use client'; - -import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent } from 'react'; -import { Check, MessageSquarePlus, Pencil, X } from 'lucide-react'; -import { Button } from '@/components/ui/Button'; -import { Loader } from '@/components/ui/Loader'; -import { cn } from '@/utils/styles'; -import { useNotebookContext } from '@/contexts/NotebookContext'; -import { useAgentChatList } from '@/hooks/useAgentChat'; -import { useChatSession } from '@/hooks/useChatSession'; -import { getChatTransport } from '@/services/chatTransport'; -import { useJumpToLatest } from '@/hooks/useJumpToLatest'; -import { MAX_AGENT_CHAT_WIDTH, MIN_AGENT_CHAT_WIDTH } from '@/hooks/useAgentChatWidth'; -import { isRfpNote } from '@/types/note'; -import { MAX_CHAT_TITLE_LENGTH, type AgentChat } from '@/types/agentChat'; -import { useEditorIsEmpty } from '@/hooks/useEditorIsEmpty'; -import { NoteReviewControls } from '@/components/Notebook/NoteReview/NoteReviewControls'; -import { NoteReviewBanner } from '@/components/Notebook/NoteReview/NoteReviewBanner'; -import { useNoteAgentReview } from '@/components/Notebook/NoteReview/useNoteAgentReview'; -import { ChatComposer } from '@/components/AgentChat/ChatComposer'; -import type { ChatNoticePolicy } from '@/components/AgentChat/chatNotices'; -import { ChatPicker } from '@/components/AgentChat/ChatPicker'; -import { ChatEmptyState } from '@/components/AgentChat/ChatEmptyState'; -import { ChatSources, collectChatSources } from '@/components/AgentChat/ChatSources'; -import { ChatTranscript } from '@/components/AgentChat/ChatTranscript'; -import { CreditMeter } from '@/components/AgentChat/CreditMeter'; -import { canSelectAIModel } from '@/types/researchAI'; -import { ModelControls } from '@/components/AgentChat/ModelControls'; - -type PanelTab = 'chat' | 'sources'; - -/** Pixels per arrow key press while the resize divider has focus. */ -const RESIZE_KEY_STEP = 24; - -/** The meter beside the composer already says when the budget is spent. */ -const NOTICES: ChatNoticePolicy = { noun: 'chat', usageLimit: 'meter' }; - -/** - * A running in-note review session, handed to the host so the accept/reject - * controls can live on the note page rather than in the chat panel. - */ -export interface NoteReviewHandle { - readonly changeCount: number; - /** Keep the assistant's side: deletes the struck ranges, keeps the rest. */ - readonly accept: () => void; - /** Keep the reader's side: deletes the inserted ranges and persists it. */ - readonly reject: () => void; -} - -interface AgentChatPanelProps { - readonly noteId: string; - readonly open: boolean; - readonly onClose: () => void; - /** The server denied access (gate changed / signed out) — hide the entry point. */ - readonly onUnavailable: () => void; - /** - * The editor's current document must be persisted as a new server version: - * the user chose "Keep mine" over an assistant version, or a reload applied - * an assistant version that newer saves had buried. Applying content - * programmatically emits no editor update, so without this save the choice - * would only live in this editor instance and vanish on the next load. - * Persists immediately and resolves with whether the save reached the - * server — the panel acknowledges the choice only on success. - */ - readonly onPersistEditorState?: () => Promise; - /** - * Docked (desktop) mode: the panel takes `width` and the host reserves the - * same gutter, so it sits beside the document instead of over it. Undocked, - * it covers the viewport as a sheet. - */ - readonly docked: boolean; - readonly width: number; - readonly isResizing: boolean; - readonly onResizeStart: () => void; - /** Keyboard resize from the divider; negative widens the panel. */ - readonly onResizeNudge: (deltaX: number) => void; - /** - * An in-note review started or ended. The host renders the accept/restore - * controls over the note; null means no review is active. - */ - readonly onReviewChange?: (review: NoteReviewHandle | null) => void; -} - -/** - * The notebook AI assistant panel: chat picker, transcript with live turn - * progress, and composer. Stays mounted while the notebook is open so chat - * selection and drafts survive closing the panel. Chat requests are gated on - * `open`; user-wide allowances load with the notebook. - */ -export function AgentChatPanel({ - noteId, - open, - onClose, - onUnavailable, - onPersistEditorState, - docked, - width, - isResizing, - onResizeStart, - onResizeNudge, - onReviewChange, -}: AgentChatPanelProps) { - const { editor, currentNote } = useNotebookContext(); - // Decide which writing preset the empty chat screen offers, and what it - // calls the document: the notebook holds RFPs as well as proposals. - const noteIsEmpty = useEditorIsEmpty(editor); - const noteIsRfp = isRfpNote(currentNote); - - // One transport per note: the hooks reset on its identity. - const transport = getChatTransport({ noteId }); - const list = useAgentChatList(transport, open); - // Null is the new-chat screen, and it is where a page visit starts: the - // assistant opens on its own opening moves rather than dropping the reader - // into the middle of whatever they last asked. Earlier chats stay one click - // away in the picker, and a selection survives closing the panel — only a - // fresh visit or a note switch resets it. - const [selectedChatId, setSelectedChatId] = useState(null); - const switchChat = useCallback((nextChatId: number | null) => setSelectedChatId(nextChatId), []); - - // Network activity is gated on `open`. No keep-alive is needed for turns - // that finish while the panel is closed or another chat is selected: the - // note version socket below reports agent edits from any chat, and - // reopening (or reselecting) refetches the transcript. - const refreshList = list.refresh; - const onListStale = useCallback(() => { - if (open) refreshList(); - }, [open, refreshList]); - const onChatCreated = useCallback((created: AgentChat) => { - setSelectedChatId(created.conversation_id); - }, []); - const session = useChatSession({ - transport, - chatId: selectedChatId, - enabled: open, - onChatCreated, - onListStale, - notices: NOTICES, - }); - const { - chat: chatState, - modelSelection, - researchAI, - draft, - setDraft: updateDraft, - attachments, - notice, - clearNotice, - sendBlocked: budgetSendDisabled, - composerBusy, - canStop, - send, - } = session; - const hasModelSelection = canSelectAIModel(researchAI.budget?.tier); - const canSelectModel = hasModelSelection && researchAI.catalog !== null; - - const composerRef = useRef(null); - const panelRef = useRef(null); - - /** - * A preset loads the composer rather than sending: its message is a starting - * point, and the details that make it worth sending — the deadline, the - * section, the sub-field — are the user's to add. Focus follows the text so - * the caret is already waiting at the end of it. - */ - const applyPreset = useCallback( - (message: string) => { - clearNotice(); - updateDraft(message); - const textarea = composerRef.current; - if (!textarea) return; - textarea.focus(); - textarea.setSelectionRange(message.length, message.length); - }, - [clearNotice, updateDraft] - ); - - // ---- a note switch starts on the new-chat screen ---- - useEffect(() => { - setSelectedChatId(null); - }, [noteId]); - - // ---- server-side access gate ---- - const [deniedNoteId, setDeniedNoteId] = useState(null); - const accessNoteRef = useRef(noteId); - useEffect(() => { - if (accessNoteRef.current !== noteId) { - accessNoteRef.current = noteId; - setDeniedNoteId(null); - // The chat hooks reset after a note switch; their current access values - // can still belong to the previous note on this render. - return; - } - if (list.access === 'hidden' || chatState.access === 'unauthorized') { - setDeniedNoteId(noteId); - } - }, [noteId, list.access, chatState.access]); - const accessDenied = deniedNoteId === noteId; - - useEffect(() => { - // Leave a visible restriction until the user closes the panel. A blocked - // account keeps the entry point so its unavailable state remains reachable. - if ( - !open && - researchAI.budgetStatus !== 'loading' && - researchAI.budget?.tier !== 'blocked' && - accessDenied - ) { - onUnavailable(); - } - }, [open, accessDenied, onUnavailable, researchAI.budgetStatus, researchAI.budget?.tier]); - - // ---- rename ---- - const [renaming, setRenaming] = useState(false); - const [renameValue, setRenameValue] = useState(''); - - const startRename = () => { - if (selectedChatId == null) return; - setRenameValue(chatState.chat?.title ?? ''); - setRenaming(true); - }; - - const sessionKeyRef = useRef(session.sessionKey); - sessionKeyRef.current = session.sessionKey; - const commitRename = async () => { - setRenaming(false); - const title = renameValue.trim(); - if (!title || title === (chatState.chat?.title ?? '')) return; - const key = session.sessionKey; - const renamed = await chatState.rename(title); - // A rename that raced a switch must not fire its note-bound refresh — the - // stale fetch would outrank and replace the current note's listing. - if (renamed && sessionKeyRef.current === key) refreshList(); - }; - - // A rename left open across a note switch would commit against whichever - // chat the new note auto-selects — it dies with the note that owned it. - useEffect(() => { - setRenaming(false); - }, [noteId]); - - // ---- assistant-version review of the note ---- - // The editor is the notebook's own; the hook keeps it in step with the - // versions the assistant writes and hands back the review to render. - const loadedNote = useMemo( - () => (currentNote ? { id: currentNote.id, versionId: currentNote.versionId } : null), - [currentNote] - ); - const noteReview = useNoteAgentReview({ - noteId, - editor, - loadedNote, - chat: chatState.chat, - onPersistEditorState, - }); - const { review, accept: acceptReview, reject: rejectReview } = noteReview; - - // The accept/reject controls render on the note page, next to the content - // they decide about — hand the host the current session, and null when it - // ends or this panel unmounts. - useEffect(() => { - if (!onReviewChange) return; - onReviewChange( - review == null - ? null - : { changeCount: review.changeCount, accept: acceptReview, reject: rejectReview } - ); - return () => onReviewChange(null); - }, [review, onReviewChange, acceptReview, rejectReview]); - - // ---- chat / sources tabs ---- - const sources = useMemo(() => collectChatSources(chatState.chat), [chatState.chat]); - const [activeTab, setActiveTab] = useState('chat'); - // A new chat starts with no citations, so a lingering Sources tab would open - // on an empty list. - useEffect(() => { - setActiveTab('chat'); - }, [selectedChatId, noteId]); - - // ---- transcript auto-scroll ---- - const { scrollRef, handleScroll, follow } = useJumpToLatest({ - resetKey: selectedChatId, - }); - useEffect(() => { - // The sources list shares this scroller; pinning it to the bottom on every - // transcript update would yank the citation the user is reading. - if (activeTab === 'chat') follow(); - }, [chatState.chat, chatState.pendingSend, activeTab, follow]); - - // ---- derived composer state ---- - const chatAccessible = selectedChatId == null ? list.access === 'ok' : chatState.access === 'ok'; - const composerDisabled = accessDenied || !chatAccessible; - - const emptyState = ( - - ); - - const renderBody = () => { - if ( - researchAI.budget?.tier === 'blocked' || - accessDenied || - list.access === 'hidden' || - chatState.access === 'unauthorized' - ) { - return ( - - You do not have access to the research assistant for this notebook. - - ); - } - if (selectedChatId == null) { - if (list.access === 'loading') return ; - if (list.access === 'error') { - return refreshList()} />; - } - return emptyState; - } - - switch (chatState.access) { - case 'loading': - return ; - case 'not_found': - return ( -
-

This chat is no longer available.

- -
- ); - case 'error': - return ( - chatState.refetch()} /> - ); - default: { - if (!chatState.chat) return ; - const isEmpty = - chatState.chat.messages.length === 0 && - chatState.chat.executions.length === 0 && - !chatState.pendingSend; - if (isEmpty) return emptyState; - return ; - } - } - }; - - return ( - - ); -} - -function TabButton({ - active, - onClick, - label, - count, -}: { - readonly active: boolean; - readonly onClick: () => void; - readonly label: string; - readonly count?: number; -}) { - return ( - - ); -} - -function CenteredLoader() { - return ( -
- -
- ); -} - -function ErrorState({ - message, - onRetry, -}: { - readonly message: string; - readonly onRetry: () => void; -}) { - return ( -
-

{message}

- -
- ); -} diff --git a/components/Notebook/LeftSidebar/NoteList.tsx b/components/Notebook/LeftSidebar/NoteList.tsx deleted file mode 100644 index 7ca854f00..000000000 --- a/components/Notebook/LeftSidebar/NoteList.tsx +++ /dev/null @@ -1,78 +0,0 @@ -'use client'; - -import { NoteListItem } from '@/components/Notebook/LeftSidebar/NoteListItem'; -import { isChangelogNote, type Note } from '@/types/note'; -import { NoteListSkeleton } from '@/components/skeletons/NoteListSkeleton'; -import { useTransition } from 'react'; -import { useUser } from '@/contexts/UserContext'; -import { useInView } from 'react-intersection-observer'; -import { useNotebookContext } from '@/contexts/NotebookContext'; - -interface NoteListProps { - notes: Note[]; - isLoading?: boolean; -} - -export const NoteList: React.FC = ({ notes, isLoading = false }) => { - const [isPending, startTransition] = useTransition(); - const { user } = useUser(); - const { hasMoreNotes, isLoadingMoreNotes, loadMoreNotes, notesError } = useNotebookContext(); - const isModerator = !!user?.isModerator; - - const { ref: sentinelRef } = useInView({ - threshold: 0, - rootMargin: '200px', - onChange: (inView) => { - if (inView) { - loadMoreNotes(); - } - }, - }); - - const filteredAndSortedNotes = notes - .filter( - (note) => - (note.access === 'WORKSPACE' || note.access === 'SHARED' || note.access === 'PRIVATE') && - (isModerator || !isChangelogNote(note)) - ) - .sort((a, b) => new Date(b.updatedDate).getTime() - new Date(a.updatedDate).getTime()); - - if (isLoading || notes.length === 0) { - return ; - } - - if (filteredAndSortedNotes.length === 0 && !hasMoreNotes) { - return ( -
-

No notes yet

-
- ); - } - - return ( -
- {filteredAndSortedNotes.map((note) => ( - - ))} - {isLoadingMoreNotes && } - {!isLoadingMoreNotes && - hasMoreNotes && - (notesError ? ( - - ) : ( - - ); -}; diff --git a/components/Notebook/LeftSidebar/NoteListItem.tsx b/components/Notebook/LeftSidebar/NoteListItem.tsx deleted file mode 100644 index 3bf6cc414..000000000 --- a/components/Notebook/LeftSidebar/NoteListItem.tsx +++ /dev/null @@ -1,153 +0,0 @@ -'use client'; - -import { File, MoreHorizontal, Copy, Trash2, Loader2 } from 'lucide-react'; -import { Button } from '@/components/ui/Button'; -import { cn } from '@/utils/styles'; -import { useRouter } from 'next/navigation'; -import { BaseMenu, BaseMenuItem } from '@/components/ui/form/BaseMenu'; -import { useDeleteNote, useDuplicateNote } from '@/hooks/useNote'; -import type { Note } from '@/types/note'; -import toast from 'react-hot-toast'; -import { useState, useCallback, useRef, useEffect } from 'react'; -import { useNotebookContext } from '@/contexts/NotebookContext'; - -interface NoteListItemProps { - note: Note; - disabled: boolean; - startTransition: (callback: () => void) => void; -} - -export const NoteListItem = ({ note, disabled, startTransition }: NoteListItemProps) => { - const router = useRouter(); - const { refreshNotes, setNotes, activeNoteId } = useNotebookContext(); - const [{ isLoading: isDeleting }, deleteNote] = useDeleteNote(); - const [{ isLoading: isDuplicating }, duplicateNote] = useDuplicateNote(); - const [isMenuOpen, setIsMenuOpen] = useState(false); - const itemRef = useRef(null); - - const isProcessing = isDeleting || isDuplicating; - const isSelected = note.id.toString() === activeNoteId; - - useEffect(() => { - if (isSelected && itemRef.current) { - const timeoutId = setTimeout(() => { - itemRef.current?.scrollIntoView({ - behavior: 'smooth', - block: 'nearest', - }); - }, 100); - - return () => clearTimeout(timeoutId); - } - }, [isSelected]); - - const handleClick = useCallback(() => { - startTransition(() => { - router.push(`/notebook/${note.organization.slug}/${note.id}`, { scroll: false }); - }); - }, [router, note.organization.slug, note.id, startTransition]); - - const handleDuplicate = async (e: React.MouseEvent) => { - e.stopPropagation(); - try { - const newNote = await duplicateNote(note.id.toString(), note.organization.slug); - toast.success('Note duplicated successfully'); - refreshNotes(); - router.replace(`/notebook/${note.organization.slug}/${newNote.id}`); - } catch (error) { - console.error('Error duplicating note:', error); - toast.error('Failed to duplicate note. Please try again.'); - } - }; - - const handleDelete = async (e: React.MouseEvent) => { - e.stopPropagation(); - if ( - !globalThis.confirm( - 'Are you sure you want to delete this note? This action cannot be undone.' - ) - ) { - return; - } - try { - await deleteNote(note.id); - refreshNotes(); - setNotes((prevNotes) => prevNotes.filter((n) => n.id !== note.id)); - if (isSelected) { - router.replace(`/notebook/${note.organization.slug}`); - } - } catch (error: unknown) { - console.error('Error deleting note:', error); - toast.error('Failed to delete note. Please try again.'); - } - }; - - const menuTriggerButton = ( - - ); - - return ( -
- - -
- - -
- {isDuplicating ? ( - - ) : ( - - )} - {isDuplicating ? 'Duplicating...' : 'Duplicate'} -
-
- -
- {isDeleting ? ( - - ) : ( - - )} - {isDeleting ? 'Deleting...' : 'Delete'} -
-
-
-
-
- ); -}; diff --git a/components/Notebook/NoteCreationPopover.tsx b/components/Notebook/NoteCreationPopover.tsx deleted file mode 100644 index 2d753a12b..000000000 --- a/components/Notebook/NoteCreationPopover.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { ReactNode } from 'react'; - -interface NoteCreationPopoverProps { - isOpen: boolean; - children?: ReactNode; -} - -export const NoteCreationPopover = ({ isOpen, children }: NoteCreationPopoverProps) => { - if (!isOpen) return null; - - return ( -
-
-
-
-
-

Creating Note

-
-

Please wait...

-
-
-
- {children &&
{children}
} -
-
- ); -}; diff --git a/components/Notebook/NoteEditorLayout.tsx b/components/Notebook/NoteEditorLayout.tsx deleted file mode 100644 index 53ff1e17b..000000000 --- a/components/Notebook/NoteEditorLayout.tsx +++ /dev/null @@ -1,409 +0,0 @@ -'use client'; - -import { useState, useEffect, useRef, useCallback } from 'react'; -import { useSearchParams } from 'next/navigation'; -import { ArrowRight, Sparkles } from 'lucide-react'; -import { cn } from '@/utils/styles'; -import { Button } from '@/components/ui/Button'; - -import { BlockEditor } from '@/components/Editor/components/BlockEditor/BlockEditor'; -import { NotePaperWrapper } from './NotePaperWrapper'; -import { NotePaperSkeleton } from './NotePaperSkeleton'; -import { NotebookHome } from './NotebookHome'; -import { NotebookTour } from './NotebookTour'; -import { NotebookTabs, type NotebookTab } from './NotebookTabs'; -import { NotesMenu } from './NotesMenu'; -import { PublishedStatusSection } from './PublishingForm/components/PublishedStatusSection'; -import { PublishingForm, PublishingFormProvider } from '@/components/Notebook/PublishingForm'; - -import { ABOVE_MOBILE_NAV } from './mobileBarOffsets'; -import { AgentChatPanel, type NoteReviewHandle } from '@/components/Notebook/AgentChatPanel'; -import { noteDiffPersistableDoc } from './NoteReview/noteDiffOverlay'; -import { NoteReviewControls } from './NoteReview/NoteReviewControls'; -import { useNotebookContext } from '@/contexts/NotebookContext'; -import { useOrganizationContext } from '@/contexts/OrganizationContext'; -import { useUser } from '@/contexts/UserContext'; -import { useScreenSize } from '@/hooks/useScreenSize'; -import { useAgentChatWidth } from '@/hooks/useAgentChatWidth'; -import { useUpdateNote } from '@/hooks/useNote'; -import { useTopBarSlot } from '@/contexts/TopBarSlotContext'; -import { useDismissableFeature } from '@/hooks/useDismissableFeature'; -import { LegacyNoteBanner } from '@/components/LegacyNoteBanner'; -import { - getNoteKind, - isChangelogNote, - isPublishedRegisteredReportNote, - NOTE_KIND_LABELS, -} from '@/types/note'; - -// Persisted (per-user) flag so the guided tour auto-runs only once — the very -// first time someone lands in the editor on a freshly-created note. -const NOTEBOOK_TOUR_FEATURE = 'notebook_tour'; - -// Query params the note-creation flows append when redirecting to the editor. -// Their presence means the user just created this note (vs. opening an existing -// one), which is the only moment we want to auto-launch the tour. -const NEW_NOTE_PARAMS = ['newChangelog', 'newGrant', 'newFunding', 'template']; - -interface NoteEditorLayoutProps { - /** - * Fires when the assistant docks or undocks. Docking is decided here — it - * depends on the viewport, the access gate and the note — but the page - * container above has to widen in step, or its centring margins strand a - * band of empty space beside the shrunken document. - */ - readonly onAgentChatDockedChange?: (docked: boolean) => void; -} - -export function NoteEditorLayout({ onAgentChatDockedChange }: NoteEditorLayoutProps = {}) { - const { - currentNote: note, - isLoadingNote, - noteError, - setEditor, - updateNoteTitle, - saveDetailsSoon, - activeNoteId, - editor, - } = useNotebookContext(); - - const { selectedOrg } = useOrganizationContext(); - const { user, isLoading: isLoadingUser } = useUser(); - const { lgAndUp, xlAndUp } = useScreenSize(); - const isDesktop = lgAndUp; - - const topBarSlot = useTopBarSlot(); - const setLeftSlot = topBarSlot?.setLeftSlot; - const searchParams = useSearchParams(); - - const { - isDismissed: isTourDismissed, - dismissFeature: dismissTour, - dismissStatus: tourDismissStatus, - } = useDismissableFeature(NOTEBOOK_TOUR_FEATURE); - - const [isLegacyNote, setIsLegacyNote] = useState(undefined); - const [activeTab, setActiveTab] = useState(() => - searchParams?.get('tab') === 'details' ? 'details' : 'document' - ); - - // ---- AI assistant chat ---- - const [isAgentChatOpen, setIsAgentChatOpen] = useState(false); - // Flipped when the server denies access (the gate can change server-side); - // hides the entry point while this note is open. - const [agentChatUnavailable, setAgentChatUnavailable] = useState(false); - // Active in-note review of an assistant version: the panel drives the - // overlay, this layout renders the accept/restore controls over the note. - const [agentReview, setAgentReview] = useState(null); - - const handleAgentChatUnavailable = useCallback(() => { - setAgentChatUnavailable(true); - setIsAgentChatOpen(false); - }, []); - - // The server's denial is note/hub-scoped and this layout survives note - // navigation — re-arm the entry point on the next note so a denial in one - // hub doesn't permanently hide the assistant in hubs the user does edit. - useEffect(() => { - setAgentChatUnavailable(false); - }, [activeNoteId]); - - const { - width: agentChatWidth, - isResizing: isAgentChatResizing, - startResize: startAgentChatResize, - nudgeWidth: nudgeAgentChatWidth, - } = useAgentChatWidth(); - - const isChangelog = isChangelogNote(note); - const isChangelogAccessDenied = isChangelog && !user?.isModerator; - - const showAgentChat = - Boolean(user) && - !agentChatUnavailable && - // Changelogs are moderator-only: the page renders Note Not Found in place - // of the document, so the assistant must not mount over it. - !isChangelogAccessDenied && - Boolean(activeNoteId) && - Boolean(note) && - !noteError && - isLegacyNote === false; - - // Docking splits the viewport: the panel takes its own column and the - // document gives up the same gutter. Below xl there isn't enough room left - // to keep the document readable, so the panel covers it as a sheet instead. - const isAgentChatDocked = showAgentChat && isAgentChatOpen && xlAndUp === true; - const isUndockedChatOpen = showAgentChat && isAgentChatOpen && !isAgentChatDocked; - - useEffect(() => { - onAgentChatDockedChange?.(isAgentChatDocked); - }, [isAgentChatDocked, onAgentChatDockedChange]); - - // Unmounting with the panel open would otherwise leave the container wide. - useEffect(() => () => onAgentChatDockedChange?.(false), [onAgentChatDockedChange]); - - const previousNoteId = useRef(activeNoteId); - const [isTourOpen, setIsTourOpen] = useState(false); - const tourAutoStarted = useRef(false); - - const isNewlyCreatedNote = NEW_NOTE_PARAMS.some((param) => searchParams?.has(param)); - - useEffect(() => { - if (previousNoteId.current !== activeNoteId) { - setActiveTab('document'); - previousNoteId.current = activeNoteId; - } - }, [activeNoteId]); - - // Surface the "Notebook" notes dropdown in the shared TopBar's left area. - useEffect(() => { - if (!setLeftSlot) return; - setLeftSlot(); - return () => setLeftSlot(null); - }, [setLeftSlot]); - - // Auto-start the tour exactly once, the first time a user opens a note they - // just created. We wait until the note is fully set up (loaded + editor - // mounted) so the highlight target already has its final size/position — - // opening earlier anchors to the skeleton and the popover jumps when the real - // content swaps in. - const isNoteReady = !isLoadingNote && Boolean(note) && isLegacyNote === false && Boolean(editor); - useEffect(() => { - if (isDesktop !== true || tourAutoStarted.current) return; - if (tourDismissStatus !== 'checked' || isTourDismissed) return; - if (!isNewlyCreatedNote) return; - if (!isNoteReady) return; - tourAutoStarted.current = true; - setIsTourOpen(true); - dismissTour(); - }, [isDesktop, isNoteReady, tourDismissStatus, isTourDismissed, isNewlyCreatedNote, dismissTour]); - - useEffect(() => { - if (isLoadingNote) return; - if (!note || noteError) { - setIsLegacyNote(false); - return; - } - setIsLegacyNote(!note.contentJson); - }, [note, noteError, isLoadingNote]); - - const [, updateNote, saveNoteNow] = useUpdateNote(note?.id, { - saveTitle: (title) => saveDetailsSoon({ title }), - onTitleUpdate: updateNoteTitle, - registeredReportProposalId: note?.proposalId, - // While an assistant review is open the editor holds a merged document; - // saves must persist it without the struck (pending-removal) ranges. - docToPersist: (editorInstance) => - noteDiffPersistableDoc(editorInstance) ?? editorInstance.state.doc, - }); - - // The panel asks for the editor's current document to be persisted as the - // newest server version: the user chose "Keep mine" over an assistant - // version, or a reload applied an assistant version that newer saves had - // buried. Applying content programmatically emits no editor update, so - // without this save the editor and the server would silently diverge and - // the choice would vanish on the next load. The save runs immediately (a - // debounced one could be cancelled by navigation before it fires) and the - // result tells the panel whether the choice actually became durable. - const handlePersistEditorState = useCallback(async () => { - if (!editor || editor.isDestroyed) return false; - return saveNoteNow(editor); - }, [editor, saveNoteNow]); - - const showTabs = Boolean(note) && !isLegacyNote && !isChangelogAccessDenied; - const isPublishedRegisteredReport = isPublishedRegisteredReportNote(note); - const isEditorReadOnly = isPublishedRegisteredReport || isLegacyNote; - const noteKind = getNoteKind(note); - const workTypeLabel = isChangelog - ? 'ChangeLog' - : noteKind === 'other' - ? undefined - : NOTE_KIND_LABELS[noteKind]; - - const renderEditor = () => { - // No note is targeted (notebook home) — render the landing view directly so - // the document skeleton doesn't flash before the empty state resolves. - if (!activeNoteId) { - return ; - } - - if ((isChangelog && isLoadingUser) || isLoadingNote || isLegacyNote === undefined) { - return ; - } - - if ((noteError && activeNoteId) || isChangelogAccessDenied) { - return ( - -
-
-

Note Not Found

-

- The note you're looking for doesn't exist or you don't have - permission to view it. -

-
-
-
- ); - } - - if (!note) { - return ; - } - - return ( - - ) : undefined - } - > - {/* Work type + draft status pinned to the document's top-left corner. */} -
- {workTypeLabel && ( - {workTypeLabel} - )} - -
- -
- ); - }; - - if (isDesktop === null) return null; - - return ( -
-
- {showTabs && ( -
- {isPublishedRegisteredReport && ( -
- This Registered Report has been published and can no longer be edited. -
- )} -
- -
- {activeTab === 'document' && ( - - )} -
-
-
- )} - -
{renderEditor()}
- {showTabs && ( -
- - - -
- )} - - {isDesktop && setIsTourOpen(false)} />} -
- - {/* Floating over the document — but only while the document is visible. - Docked, the panel sits beside it and the controls shift by the panel's - width; undocked, the panel covers the document and carries its own - copy of these controls, so this one stands down. */} - {agentReview && (!showTabs || activeTab === 'document') && !isUndockedChatOpen && ( -
- -
- )} - - {/* - * Floats in the bottom-right corner, on the side the panel docks to. - * Below `tablet` it clears the 64px MobileBottomNav. It hides once open — - * the panel would cover it, and its close button is the way back. - */} - {showAgentChat && activeNoteId && !isAgentChatOpen && ( - - )} - - {showAgentChat && activeNoteId && ( - setIsAgentChatOpen(false)} - onUnavailable={handleAgentChatUnavailable} - onPersistEditorState={handlePersistEditorState} - onReviewChange={setAgentReview} - docked={isAgentChatDocked} - width={agentChatWidth} - isResizing={isAgentChatResizing} - onResizeStart={startAgentChatResize} - onResizeNudge={nudgeAgentChatWidth} - /> - )} -
- ); -} diff --git a/components/Notebook/NotePaperSkeleton.tsx b/components/Notebook/NotePaperSkeleton.tsx deleted file mode 100644 index 2425536ea..000000000 --- a/components/Notebook/NotePaperSkeleton.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { NotebookSkeleton } from '@/components/skeletons/NotebookSkeleton'; -import { NotePaperWrapper } from './NotePaperWrapper'; - -export const NotePaperSkeleton = () => { - return ( - - - - ); -}; diff --git a/components/Notebook/NotePaperWrapper.tsx b/components/Notebook/NotePaperWrapper.tsx deleted file mode 100644 index 79b762aca..000000000 --- a/components/Notebook/NotePaperWrapper.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { ReactNode } from 'react'; -import { cn } from '@/utils/styles'; - -/** Shared editor paper card — provides the left gutter (pl-16) and top padding. */ -interface NotePaperProps extends React.HTMLAttributes { - children: ReactNode; - className?: string; - minHeight?: string; -} - -export const NotePaper = ({ - children, - className, - minHeight = '800px', - ...rest -}: NotePaperProps) => { - return ( -
- {children} -
- ); -}; - -/** Full-page wrapper for notebook routes. Adds gray background, shadow, and optional banner. */ -interface NotePaperWrapperProps { - children: ReactNode; - className?: string; - showBanner?: ReactNode; - /** - * When false, render just the white paper card (no gray canvas / centering), - * letting the surrounding page supply the gray background. Used in the - * shared page layout where the scroll area is already gray. - */ - canvas?: boolean; -} - -export const NotePaperWrapper = ({ - children, - className = '', - showBanner, - canvas = true, -}: NotePaperWrapperProps) => { - const content = ( - <> - {showBanner && ( - - {showBanner} - - )} - - {children} - - - ); - - if (!canvas) { - return content; - } - - return ( -
-
-
{content}
-
-
- ); -}; diff --git a/components/Notebook/NotebookHome.tsx b/components/Notebook/NotebookHome.tsx deleted file mode 100644 index 238146bd7..000000000 --- a/components/Notebook/NotebookHome.tsx +++ /dev/null @@ -1,149 +0,0 @@ -'use client'; - -import { useState } from 'react'; -import { useRouter } from 'next/navigation'; -import { ArrowRight } from 'lucide-react'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faBullhorn, faFileSignature } from '@fortawesome/pro-light-svg-icons'; -import { NoteList } from '@/components/Notebook/LeftSidebar/NoteList'; -import { useNotebookContext } from '@/contexts/NotebookContext'; -import { - OpenFundingOpportunityModal, - type FundingOpportunityCreationMethod, -} from '@/components/Funding/OpenFundingOpportunityModal'; -import { - OpenProposalModal, - type ProposalCreationMethod, -} from '@/components/Funding/OpenProposalModal'; -import Icon from '@/components/ui/icons/Icon'; -import { NotePaperWrapper } from './NotePaperWrapper'; -import { useUser } from '@/contexts/UserContext'; - -interface CreateOption { - id: string; - title: string; - description: string; - icon: React.ReactNode; - onClick: () => void; -} - -/** - * Landing view for the notebook when no specific note is open. Mirrors the - * "Notebook" dropdown: surfaces the funding-opportunity / proposal creation - * flows alongside the user's existing files. - */ -export function NotebookHome() { - const router = useRouter(); - const { notes, isLoading: isLoadingNotes } = useNotebookContext(); - const { user } = useUser(); - const isModerator = !!user?.isModerator; - - const [isFundingOpportunityModalOpen, setIsFundingOpportunityModalOpen] = useState(false); - const [isProposalModalOpen, setIsProposalModalOpen] = useState(false); - - // Mirror PublishMenu / LeftSidebar: the modal picks a creation method, then we - // hand off to the notebook page which scaffolds the document from it. - const handleConfirmOpenGrant = (method: FundingOpportunityCreationMethod) => { - setIsFundingOpportunityModalOpen(false); - router.push(`/notebook?newGrant=true&grantSource=${method}`); - }; - - const handleConfirmCreateProposal = (method: ProposalCreationMethod) => { - setIsProposalModalOpen(false); - router.push(`/notebook?newFunding=true&proposalSource=${method}`); - }; - - const createOptions: CreateOption[] = [ - { - id: 'funding-opportunity', - title: 'Request for Proposal', - description: 'Fund specific research you care about', - icon: , - onClick: () => setIsFundingOpportunityModalOpen(true), - }, - { - id: 'proposal', - title: 'Proposal', - description: 'Raise money for your research', - icon: , - onClick: () => setIsProposalModalOpen(true), - }, - ...(isModerator - ? [ - { - id: 'changelog', - title: 'ChangeLog', - description: 'Publish a ResearchHub product update', - icon: , - onClick: () => router.push('/notebook?newChangelog=true'), - }, - ] - : []), - ]; - - const hasNotes = notes?.some( - (note) => note.access === 'WORKSPACE' || note.access === 'SHARED' || note.access === 'PRIVATE' - ); - - return ( - -
-
-

My Notebook

-

Start something new or jump back into your work.

-
- - {/* Create */} -
- {createOptions.map((option) => ( - - ))} -
- - {/* Files */} -
-

- Your files -

- {hasNotes || isLoadingNotes ? ( - - ) : ( -
- No files yet. Create an RFP or proposal to get started. -
- )} -
-
- - setIsFundingOpportunityModalOpen(false)} - onConfirm={handleConfirmOpenGrant} - minimal - /> - - setIsProposalModalOpen(false)} - onConfirm={handleConfirmCreateProposal} - minimal - /> -
- ); -} diff --git a/components/Notebook/NotebookPrimaryNavigation.tsx b/components/Notebook/NotebookPrimaryNavigation.tsx deleted file mode 100644 index 01cac0083..000000000 --- a/components/Notebook/NotebookPrimaryNavigation.tsx +++ /dev/null @@ -1,138 +0,0 @@ -'use client'; - -import { NoteList } from '@/components/Notebook/LeftSidebar/NoteList'; -import { useOrganizationContext } from '@/contexts/OrganizationContext'; -import { UserPlus } from 'lucide-react'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faBullhorn, faFileSignature } from '@fortawesome/pro-light-svg-icons'; -import { useNotebookContext } from '@/contexts/NotebookContext'; -import Icon from '@/components/ui/icons/Icon'; -import { useUser } from '@/contexts/UserContext'; - -export const NOTEBOOK_WORK_TYPES = [ - { - value: 'grant', - label: 'RFP', - description: 'Offer funding for research applications.', - }, - { - value: 'preregistration', - label: 'Proposal', - description: 'Create a research proposal and optionally raise funding.', - }, - { - value: 'discussion', - label: 'ChangeLog', - description: 'Publish a ResearchHub product update.', - }, -] as const; - -export const getAvailableNotebookWorkTypes = (isModerator: boolean) => - NOTEBOOK_WORK_TYPES.filter((workType) => workType.value !== 'discussion' || isModerator); - -type NotebookWorkType = (typeof NOTEBOOK_WORK_TYPES)[number]['value']; - -const SectionHeading = ({ children }: { children: React.ReactNode }) => ( -

- {children} -

-); - -interface NotebookPrimaryNavigationProps { - onNewFundingOpportunity: () => void; - onNewProposal: () => void; - onNewChangelog: () => void; - onInvitePeople: () => void; -} - -/** - * Body of the notebook's primary navigation menu (the "My Notebook" dropdown on - * desktop / full-screen sheet on mobile). Surfaces document-creation entry - * points, the user's files, and workspace actions. - * - * Document-creation actions are delegated to the parent (`NotesMenu`) so it can - * close the menu before opening a modal or navigating — the modals live there - * because this component unmounts when the menu closes. - */ -export const NotebookPrimaryNavigation = ({ - onNewFundingOpportunity, - onNewProposal, - onNewChangelog, - onInvitePeople, -}: NotebookPrimaryNavigationProps) => { - const { selectedOrg } = useOrganizationContext(); - const { notes, isLoading: isLoadingNotes } = useNotebookContext(); - const { user } = useUser(); - - const isCurrentUserAdmin = selectedOrg?.userPermission?.accessType === 'ADMIN'; - const isModerator = !!user?.isModerator; - - const hasNotes = notes?.some( - (note) => note.access === 'WORKSPACE' || note.access === 'SHARED' || note.access === 'PRIVATE' - ); - const createActions: Record void }> = { - grant: { - icon: , - onClick: onNewFundingOpportunity, - }, - preregistration: { - icon: , - onClick: onNewProposal, - }, - discussion: { - icon: , - onClick: onNewChangelog, - }, - }; - const availableWorkTypes = getAvailableNotebookWorkTypes(isModerator); - - return ( -
- {/* Create */} - Create - {availableWorkTypes.map((workType) => { - const action = createActions[workType.value]; - return ( - - ); - })} - -
- - {/* Files */} - Files -
- {hasNotes || isLoadingNotes ? ( - - ) : ( -
No notes yet
- )} -
- -
- - {/* Workspace */} - Workspace - -
- ); -}; diff --git a/components/Notebook/NotebookTabs.tsx b/components/Notebook/NotebookTabs.tsx deleted file mode 100644 index 225fe9816..000000000 --- a/components/Notebook/NotebookTabs.tsx +++ /dev/null @@ -1,92 +0,0 @@ -'use client'; - -import { ArrowRight } from 'lucide-react'; -import { cn } from '@/utils/styles'; - -export type NotebookTab = 'document' | 'details'; - -interface NotebookTabsProps { - active: NotebookTab; - onChange: (tab: NotebookTab) => void; -} - -const STEPS: { id: NotebookTab; label: string; dataTour?: string }[] = [ - { id: 'document', label: 'Document' }, - { id: 'details', label: 'Details', dataTour: 'notebook-publish' }, -]; - -/** Linear two-step flow shown in the notebook top bar. It reads as a sequence - * (Document → Details) rather than parallel tabs, so the progression toward - * publishing is visually explicit. */ -export function NotebookTabs({ active, onChange }: NotebookTabsProps) { - const activeIndex = STEPS.findIndex((step) => step.id === active); - - return ( - - ); -} - -type StepState = 'current' | 'complete' | 'upcoming'; - -function Step({ - index, - label, - state, - onClick, - dataTour, -}: Readonly<{ - index: number; - label: string; - state: StepState; - onClick: () => void; - dataTour?: string; -}>) { - return ( - - ); -} diff --git a/components/Notebook/NotebookTour.tsx b/components/Notebook/NotebookTour.tsx deleted file mode 100644 index d86695689..000000000 --- a/components/Notebook/NotebookTour.tsx +++ /dev/null @@ -1,200 +0,0 @@ -'use client'; - -import { useEffect, useRef, useState } from 'react'; -import { createPortal } from 'react-dom'; -import { RadiatingDot } from '@/components/ui/RadiatingDot'; -import { cn } from '@/utils/styles'; - -type Placement = 'top' | 'bottom' | 'left' | 'right' | 'center'; - -interface TourStep { - selector: string; - title: string; - description: string; - placement: Placement; -} - -// Steps are matched to live DOM via `data-tour` anchors. If a target isn't -// present (e.g. the publishing sidebar before a note is opened), the step -// gracefully falls back to a centered popover with no spotlight. -const STEPS: TourStep[] = [ - { - selector: '[data-tour="notebook-editor"]', - title: 'Write in the main area', - description: - 'This is your document. Draft your document here. Everything autosaves as you type.', - placement: 'center', - }, - { - selector: '[data-tour="notebook-publish"]', - title: 'Add details & publish', - description: - 'Switch to the Details tab to set attributes of your document. Once it looks good, click the Publish button.', - placement: 'bottom', - }, -]; - -const SPOTLIGHT_PADDING = 8; -const POPOVER_WIDTH = 320; - -interface NotebookTourProps { - run: boolean; - onClose: () => void; -} - -export function NotebookTour({ run, onClose }: NotebookTourProps) { - const [stepIndex, setStepIndex] = useState(0); - const [rect, setRect] = useState(null); - const [popoverPos, setPopoverPos] = useState<{ top: number; left: number } | null>(null); - const popoverRef = useRef(null); - - const step = STEPS[stepIndex]; - - // Restart from the first step each time the tour is (re)opened. - useEffect(() => { - if (run) setStepIndex(0); - }, [run]); - - // Continuously track the target while the tour is open. The notebook layout - // animates (the right sidebar slides in via a grid-template-columns - // transition, content reflows on load), so a one-time measurement lands the - // highlight out of place. Measuring every frame keeps the ring glued to the - // target through any reflow; we only re-render when the rect actually moves. - useEffect(() => { - if (!run) return; - let raf = 0; - let prevKey = ''; - const tick = () => { - const el = document.querySelector(step.selector) as HTMLElement | null; - const r = el ? el.getBoundingClientRect() : null; - const key = r - ? `${Math.round(r.top)}:${Math.round(r.left)}:${Math.round(r.width)}:${Math.round(r.height)}` - : 'none'; - if (key !== prevKey) { - prevKey = key; - setRect(r); - } - raf = requestAnimationFrame(tick); - }; - raf = requestAnimationFrame(tick); - return () => cancelAnimationFrame(raf); - }, [run, step]); - - // Position the popover relative to the target (or centered as a fallback). - useEffect(() => { - if (!run) return; - const w = POPOVER_WIDTH; - const h = popoverRef.current?.offsetHeight ?? 190; - const vw = window.innerWidth; - const vh = window.innerHeight; - const margin = 16; - - let top: number; - let left: number; - - if (step.placement === 'center' && rect) { - // Center the popover over the highlighted target rather than the viewport. - top = rect.top + rect.height / 2 - h / 2; - left = rect.left + rect.width / 2 - w / 2; - } else if (!rect || step.placement === 'center') { - top = vh / 2 - h / 2; - left = vw / 2 - w / 2; - } else if (step.placement === 'bottom') { - top = rect.bottom + 12; - left = rect.left + rect.width / 2 - w / 2; - } else if (step.placement === 'top') { - top = rect.top - h - 12; - left = rect.left + rect.width / 2 - w / 2; - } else if (step.placement === 'left') { - left = rect.left - w - 12; - top = rect.top + rect.height / 2 - h / 2; - } else { - left = rect.right + 12; - top = rect.top + rect.height / 2 - h / 2; - } - - left = Math.min(Math.max(left, margin), vw - w - margin); - top = Math.min(Math.max(top, margin), vh - h - margin); - setPopoverPos({ top, left }); - }, [run, rect, step, stepIndex]); - - if (!run || typeof document === 'undefined') return null; - - const isLast = stepIndex === STEPS.length - 1; - const handleNext = () => (isLast ? onClose() : setStepIndex((i) => i + 1)); - const handleBack = () => setStepIndex((i) => Math.max(0, i - 1)); - - const spotlight = rect - ? { - top: rect.top - SPOTLIGHT_PADDING, - left: rect.left - SPOTLIGHT_PADDING, - width: rect.width + SPOTLIGHT_PADDING * 2, - height: rect.height + SPOTLIGHT_PADDING * 2, - } - : null; - - return createPortal( -
- {spotlight && ( -
- )} - -
-
-
- -

{step.title}

-
-

{step.description}

- -
- -
- {stepIndex > 0 && ( - - )} - -
-
-
-
-
, - document.body - ); -} diff --git a/components/Notebook/NotesMenu.tsx b/components/Notebook/NotesMenu.tsx deleted file mode 100644 index 2c338a465..000000000 --- a/components/Notebook/NotesMenu.tsx +++ /dev/null @@ -1,206 +0,0 @@ -'use client'; - -import { useEffect, useState } from 'react'; -import { createPortal } from 'react-dom'; -import { usePathname, useRouter } from 'next/navigation'; -import { ChevronDown, X } from 'lucide-react'; -import { NotebookPrimaryNavigation } from '@/components/Notebook/NotebookPrimaryNavigation'; -import { OrganizationSettingsModal } from '@/components/modals/OrganizationSettingsModal'; -import { - OpenFundingOpportunityModal, - type FundingOpportunityCreationMethod, -} from '@/components/Funding/OpenFundingOpportunityModal'; -import { - OpenProposalModal, - type ProposalCreationMethod, -} from '@/components/Funding/OpenProposalModal'; -import { useOrganizationContext } from '@/contexts/OrganizationContext'; -import Icon from '@/components/ui/icons/Icon'; -import { useScreenSize } from '@/hooks/useScreenSize'; -import { cn } from '@/utils/styles'; - -/** - * Compact replacement for the persistent notebook left sidebar. Lives in the - * editor top bar and reveals the note browser/creator in a dropdown so the - * horizontal space can go to the (more important) publishing sidebar. - * - * On mobile it expands to a full-screen sheet. That sheet is rendered through a - * portal because the top bar uses a CSS transform (for its show/hide - * animation), which would otherwise trap a `position: fixed` child inside the - * thin top-bar box instead of letting it cover the viewport. - */ -export function NotesMenu() { - const [isOpen, setIsOpen] = useState(false); - const [isMounted, setIsMounted] = useState(false); - // Bottom inset so the mobile sheet stops above the (fixed) bottom nav rather - // than covering it. The sheet intentionally covers the top bar. - const [bottomInset, setBottomInset] = useState(0); - // The creation modals live here (rather than inside NotebookPrimaryNavigation) - // so the menu can close as the modal opens without unmounting the modal. - const [isFundingOpportunityModalOpen, setIsFundingOpportunityModalOpen] = useState(false); - const [isProposalModalOpen, setIsProposalModalOpen] = useState(false); - const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false); - const pathname = usePathname(); - const router = useRouter(); - const { smAndDown } = useScreenSize(); - const { selectedOrg } = useOrganizationContext(); - - const isCurrentUserAdmin = selectedOrg?.userPermission?.accessType === 'ADMIN'; - - // Mirror PublishMenu: the modal picks a creation method, then we hand off to - // the notebook page which scaffolds the document from that method. - const handleConfirmOpenGrant = (method: FundingOpportunityCreationMethod) => { - setIsFundingOpportunityModalOpen(false); - router.push(`/notebook?newGrant=true&grantSource=${method}`); - }; - - const handleConfirmCreateProposal = (method: ProposalCreationMethod) => { - setIsProposalModalOpen(false); - router.push(`/notebook?newFunding=true&proposalSource=${method}`); - }; - - useEffect(() => { - setIsMounted(true); - }, []); - - // Close when navigating to/creating a note (NoteListItem pushes routes - // directly, so we key off the pathname instead of an explicit callback). - useEffect(() => { - setIsOpen(false); - }, [pathname]); - - useEffect(() => { - if (!isOpen) return; - const onKey = (e: KeyboardEvent) => { - if (e.key === 'Escape') setIsOpen(false); - }; - window.addEventListener('keydown', onKey); - return () => window.removeEventListener('keydown', onKey); - }, [isOpen]); - - const isMobile = smAndDown === true; - - // Each creation action closes the menu first, then opens its modal / navigates. - const handleNewFundingOpportunity = () => { - setIsOpen(false); - setIsFundingOpportunityModalOpen(true); - }; - - const handleNewProposal = () => { - setIsOpen(false); - setIsProposalModalOpen(true); - }; - - const handleNewChangelog = () => { - setIsOpen(false); - router.push('/notebook?newChangelog=true'); - }; - - const handleInvitePeople = () => { - setIsOpen(false); - setIsSettingsModalOpen(true); - }; - - const navigation = ( - - ); - - // Measure the bottom nav while the mobile sheet is open so it stops just - // above it (accounts for safe areas). - useEffect(() => { - if (!isOpen || !isMobile) return; - const measure = () => { - const bottomNav = document.querySelector('[data-mobile-bottom-nav]'); - setBottomInset(bottomNav?.getBoundingClientRect().height ?? 0); - }; - measure(); - window.addEventListener('resize', measure); - return () => window.removeEventListener('resize', measure); - }, [isOpen, isMobile]); - - return ( -
- - - {/* Desktop: anchored dropdown rendered inline next to the trigger. */} - {isOpen && !isMobile && ( - <> - {/* Click-catcher sits below the panel and any nested menus/modals. */} -
setIsOpen(false)} aria-hidden /> -
- {navigation} -
- - )} - - {/* Mobile: sheet portaled to so it escapes the top bar's - transformed stacking context. It covers the top bar (z above its - z-[60]) and stops just above the fixed bottom nav. */} - {isOpen && - isMobile && - isMounted && - createPortal( -
- {/* Header with a close control. */} -
-
- - My Notebook -
- -
- -
{navigation}
-
, - document.body - )} - - setIsFundingOpportunityModalOpen(false)} - onConfirm={handleConfirmOpenGrant} - minimal - /> - - setIsProposalModalOpen(false)} - onConfirm={handleConfirmCreateProposal} - minimal - /> - - {selectedOrg && isCurrentUserAdmin && ( - setIsSettingsModalOpen(false)} - /> - )} -
- ); -} diff --git a/components/Notebook/PublishingForm/PublishButton.tsx b/components/Notebook/PublishingForm/PublishButton.tsx deleted file mode 100644 index 07fd14e84..000000000 --- a/components/Notebook/PublishingForm/PublishButton.tsx +++ /dev/null @@ -1,53 +0,0 @@ -'use client'; - -import type { ComponentProps } from 'react'; -import { Button } from '@/components/ui/Button'; -import { cn } from '@/utils/styles'; -import { usePublishingCompletion } from './completion'; -import { usePublishingController, type PublishingController } from './PublishingFormProvider'; - -const publishLabel = ({ - readOnly, - isUpserting, - isLinkingNonprofit, - isRedirecting, - isPublished, -}: PublishingController): string => { - if (readOnly) return 'Published'; - if (isUpserting) return 'Publishing...'; - if (isLinkingNonprofit) return 'Linking nonprofit...'; - if (isRedirecting) return 'Redirecting...'; - return isPublished ? 'Update' : 'Publish'; -}; - -interface PublishButtonProps { - /** - * Stay disabled until every required detail is filled in. Without it the - * click validates and names what is missing, which suits a form the user - * is looking at; with it the button reads as the last step of a checklist. - */ - readonly requireComplete?: boolean; - readonly size?: ComponentProps['size']; - readonly className?: string; -} - -/** Starts the publish flow for the note the surrounding provider holds. */ -export function PublishButton({ requireComplete = false, size, className }: PublishButtonProps) { - const controller = usePublishingController(); - const { isComplete } = usePublishingCompletion(); - const blockedByChecklist = requireComplete && !isComplete && !controller.isPublished; - - return ( - - ); -} diff --git a/components/Notebook/PublishingForm/PublishingFormProvider.tsx b/components/Notebook/PublishingForm/PublishingFormProvider.tsx index 9f942f325..eb7dc64c9 100644 --- a/components/Notebook/PublishingForm/PublishingFormProvider.tsx +++ b/components/Notebook/PublishingForm/PublishingFormProvider.tsx @@ -33,7 +33,7 @@ import { type PublishAction, } from './usePublishAction'; -export interface PublishingController extends PublishAction { +interface PublishingController extends PublishAction { readonly note: NoteWithContent | null; readonly editor: Editor | null; /** The form can be read but not changed or published. */ diff --git a/components/Notebook/PublishingForm/components/AuthorsSection.tsx b/components/Notebook/PublishingForm/components/AuthorsSection.tsx deleted file mode 100644 index bedf15a85..000000000 --- a/components/Notebook/PublishingForm/components/AuthorsSection.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Users } from 'lucide-react'; -import { SectionHeader } from './SectionHeader'; -import { cn } from '@/utils/styles'; -import type { SectionProps } from './SectionProps'; -import { useFormContext } from 'react-hook-form'; -import { getFieldErrorMessage } from '@/utils/form'; -import { SearchableUserSelect } from '@/components/ui/form/SearchableUserSelect'; - -export function AuthorsSection({ className }: SectionProps) { - const { - watch, - setValue, - formState: { errors }, - } = useFormContext(); - - const authors = watch('authors') || []; - - return ( -
- Authors - setValue('authors', newAuthors, { shouldValidate: true })} - placeholder="Search for authors..." - helperText="Drag and drop authors to arrange them in the order they should appear." - error={getFieldErrorMessage(errors.authors, 'Invalid authors')} - /> -
- ); -} diff --git a/components/Notebook/PublishingForm/components/ContactsSection.tsx b/components/Notebook/PublishingForm/components/ContactsSection.tsx deleted file mode 100644 index f6ee4ccbc..000000000 --- a/components/Notebook/PublishingForm/components/ContactsSection.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Users } from 'lucide-react'; -import { SectionHeader } from './SectionHeader'; -import { cn } from '@/utils/styles'; -import type { SectionProps } from './SectionProps'; -import { useFormContext } from 'react-hook-form'; -import { getFieldErrorMessage } from '@/utils/form'; -import { SearchableUserSelect } from '@/components/ui/form/SearchableUserSelect'; -import { UserSuggestion } from '@/types/search'; - -const getContactId = (user: UserSuggestion) => user.id!.toString(); - -export function ContactsSection({ className }: SectionProps) { - const { - watch, - setValue, - formState: { errors }, - } = useFormContext(); - - const contacts = watch('contacts') || []; - - return ( -
- Contacts - setValue('contacts', newContacts, { shouldValidate: true })} - placeholder="Search for contacts..." - error={getFieldErrorMessage(errors.contacts, 'Invalid contacts')} - helperText="Add contacts who will be responsible for managing this RFP. These contacts will receive important updates about its progress." - getOptionValue={getContactId} - /> -
- ); -} diff --git a/components/Notebook/PublishingForm/components/EndDateSection.tsx b/components/Notebook/PublishingForm/components/EndDateSection.tsx index 7ebd151bb..faf9f4d36 100644 --- a/components/Notebook/PublishingForm/components/EndDateSection.tsx +++ b/components/Notebook/PublishingForm/components/EndDateSection.tsx @@ -1,44 +1,3 @@ -import { useFormContext } from 'react-hook-form'; -import { ChevronDown } from 'lucide-react'; - /** What a fundraise's duration means; shared with the workspace's publish dialog. */ export const FUNDRAISE_DURATION_HELP = 'Your proposal will stop accepting contributions after this period.'; - -const END_DATE_OPTIONS = [ - { value: '30', label: '30 days' }, - { value: '60', label: '60 days' }, - { value: '90', label: '90 days' }, -] as const; - -export function EndDateSection() { - const { watch, setValue } = useFormContext(); - const fundraiseEndDays = watch('fundraiseEndDays') ?? '90'; - - return ( -
-

- Fundraise Duration -

-
- - -
-

{FUNDRAISE_DURATION_HELP}

-
- ); -} diff --git a/components/Notebook/PublishingForm/components/FundingGoalField.tsx b/components/Notebook/PublishingForm/components/FundingGoalField.tsx deleted file mode 100644 index d89397aa0..000000000 --- a/components/Notebook/PublishingForm/components/FundingGoalField.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { useFormContext } from 'react-hook-form'; -import { Input } from '@/components/ui/form/Input'; -import type { PublishingFormData } from '../schema'; - -/** The total a proposal asks funders for, in whole US dollars. */ -export function FundingGoalField() { - const { - register, - setValue, - formState: { errors }, - } = useFormContext(); - - return ( - USD
- } - helperText="Set your total funding goal for this research project" - onChange={(e) => { - const numericValue = e.target.value.replaceAll(/\D/g, ''); - setValue('budget', numericValue, { shouldValidate: true }); - - if (numericValue) { - e.target.value = new Intl.NumberFormat('en-US').format(Number.parseInt(numericValue)); - } else { - e.target.value = ''; - } - }} - /> - ); -} diff --git a/components/Notebook/PublishingForm/components/FundingOpportunityField.tsx b/components/Notebook/PublishingForm/components/FundingOpportunityField.tsx deleted file mode 100644 index c7844115e..000000000 --- a/components/Notebook/PublishingForm/components/FundingOpportunityField.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { useState } from 'react'; -import Image from 'next/image'; -import { Plus, X } from 'lucide-react'; -import { useFormContext } from 'react-hook-form'; -import { SelectFundingOpportunityModal } from '@/components/modals/SelectFundingOpportunityModal'; -import { GRANT_IMAGE_FALLBACK_GRADIENT } from '@/types/grant'; -import { formatCompactAmount } from '@/utils/currency'; -import type { PublishingFormData } from '../schema'; -import { useSelectedGrant } from '../useSelectedGrant'; - -interface FundingOpportunityFieldProps { - readonly noteId: number; -} - -/** - * The Request for Proposal this proposal answers: the chosen one as a card, - * or a prompt to pick one. Renders nothing once the proposal is published, - * because the answer cannot change after that. - */ -export function FundingOpportunityField({ noteId }: FundingOpportunityFieldProps) { - const { watch } = useFormContext(); - const workId = watch('workId'); - const { selectedGrant, isSaving, save } = useSelectedGrant(noteId); - const [isModalOpen, setIsModalOpen] = useState(false); - - if (workId) return null; - - return ( - <> -
-

- Request for Proposal (Optional) -

- {selectedGrant ? ( -
-
- {selectedGrant.imageUrl ? ( - {selectedGrant.shortTitle} - ) : ( -
- )} -
-
-
- {selectedGrant.organization || 'RFP'} -
-
- {selectedGrant.shortTitle} -
-
- {formatCompactAmount(selectedGrant.fundingAmount)} Funding -
-
- -
- ) : ( - - )} -
- - setIsModalOpen(false)} - onSelect={(grant) => void save(grant)} - /> - - ); -} diff --git a/components/Notebook/PublishingForm/components/FundingSection.tsx b/components/Notebook/PublishingForm/components/FundingSection.tsx deleted file mode 100644 index 2e6a538d9..000000000 --- a/components/Notebook/PublishingForm/components/FundingSection.tsx +++ /dev/null @@ -1,243 +0,0 @@ -import { useFormContext } from 'react-hook-form'; -import { Upload, Image as ImageIcon, Gift } from 'lucide-react'; -import { Button } from '@/components/ui/Button'; -import { Input } from '@/components/ui/form/Input'; -import { Switch } from '@/components/ui/Switch'; -import Image from 'next/image'; -import { cn } from '@/utils/styles'; -import { useRef, useState, useEffect } from 'react'; -import type { Note } from '@/types/note'; -import { NonprofitSearchSection } from '@/components/Nonprofit'; -import { useNonprofitByFundraiseId } from '@/hooks/useNonprofitByFundraiseId'; -import { useNonprofitSearch } from '@/hooks/useNonprofitSearch'; -import { FundingGoalField } from './FundingGoalField'; -import { FundingOpportunityField } from './FundingOpportunityField'; - -interface FundingSectionProps { - note: Note; -} - -const FEATURE_FLAG_NFT_REWARDS = false; - -export function FundingSection({ note }: Readonly) { - const { register, watch, setValue } = useFormContext(); - const rewardFunders = watch('rewardFunders'); - const budget = watch('budget'); - const nftSupply = watch('nftSupply'); - const fileInputRef = useRef(null); - const [previewUrl, setPreviewUrl] = useState(null); - const [isEditingNonprofit, setIsEditingNonprofit] = useState(false); - - const fundraise = note.post?.fundraise; - const { - nonprofit, - departmentLabName: existingNote, - isLoading: isLoadingNonprofit, - } = useNonprofitByFundraiseId(fundraise?.id); - const { results: nonprofitSearchResults, searchNonprofits } = useNonprofitSearch(); - - // If we have a fundraise and a nonprofit with EIN, search for complete data - useEffect(() => { - if (nonprofit?.ein && !isEditingNonprofit) { - searchNonprofits(nonprofit.ein); - } - }, [nonprofit, searchNonprofits, isEditingNonprofit]); - - // When we have both the nonprofit from the fundraise and search results, merge the data - // and set it in the form - useEffect(() => { - if ( - nonprofit && - nonprofitSearchResults && - nonprofitSearchResults.length > 0 && - !isEditingNonprofit - ) { - const matchedNonprofit = nonprofitSearchResults.find( - (result) => result.ein === nonprofit.ein - ); - - if (matchedNonprofit) { - const mergedNonprofit = { - ...matchedNonprofit, - id: nonprofit.id, - endaomentOrgId: nonprofit.endaomentOrgId || matchedNonprofit.endaomentOrgId, - baseWalletAddress: nonprofit.baseWalletAddress || matchedNonprofit.baseWalletAddress, - }; - - setValue('selectedNonprofit', mergedNonprofit); - setValue('departmentLabName', existingNote); - } else { - setValue('selectedNonprofit', nonprofit); - setValue('departmentLabName', existingNote); - } - } else if (nonprofit && !isEditingNonprofit) { - setValue('selectedNonprofit', nonprofit); - setValue('departmentLabName', existingNote); - } - }, [nonprofit, nonprofitSearchResults, existingNote, setValue, isEditingNonprofit]); - - const handleFileChange = (e: React.ChangeEvent) => { - const file = e.target.files?.[0]; - if (file) { - setValue('nftArt', file); - const url = URL.createObjectURL(file); - setPreviewUrl(url); - } - }; - - const formatNumberWithCommas = (value: string) => { - const numericValue = value.replaceAll(/\D/g, ''); - return numericValue ? Number.parseInt(numericValue).toLocaleString() : ''; - }; - - const calculateMinDonation = () => { - const funding = Number.parseFloat(budget?.replaceAll(/[^0-9.]/g, '') || '0'); - const supply = Number.parseInt(nftSupply?.replaceAll(/\D/g, '') || '0'); - if (!funding || !supply) return '0.00'; - return (funding / supply).toFixed(2); - }; - - return ( -
- - - {fundraise ? ( - <> -
- {isLoadingNonprofit && ( -

Loading nonprofit information...

- )} - {!isLoadingNonprofit && (isEditingNonprofit || !nonprofit) && ( - - )} - {!isLoadingNonprofit && !isEditingNonprofit && nonprofit && ( - setIsEditingNonprofit(true)} - /> - )} -
- - ) : ( - <> - - -
- -
- - )} - - {FEATURE_FLAG_NFT_REWARDS && ( - <> -
-
-
- -

- Reward Funders -

-
- setValue('rewardFunders', checked)} - /> -
-

- Reward your funders with a memento of your research as an NFT. -

-
- {rewardFunders && ( - <> - NFT Art Upload Section -
- NFT Art - - -
- NFT Supply Section -
- { - const formatted = formatNumberWithCommas(e.target.value); - setValue('nftSupply', formatted, { shouldValidate: true }); - }} - /> -
- Donation Rewards Section -
-
- - Donation Rewards -
-
- 0 - ? `$${calculateMinDonation()} per NFT` - : '-' - } - className="w-full pl-3 pr-12 py-2 text-sm text-gray-900 bg-transparent border-0 cursor-default focus:outline-none focus:ring-0" - /> -
-

- {Number.parseFloat(calculateMinDonation()) > 0 - ? `Funders must donate at least $${calculateMinDonation()} USD to receive one research memento NFT` - : 'Set a funding goal and NFT supply to calculate the minimum donation per NFT'} -

-
- - )} - - )} -
- ); -} diff --git a/components/Notebook/PublishingForm/components/GrantApplicationVisibilitySection.tsx b/components/Notebook/PublishingForm/components/GrantApplicationVisibilitySection.tsx index 215364a9d..ab7be66b3 100644 --- a/components/Notebook/PublishingForm/components/GrantApplicationVisibilitySection.tsx +++ b/components/Notebook/PublishingForm/components/GrantApplicationVisibilitySection.tsx @@ -1,7 +1,3 @@ -import { useFormContext } from 'react-hook-form'; -import { Eye } from 'lucide-react'; -import { RadioGroup } from '@/components/ui/form/RadioGroup'; -import { SectionHeader } from './SectionHeader'; import { CommunityMatchTooltip } from '@/components/tooltips/CommunityMatchTooltip'; const CommunityMatchBadge = () => ( @@ -34,23 +30,3 @@ export const GRANT_APPLICATION_VISIBILITY_OPTIONS = [ description: 'Only yourself and peer-reviewers can view private proposals.', }, ]; - -export function GrantApplicationVisibilitySection() { - const { watch, setValue } = useFormContext(); - const value = watch('applicationVisibility') ?? 'OPTIONAL'; - - return ( -
- Application Visibility -

{GRANT_APPLICATION_VISIBILITY_HELP}

-
- setValue('applicationVisibility', next, { shouldValidate: true })} - size="sm" - /> -
-
- ); -} diff --git a/components/Notebook/PublishingForm/components/GrantDescriptionSection.tsx b/components/Notebook/PublishingForm/components/GrantDescriptionSection.tsx deleted file mode 100644 index 6f8a5ad21..000000000 --- a/components/Notebook/PublishingForm/components/GrantDescriptionSection.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { useFormContext } from 'react-hook-form'; -import { FileText } from 'lucide-react'; -import { Textarea } from '@/components/ui/form/Textarea'; -import { SectionHeader } from './SectionHeader'; -import { cn } from '@/utils/styles'; -import type { SectionProps } from './SectionProps'; - -export function GrantDescriptionSection({ className }: SectionProps) { - const { - register, - formState: { errors }, - } = useFormContext(); - - return ( -
- Short Description -
-