From b440901843a930c6c87ec23c59f90f1349c25b50 Mon Sep 17 00:00:00 2001 From: IEatChili Date: Thu, 6 Jun 2024 15:23:12 -0400 Subject: feat: updated ui --- package-lock.json | 2 +- package.json | 2 +- src/client/documents/DocumentTypes.ts | 1 + src/client/documents/Documents.ts | 4 + src/client/util/CurrentUserUtils.ts | 7 + src/client/views/Main.tsx | 2 + src/client/views/MainView.tsx | 1 + .../collectionFreeForm/ImageLabelBox.scss | 26 ++++ .../collectionFreeForm/ImageLabelBox.tsx | 150 +++++++++++++++++++++ .../collectionFreeForm/ImageLabelHandler.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 56 +++++--- src/client/views/linking/LinkPopup.tsx | 1 - src/fields/Doc.ts | 1 + 13 files changed, 232 insertions(+), 23 deletions(-) create mode 100644 src/client/views/collections/collectionFreeForm/ImageLabelBox.scss create mode 100644 src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx diff --git a/package-lock.json b/package-lock.json index b143dc5c1..9b3904ff7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -142,7 +142,7 @@ "mathquill": "^0.10.1-a", "md5-file": "^5.0.0", "memorystream": "^0.3.1", - "mermaid": "^10.9.0", + "mermaid": "^10.9.1", "mobile-detect": "^1.4.5", "mobx": "^6.12.0", "mobx-react": "^9.1.0", diff --git a/package.json b/package.json index 52f627b63..ed05c4f45 100644 --- a/package.json +++ b/package.json @@ -227,7 +227,7 @@ "mathquill": "^0.10.1-a", "md5-file": "^5.0.0", "memorystream": "^0.3.1", - "mermaid": "^10.9.0", + "mermaid": "^10.9.1", "mobile-detect": "^1.4.5", "mobx": "^6.12.0", "mobx-react": "^9.1.0", diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 8f95068db..a9ea889b3 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -16,6 +16,7 @@ export enum DocumentType { SCREENSHOT = 'screenshot', FONTICON = 'fonticonbox', SEARCH = 'search', // search query + IMAGEGROUPER = 'imagegrouper', LABEL = 'label', // simple text label BUTTON = 'button', // onClick button WEBCAM = 'webcam', // webcam diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a67e6b4f6..449347403 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -784,6 +784,10 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.SEARCH), new List([]), options); } + export function ImageGrouperDocument(options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.IMAGEGROUPER), undefined, options); + } + export function LoadingDocument(file: File | string, options: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.LOADING), undefined, { _height: 150, _width: 200, title: typeof file === 'string' ? file : file.name, ...options }, undefined, ''); } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index e095bc659..486b6815a 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -458,6 +458,7 @@ pie title Minerals in my tap water { title: "Shared", toolTip: "Shared Docs", target: Doc.MySharedDocs, ignoreClick: true, icon: "users", funcs: {badgeValue: badgeValue}}, { title: "Trails", toolTip: "Trails ⌘R", target: Doc.UserDoc(), ignoreClick: true, icon: "pres-trail", funcs: {target: getActiveDashTrails}}, { title: "User Doc", toolTip: "User Doc", target: this.setupUserDocView(doc, "myUserDocView"), ignoreClick: true, icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, + { title: "Image Grouper", toolTip: "Image Grouper", target: this.setupImageGrouper(doc, "myImageGrouper"), ignoreClick: true, icon: "folder-open", hidden: true } ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(this)'}})); } @@ -493,6 +494,12 @@ pie title Minerals in my tap water _lockedPosition: true, _type_collection: CollectionViewType.Schema }); } + static setupImageGrouper(doc: Doc, field: string) { + return DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.ImageGrouperDocument(opts), { + dontRegisterView: true, backgroundColor: "dimgray", ignoreClick: true, title: "Image Grouper", isSystem: true, childDragAction: dropActionType.embed, + _lockedPosition: true, _type_collection: CollectionViewType.Schema }); + } + /// Initializes the panel of draggable tools that is opened from the left sidebar. static setupToolsBtnPanel(doc: Doc, field:string) { const allTools = DocListCast(DocCast(doc[field])?.data); diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 43b9a6b39..8242e7c27 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -60,6 +60,7 @@ import { SummaryView } from './nodes/formattedText/SummaryView'; import { ImportElementBox } from './nodes/importBox/ImportElementBox'; import { PresBox, PresElementBox } from './nodes/trails'; import { SearchBox } from './search/SearchBox'; +import { ImageLabelBox } from './collections/collectionFreeForm/ImageLabelBox'; dotenv.config(); @@ -131,6 +132,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; PresBox, PresElementBox, SearchBox, + ImageLabelBox, //Here! FunctionPlotBox, InkingStroke, LinkBox, diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 31d88fb87..5b4c2b5ba 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -76,6 +76,7 @@ import { PresBox } from './nodes/trails'; import { AnchorMenu } from './pdf/AnchorMenu'; import { GPTPopup } from './pdf/GPTPopup/GPTPopup'; import { TopBar } from './topbar/TopBar'; +import { ImageLabelBox } from './collections/collectionFreeForm/ImageLabelBox'; const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore const _global = (window /* browser */ || global) /* node */ as any; diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss new file mode 100644 index 000000000..d0c12814c --- /dev/null +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss @@ -0,0 +1,26 @@ +.image-label-list { + display: flex; + flex-direction: column; + align-items: center; // Centers the content vertically in the flex container + width: 100%; + + > div { + display: flex; + justify-content: space-between; // Puts the content and delete button on opposite ends + align-items: center; + width: 100%; + margin-top: 8px; // Adds space between label rows + background-color: black; + + p { + text-align: center; // Centers the text of the paragraph + font-size: large; + vertical-align: middle; + } + + .IconButton { + // Styling for the delete button + margin-left: auto; // Pushes the button to the far right + } + } +} diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx new file mode 100644 index 000000000..1c0035f0d --- /dev/null +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -0,0 +1,150 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Colors, IconButton } from 'browndash-components'; +import { action, makeObservable, observable } from 'mobx'; +import { observer } from 'mobx-react'; +import React from 'react'; +import { Doc } from '../../../../fields/Doc'; +import { Docs } from '../../../documents/Documents'; +import { DocumentType } from '../../../documents/DocumentTypes'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { FieldView, FieldViewProps } from '../../nodes/FieldView'; +import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; +import './ImageLabelBox.scss'; +import { MainView } from '../../MainView'; +import { MarqueeView } from './MarqueeView'; + +@observer +export class ImageLabelBox extends ViewBoxBaseComponent() { + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(ImageLabelBox, fieldKey); + } + + public static Instance: ImageLabelBox | null = null; + private _inputRef = React.createRef(); + @observable _loading: boolean = true; + @observable _currentLabel: string = ''; + @observable _labelGroups: string[] = []; + + constructor(props: any) { + super(props); + makeObservable(this); + ImageLabelBox.Instance = this; + + console.log('Image Box Has Been Initialized'); + } + + /** + * This method is called when the SearchBox component is first mounted. When the user opens + * the search panel, the search input box is automatically selected. This allows the user to + * type in the search input box immediately, without needing clicking on it first. + */ + componentDidMount() { + // if (this._inputRef.current) { + // this._inputRef.current.focus(); + // } + } + + @action + addLabel = (label: string) => { + label = label.toUpperCase().trim(); + if (label.length > 0) { + if (!this._labelGroups.includes(label)) { + this._labelGroups = [...this._labelGroups, label]; + } + } + }; + + @action + removeLabel = (label: string) => { + const labelUp = label.toUpperCase(); + this._labelGroups = this._labelGroups.filter(group => group !== labelUp); + }; + + @action + groupImages = () => { + MarqueeOptionsMenu.Instance.groupImages(); + this._labelGroups = []; + MainView.Instance.closeFlyout(); + }; + + @action + startLoading = () => { + this._loading = true; + }; + + @action + endLoading = () => { + this._loading = false; + }; + + render() { + if (this._loading) { + return
Loading...
; + } + + return ( +
+
+ { + // e.key === 'Enter' ? this.submitSearch() : null; + // e.stopPropagation(); + // }} + type="text" + placeholder="Input a group to put images into..." + aria-label="label-input" + id="new-label" + className="searchBox-input" + style={{ width: '100%', borderRadius: '5px' }} + ref={this._inputRef} + /> + { + const input = document.getElementById('new-label') as HTMLInputElement; + const newLabel = input.value; + this.addLabel(newLabel); + this._currentLabel = ''; + input.value = ''; + }} + icon={} + color={MarqueeOptionsMenu.Instance.userColor} + style={{ width: '19px' }} + /> + {this._labelGroups.length > 0 ? ( + } color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} /> + ) : ( +
+ )} +
+
+
+ {this._labelGroups.map(group => { + return ( +
+

{group}

+ { + this.removeLabel(group); + }} + icon={'x'} + color={MarqueeOptionsMenu.Instance.userColor} + style={{ width: '8px' }} + /> +
+ ); + })} +
+
+
+ ); + } +} + +Docs.Prototypes.TemplateMap.set(DocumentType.IMAGEGROUPER, { + layout: { view: ImageLabelBox, dataField: 'data' }, + options: { acl: '', _width: 400 }, +}); diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelHandler.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelHandler.tsx index 7f27c6b5c..73befb205 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelHandler.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelHandler.tsx @@ -77,7 +77,7 @@ export class ImageLabelHandler extends ObservableReactComponent<{}> { }}>
} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} /> - + { diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index dc15c83c5..bb5a2a66e 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -5,7 +5,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { ClientUtils, lightOrDark, returnFalse } from '../../../../ClientUtils'; import { intersectRect, numberRange } from '../../../../Utils'; -import { Doc, NumListCast, Opt } from '../../../../fields/Doc'; +import { Doc, DocListCast, NumListCast, Opt } from '../../../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { InkData, InkField, InkTool } from '../../../../fields/InkField'; @@ -36,6 +36,9 @@ import { CollectionFreeFormView } from './CollectionFreeFormView'; import { ImageLabelHandler } from './ImageLabelHandler'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './MarqueeView.scss'; +import { MainView } from '../../MainView'; +import { ImageLabelBox } from './ImageLabelBox'; +import { SearchBox } from '../../search/SearchBox'; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -53,6 +56,9 @@ interface MarqueeViewProps { slowLoadDocuments: (files: File[] | string, options: DocumentOptions, generatedDocuments: Doc[], text: string, completed: ((doc: Doc[]) => void) | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => Promise; } +/** + * A component that deals with the marquee select in the freeform canvas. + */ @observer export class MarqueeView extends ObservableReactComponent { public static CurViewBounds(pinDoc: Doc, panelWidth: number, panelHeight: number) { @@ -60,9 +66,12 @@ export class MarqueeView extends ObservableReactComponent { - this._selectedDocs = this.marqueeSelect(false, DocumentType.IMG); + if (e) { + const groupButton = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyImageGrouper); + if (groupButton) { + MainView.Instance.expandFlyout(groupButton); + while (!ImageLabelBox.Instance) { + await new Promise(resolve => setTimeout(resolve, 1000)).then(() => { + console.log('Waiting for Image Label Box'); + }); + } + ImageLabelBox.Instance.startLoading(); + } + } + + this._selectedDocs = this.marqueeSelect(false, DocumentType.IMG); // Get the selected documents from the marquee select. const imageInfos = this._selectedDocs.map(async doc => { - const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); - return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => + if (!doc[DocData].data_labels) { + const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); + return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => !hrefBase64 ? undefined : gptImageLabel(hrefBase64).then(labels => Promise.all(labels.split('\n').map(label => gptGetEmbedding(label))).then(embeddings => ({ doc, embeddings, labels }))) ); // prettier-ignore - }); + } + }); // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. (await Promise.all(imageInfos)).forEach(imageInfo => { - if (imageInfo && Array.isArray(imageInfo.embeddings)) { + if (imageInfo && imageInfo.embeddings && Array.isArray(imageInfo.embeddings)) { imageInfo.doc[DocData].data_labels = imageInfo.labels; numberRange(3).forEach(n => { imageInfo.doc[`data_labels_embedding_${n + 1}`] = new List(imageInfo.embeddings[n]); }); } - }); + }); // Add the labels as fields to each image. - if (e) { - ImageLabelHandler.Instance.displayLabelHandler(e.pageX, e.pageY); - } + ImageLabelBox.Instance!.endLoading(); + console.log('Complete!'); }); /** @@ -464,7 +486,7 @@ export class MarqueeView extends ObservableReactComponent { - const labelGroups = ImageLabelHandler.Instance._labelGroups; + const labelGroups = ImageLabelBox.Instance!._labelGroups; const labelToEmbedding = new Map(); // Create embeddings for the labels. await Promise.all(labelGroups.map(async label => gptGetEmbedding(label).then(labelEmbedding => labelToEmbedding.set(label, labelEmbedding)))); @@ -478,14 +500,10 @@ export class MarqueeView extends ObservableReactComponent ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) .reduce((prev, cur) => cur.similarityScore < 0.3 || cur.similarityScore <= prev.similarityScore ? prev: cur, { label: '', similarityScore: 0, }); // prettier-ignore - - numberRange(3).forEach(n => { - doc[`data_labels_embedding_${n + 1}`] = undefined; - }); - doc[DocData].data_label = mostSimilarLabelCollect; + doc[DocData].data_label = mostSimilarLabelCollect; // The label most similar to the image's contents. }); - this._props.Document._type_collection = CollectionViewType.Time; - this._props.Document.pivotField = 'data_label'; + this._props.Document._type_collection = CollectionViewType.Time; // Change the collection view to a Time view. + this._props.Document.pivotField = 'data_label'; // Sets the pivot to be the 'data_label'. }); @undoBatch diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx index 76a8396ff..2405e375d 100644 --- a/src/client/views/linking/LinkPopup.tsx +++ b/src/client/views/linking/LinkPopup.tsx @@ -45,7 +45,6 @@ export class LinkPopup extends React.Component { {/* */} - Date: Mon, 10 Jun 2024 11:06:02 -0400 Subject: feat: ui changes --- package-lock.json | 6 +++ package.json | 1 + .../collectionFreeForm/ImageLabelBox.scss | 23 +++++++++ .../collectionFreeForm/ImageLabelBox.tsx | 60 ++++++++++++++++++---- .../collectionFreeForm/MarqueeOptionsMenu.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 9 ++-- 6 files changed, 86 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9b3904ff7..6cd2ab605 100644 --- a/package-lock.json +++ b/package-lock.json @@ -136,6 +136,7 @@ "js-datepicker": "^5.18.2", "jsonschema": "^1.4.1", "jszip": "^3.10.1", + "ldrs": "^1.0.2", "lodash": "^4.17.21", "mapbox-gl": "^3.0.1", "markdown-it": "^14.1.0", @@ -23613,6 +23614,11 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/ldrs": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ldrs/-/ldrs-1.0.2.tgz", + "integrity": "sha512-sYJmivdkIiHrUEqTrEWccBoLdaENpzbzkABI5rk8rRxTXrg9i2xVuDvUUuhOhJY3RmQyaoxs046pM1DCRdcIpg==" + }, "node_modules/leac": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", diff --git a/package.json b/package.json index ed05c4f45..bbd2a4c46 100644 --- a/package.json +++ b/package.json @@ -221,6 +221,7 @@ "js-datepicker": "^5.18.2", "jsonschema": "^1.4.1", "jszip": "^3.10.1", + "ldrs": "^1.0.2", "lodash": "^4.17.21", "mapbox-gl": "^3.0.1", "markdown-it": "^14.1.0", diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss index d0c12814c..5f2ce4e14 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss @@ -1,3 +1,18 @@ +.image-box-container { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + font-size: 10px; + line-height: 1; + background: none; + z-index: 1000; + padding: 0px; + overflow: auto; + cursor: default; +} + .image-label-list { display: flex; flex-direction: column; @@ -16,6 +31,7 @@ text-align: center; // Centers the text of the paragraph font-size: large; vertical-align: middle; + margin-left: 10px; } .IconButton { @@ -24,3 +40,10 @@ } } } + +.image-information { + display: flex; + flex-direction: column; + //align-items: center; + width: 100%; +} diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index 1c0035f0d..83ae69cfb 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -12,6 +12,11 @@ import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './ImageLabelBox.scss'; import { MainView } from '../../MainView'; import { MarqueeView } from './MarqueeView'; +import 'ldrs/ring'; +import { ring } from 'ldrs'; +import { SnappingManager } from '../../../util/SnappingManager'; +import { ImageCast } from '../../../../fields/Types'; +import { DocData } from '../../../../fields/DocSymbols'; @observer export class ImageLabelBox extends ViewBoxBaseComponent() { @@ -24,12 +29,14 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { @observable _loading: boolean = true; @observable _currentLabel: string = ''; @observable _labelGroups: string[] = []; + @observable _selectedImages: Doc[] = []; + @observable _displayImageInformation: boolean = false; constructor(props: any) { super(props); makeObservable(this); ImageLabelBox.Instance = this; - + ring.register(); console.log('Image Box Has Been Initialized'); } @@ -77,14 +84,32 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { this._loading = false; }; + @action + setSelectedImages = (selected: Doc[]) => { + this._selectedImages = selected; + }; + render() { if (this._loading) { - return
Loading...
; + return ( +
+ +
+ ); } return ( -
-
+
+
+ { + this._displayImageInformation = !this._displayImageInformation; + }} + icon={this._displayImageInformation ? : } + color={MarqueeOptionsMenu.Instance.userColor} + style={{ width: '19px' }} + /> () { // e.stopPropagation(); // }} type="text" - placeholder="Input a group to put images into..." + placeholder="Input labels for image groupings..." aria-label="label-input" id="new-label" className="searchBox-input" @@ -101,7 +126,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { ref={this._inputRef} /> { const input = document.getElementById('new-label') as HTMLInputElement; const newLabel = input.value; @@ -113,11 +138,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} /> - {this._labelGroups.length > 0 ? ( - } color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} /> - ) : ( -
- )} + {this._labelGroups.length > 0 ? } color={Colors.MEDIUM_BLUE} style={{ width: '19px' }} /> :
}
@@ -139,6 +160,23 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { })}
+ {this._displayImageInformation ? ( +
+ {this._selectedImages.map(doc => { + const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); + return ( +
+ + {(doc[DocData].data_labels as string).split('\n').map(label => { + return
{label}
; + })} +
+ ); + })} +
+ ) : ( +
+ )}
); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index f02cd9d45..b94a22d04 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -39,7 +39,7 @@ export class MarqueeOptionsMenu extends AntimodeMenu { } color={this.userColor} /> } color={this.userColor} /> } color={this.userColor} /> - } color={this.userColor} /> + } color={this.userColor} /> ); return this.getElement(buttons); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index bb5a2a66e..f98883bff 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -456,6 +456,7 @@ export class MarqueeView extends ObservableReactComponent { if (!doc[DocData].data_labels) { @@ -478,7 +479,7 @@ export class MarqueeView extends ObservableReactComponent Date: Wed, 12 Jun 2024 12:32:19 -0400 Subject: feat: updated and fixed ui --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/MainView.tsx | 2 +- .../collectionFreeForm/ImageLabelBox.scss | 40 +++++- .../collectionFreeForm/ImageLabelBox.tsx | 159 +++++++++++++++------ .../collections/collectionFreeForm/MarqueeView.tsx | 46 +----- 5 files changed, 164 insertions(+), 85 deletions(-) diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 486b6815a..cb3d9df62 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -458,7 +458,7 @@ pie title Minerals in my tap water { title: "Shared", toolTip: "Shared Docs", target: Doc.MySharedDocs, ignoreClick: true, icon: "users", funcs: {badgeValue: badgeValue}}, { title: "Trails", toolTip: "Trails ⌘R", target: Doc.UserDoc(), ignoreClick: true, icon: "pres-trail", funcs: {target: getActiveDashTrails}}, { title: "User Doc", toolTip: "User Doc", target: this.setupUserDocView(doc, "myUserDocView"), ignoreClick: true, icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, - { title: "Image Grouper", toolTip: "Image Grouper", target: this.setupImageGrouper(doc, "myImageGrouper"), ignoreClick: true, icon: "folder-open", hidden: true } + { title: "Image Grouper", toolTip: "Image Grouper", target: this.setupImageGrouper(doc, "myImageGrouper"), ignoreClick: true, icon: "folder-open", hidden: false } ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(this)'}})); } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 5b4c2b5ba..716edc22d 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -76,7 +76,7 @@ import { PresBox } from './nodes/trails'; import { AnchorMenu } from './pdf/AnchorMenu'; import { GPTPopup } from './pdf/GPTPopup/GPTPopup'; import { TopBar } from './topbar/TopBar'; -import { ImageLabelBox } from './collections/collectionFreeForm/ImageLabelBox'; +import { ImageLabelBox, ImageLabelBoxData } from './collections/collectionFreeForm/ImageLabelBox'; const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore const _global = (window /* browser */ || global) /* node */ as any; diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss index 5f2ce4e14..819c72760 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss @@ -41,9 +41,45 @@ } } -.image-information { +.image-information-list { display: flex; flex-direction: column; - //align-items: center; + align-items: center; + width: 100%; + margin-top: 10px; +} + +.image-information { + border: 1px solid; width: 100%; + display: inline-flex; + flex-direction: column; + justify-content: center; + align-items: center; + overflow: hidden; + padding: 2px; + overflow-x: auto; + overflow-y: auto; + + img { + max-width: 200px; + max-height: 200px; + width: auto; + height: auto; + } +} + +.image-information-labels { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .image-label { + margin-top: 5px; + margin-bottom: 5px; + padding: 3px; + border-radius: 2px; + border: solid 1px; + } } diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index 83ae69cfb..f5530ccc4 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Colors, IconButton } from 'browndash-components'; -import { action, makeObservable, observable } from 'mobx'; +import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; import { Doc } from '../../../../fields/Doc'; @@ -11,12 +11,51 @@ import { FieldView, FieldViewProps } from '../../nodes/FieldView'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './ImageLabelBox.scss'; import { MainView } from '../../MainView'; -import { MarqueeView } from './MarqueeView'; import 'ldrs/ring'; import { ring } from 'ldrs'; import { SnappingManager } from '../../../util/SnappingManager'; import { ImageCast } from '../../../../fields/Types'; import { DocData } from '../../../../fields/DocSymbols'; +import { SettingsManager } from '../../../util/SettingsManager'; +import { CollectionCardView } from '../CollectionCardDeckView'; +import { gptGetEmbedding, gptImageLabel } from '../../../apis/gpt/GPT'; +import { numberRange, Utils } from '../../../../Utils'; +import { List } from '../../../../fields/List'; + +export class ImageLabelBoxData { + static _instance: ImageLabelBoxData; + @observable _docs: Doc[] = []; + @observable _labelGroups: string[] = []; + + constructor() { + makeObservable(this); + ImageLabelBoxData._instance = this; + } + public static get Instance() { + return ImageLabelBoxData._instance ?? new ImageLabelBoxData(); + } + + @action + public setData = (docs: Doc[]) => { + this._docs = docs; + }; + + @action + addLabel = (label: string) => { + label = label.toUpperCase().trim(); + if (label.length > 0) { + if (!this._labelGroups.includes(label)) { + this._labelGroups = [...this._labelGroups, label]; + } + } + }; + + @action + removeLabel = (label: string) => { + const labelUp = label.toUpperCase(); + this._labelGroups = this._labelGroups.filter(group => group !== labelUp); + }; +} @observer export class ImageLabelBox extends ViewBoxBaseComponent() { @@ -24,59 +63,53 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { return FieldView.LayoutString(ImageLabelBox, fieldKey); } - public static Instance: ImageLabelBox | null = null; + public static Instance: ImageLabelBox; private _inputRef = React.createRef(); - @observable _loading: boolean = true; - @observable _currentLabel: string = ''; - @observable _labelGroups: string[] = []; - @observable _selectedImages: Doc[] = []; + @observable _loading: boolean = false; + private _currentLabel: string = ''; + + @computed get _labelGroups() { + return ImageLabelBoxData.Instance._labelGroups; + } + + @computed get _selectedImages() { + // return DocListCast(this.dataDoc.data); + return ImageLabelBoxData.Instance._docs; + } @observable _displayImageInformation: boolean = false; constructor(props: any) { super(props); makeObservable(this); - ImageLabelBox.Instance = this; ring.register(); + ImageLabelBox.Instance = this; console.log('Image Box Has Been Initialized'); } + // ImageLabelBox.Instance.setData() /** * This method is called when the SearchBox component is first mounted. When the user opens * the search panel, the search input box is automatically selected. This allows the user to * type in the search input box immediately, without needing clicking on it first. */ componentDidMount() { - // if (this._inputRef.current) { - // this._inputRef.current.focus(); - // } + this.classifyImagesInBox(); + reaction( + () => this._selectedImages, + () => this.classifyImagesInBox() + ); } - @action - addLabel = (label: string) => { - label = label.toUpperCase().trim(); - if (label.length > 0) { - if (!this._labelGroups.includes(label)) { - this._labelGroups = [...this._labelGroups, label]; - } - } - }; - - @action - removeLabel = (label: string) => { - const labelUp = label.toUpperCase(); - this._labelGroups = this._labelGroups.filter(group => group !== labelUp); - }; - @action groupImages = () => { MarqueeOptionsMenu.Instance.groupImages(); - this._labelGroups = []; MainView.Instance.closeFlyout(); }; @action startLoading = () => { this._loading = true; + console.log('Start loading has been called!'); }; @action @@ -85,8 +118,38 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { }; @action - setSelectedImages = (selected: Doc[]) => { - this._selectedImages = selected; + toggleDisplayInformation = () => { + this._displayImageInformation = !this._displayImageInformation; + }; + + onInputChange = action((e: React.ChangeEvent) => { + this._currentLabel = e.target.value; + }); + + classifyImagesInBox = async () => { + this.startLoading(); + + const imageInfos = this._selectedImages.map(async doc => { + if (!doc[DocData].data_labels) { + const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); + return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => + !hrefBase64 ? undefined : + gptImageLabel(hrefBase64).then(labels => + Promise.all(labels.split('\n').map(label => gptGetEmbedding(label))).then(embeddings => + ({ doc, embeddings, labels }))) ); // prettier-ignore + } + }); // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. + + (await Promise.all(imageInfos)).forEach(imageInfo => { + if (imageInfo && imageInfo.embeddings && Array.isArray(imageInfo.embeddings)) { + imageInfo.doc[DocData].data_labels = imageInfo.labels; + numberRange(3).forEach(n => { + imageInfo.doc[`data_labels_embedding_${n + 1}`] = new List(imageInfo.embeddings[n]); + }); + } + }); // Add the labels as fields to each image. + + this.endLoading(); }; render() { @@ -98,14 +161,20 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { ); } + if (this._selectedImages.length === 0) { + return ( +
+

In order to classify and sort images, marquee select the desired images and press the 'Classify and Sort Images' button. Then, add the desired groups for the images to be put in.

+
+ ); + } + return (
{ - this._displayImageInformation = !this._displayImageInformation; - }} + onPointerDown={this.toggleDisplayInformation} icon={this._displayImageInformation ? : } color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} @@ -113,6 +182,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { { // e.key === 'Enter' ? this.submitSearch() : null; // e.stopPropagation(); @@ -129,8 +199,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { tooltip={'Add a label'} onPointerDown={() => { const input = document.getElementById('new-label') as HTMLInputElement; - const newLabel = input.value; - this.addLabel(newLabel); + ImageLabelBoxData.Instance.addLabel(this._currentLabel); this._currentLabel = ''; input.value = ''; }} @@ -144,12 +213,12 @@ export class ImageLabelBox extends ViewBoxBaseComponent() {
{this._labelGroups.map(group => { return ( -
+

{group}

{ - this.removeLabel(group); + ImageLabelBoxData.Instance.removeLabel(group); }} icon={'x'} color={MarqueeOptionsMenu.Instance.userColor} @@ -161,15 +230,21 @@ export class ImageLabelBox extends ViewBoxBaseComponent() {
{this._displayImageInformation ? ( -
+
{this._selectedImages.map(doc => { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return ( -
+
- {(doc[DocData].data_labels as string).split('\n').map(label => { - return
{label}
; - })} +
+ {(doc[DocData].data_labels as string).split('\n').map(label => { + return ( +
+ {label} +
+ ); + })} +
); })} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index f98883bff..81f2a94c1 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -37,7 +37,7 @@ import { ImageLabelHandler } from './ImageLabelHandler'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './MarqueeView.scss'; import { MainView } from '../../MainView'; -import { ImageLabelBox } from './ImageLabelBox'; +import { ImageLabelBox, ImageLabelBoxData } from './ImageLabelBox'; import { SearchBox } from '../../search/SearchBox'; interface MarqueeViewProps { @@ -442,44 +442,12 @@ export class MarqueeView extends ObservableReactComponent { - if (e) { - const groupButton = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyImageGrouper); - if (groupButton) { - MainView.Instance.expandFlyout(groupButton); - while (!ImageLabelBox.Instance) { - await new Promise(resolve => setTimeout(resolve, 1000)).then(() => { - console.log('Waiting for Image Label Box'); - }); - } - ImageLabelBox.Instance.startLoading(); - } + const groupButton = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyImageGrouper); + if (groupButton) { + this._selectedDocs = this.marqueeSelect(false, DocumentType.IMG); + ImageLabelBoxData.Instance.setData(this._selectedDocs); + MainView.Instance.expandFlyout(groupButton); } - - this._selectedDocs = this.marqueeSelect(false, DocumentType.IMG); // Get the selected documents from the marquee select. - ImageLabelBox.Instance!.setSelectedImages(this._selectedDocs); - - const imageInfos = this._selectedDocs.map(async doc => { - if (!doc[DocData].data_labels) { - const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); - return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => - !hrefBase64 ? undefined : - gptImageLabel(hrefBase64).then(labels => - Promise.all(labels.split('\n').map(label => gptGetEmbedding(label))).then(embeddings => - ({ doc, embeddings, labels }))) ); // prettier-ignore - } - }); // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. - - (await Promise.all(imageInfos)).forEach(imageInfo => { - if (imageInfo && imageInfo.embeddings && Array.isArray(imageInfo.embeddings)) { - imageInfo.doc[DocData].data_labels = imageInfo.labels; - numberRange(3).forEach(n => { - imageInfo.doc[`data_labels_embedding_${n + 1}`] = new List(imageInfo.embeddings[n]); - }); - } - }); // Add the labels as fields to each image. - - ImageLabelBox.Instance!.endLoading(); - console.log(this._selectedDocs); }); /** @@ -496,7 +464,7 @@ export class MarqueeView extends ObservableReactComponent { const embedLists = numberRange(3).map(n => Array.from(NumListCast(doc[`data_labels_embedding_${n + 1}`]))); - const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map(l => (embedding && similarity(Array.from(embedding), l)) || 0)); + const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map((l, index) => (embedding && (1 - index * 0.1) * similarity(Array.from(embedding), l)!) || 0)); const {label: mostSimilarLabelCollect} = labelGroups.map(label => ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) .reduce((prev, cur) => cur.similarityScore < 0.3 || cur.similarityScore <= prev.similarityScore ? prev: cur, -- cgit v1.2.3-70-g09d2 From 8aee62b8623e23f6478960291857ee47f50f9aaf Mon Sep 17 00:00:00 2001 From: IEatChili Date: Thu, 13 Jun 2024 16:28:24 -0400 Subject: feat: more ui updates --- .../collectionFreeForm/ImageLabelBox.tsx | 81 +++++++++++++++++++--- .../collections/collectionFreeForm/MarqueeView.tsx | 22 +----- src/client/views/nodes/ImageBox.tsx | 4 ++ 3 files changed, 76 insertions(+), 31 deletions(-) diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index f5530ccc4..571a4504f 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -3,9 +3,9 @@ import { Colors, IconButton } from 'browndash-components'; import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; -import { Doc } from '../../../../fields/Doc'; +import { Doc, NumListCast, Opt } from '../../../../fields/Doc'; import { Docs } from '../../../documents/Documents'; -import { DocumentType } from '../../../documents/DocumentTypes'; +import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { FieldView, FieldViewProps } from '../../nodes/FieldView'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; @@ -21,6 +21,9 @@ import { CollectionCardView } from '../CollectionCardDeckView'; import { gptGetEmbedding, gptImageLabel } from '../../../apis/gpt/GPT'; import { numberRange, Utils } from '../../../../Utils'; import { List } from '../../../../fields/List'; +import { DragManager } from '../../../util/DragManager'; +import { OpenWhere } from '../../nodes/OpenWhere'; +import similarity from 'compute-cosine-similarity'; export class ImageLabelBoxData { static _instance: ImageLabelBoxData; @@ -63,11 +66,26 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { return FieldView.LayoutString(ImageLabelBox, fieldKey); } + private _dropDisposer?: DragManager.DragDropDisposer; public static Instance: ImageLabelBox; private _inputRef = React.createRef(); @observable _loading: boolean = false; private _currentLabel: string = ''; + protected createDropTarget = (ele: HTMLDivElement) => { + this._dropDisposer?.(); + ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc)); + }; + + protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { + const { docDragData } = de.complete; + if (docDragData) { + ImageLabelBoxData.Instance.setData(ImageLabelBoxData.Instance._docs.concat(docDragData.droppedDocuments)); + return false; + } + return false; + } + @computed get _labelGroups() { return ImageLabelBoxData.Instance._labelGroups; } @@ -102,7 +120,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { @action groupImages = () => { - MarqueeOptionsMenu.Instance.groupImages(); + this.groupImagesInBox(); MainView.Instance.closeFlyout(); }; @@ -122,6 +140,14 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { this._displayImageInformation = !this._displayImageInformation; }; + @action + submitLabel = () => { + const input = document.getElementById('new-label') as HTMLInputElement; + ImageLabelBoxData.Instance.addLabel(this._currentLabel); + this._currentLabel = ''; + input.value = ''; + }; + onInputChange = action((e: React.ChangeEvent) => { this._currentLabel = e.target.value; }); @@ -143,6 +169,13 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { (await Promise.all(imageInfos)).forEach(imageInfo => { if (imageInfo && imageInfo.embeddings && Array.isArray(imageInfo.embeddings)) { imageInfo.doc[DocData].data_labels = imageInfo.labels; + + const labels = imageInfo.labels.split('\n'); + labels.forEach(label => { + label = label.replace(/^\d+\.\s*/, '').trim(); + imageInfo.doc[DocData][`${label}`] = true; + }); + numberRange(3).forEach(n => { imageInfo.doc[`data_labels_embedding_${n + 1}`] = new List(imageInfo.embeddings[n]); }); @@ -152,6 +185,32 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { this.endLoading(); }; + /** + * Groups images to most similar labels. + */ + groupImagesInBox = action(async () => { + console.log('Calling!'); + const labelToEmbedding = new Map(); + // Create embeddings for the labels. + await Promise.all(this._labelGroups.map(async label => gptGetEmbedding(label).then(labelEmbedding => labelToEmbedding.set(label, labelEmbedding)))); + + // For each image, loop through the labels, and calculate similarity. Associate it with the + // most similar one. + this._selectedImages.forEach(doc => { + const embedLists = numberRange(3).map(n => Array.from(NumListCast(doc[`data_labels_embedding_${n + 1}`]))); + const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map((l, index) => (embedding && (1 - index * 0.1) * similarity(Array.from(embedding), l)!) || 0)); + const {label: mostSimilarLabelCollect} = + this._labelGroups.map(label => ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) + .reduce((prev, cur) => cur.similarityScore < 0.3 || cur.similarityScore <= prev.similarityScore ? prev: cur, + { label: '', similarityScore: 0, }); // prettier-ignore + doc[DocData].data_label = mostSimilarLabelCollect; // The label most similar to the image's contents. + }); + + if (this._selectedImages) { + MarqueeOptionsMenu.Instance.groupImages(); + } + }); + render() { if (this._loading) { return ( @@ -163,14 +222,14 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { if (this._selectedImages.length === 0) { return ( -
+
this.createDropTarget(ele)}>

In order to classify and sort images, marquee select the desired images and press the 'Classify and Sort Images' button. Then, add the desired groups for the images to be put in.

); } return ( -
+
this.createDropTarget(ele)}>
() { defaultValue="" autoComplete="off" onChange={this.onInputChange} - // onKeyDown={e => { - // e.key === 'Enter' ? this.submitSearch() : null; - // e.stopPropagation(); - // }} + onKeyDown={e => { + e.key === 'Enter' ? this.submitLabel() : null; + e.stopPropagation(); + }} type="text" - placeholder="Input labels for image groupings..." + placeholder="Input groups for images to be put into..." aria-label="label-input" id="new-label" className="searchBox-input" @@ -234,7 +293,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { {this._selectedImages.map(doc => { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return ( -
+
this._props.addDocTab(doc, OpenWhere.addRightKeyvalue)}>
{(doc[DocData].data_labels as string).split('\n').map(label => { diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 81f2a94c1..f03a9d62d 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -455,26 +455,8 @@ export class MarqueeView extends ObservableReactComponent { - const labelGroups = ImageLabelBox.Instance!._labelGroups; - const labelToEmbedding = new Map(); - // Create embeddings for the labels. - await Promise.all(labelGroups.map(async label => gptGetEmbedding(label).then(labelEmbedding => labelToEmbedding.set(label, labelEmbedding)))); - - // For each image, loop through the labels, and calculate similarity. Associate it with the - // most similar one. - this._selectedDocs.forEach(doc => { - const embedLists = numberRange(3).map(n => Array.from(NumListCast(doc[`data_labels_embedding_${n + 1}`]))); - const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map((l, index) => (embedding && (1 - index * 0.1) * similarity(Array.from(embedding), l)!) || 0)); - const {label: mostSimilarLabelCollect} = - labelGroups.map(label => ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) - .reduce((prev, cur) => cur.similarityScore < 0.3 || cur.similarityScore <= prev.similarityScore ? prev: cur, - { label: '', similarityScore: 0, }); // prettier-ignore - doc[DocData].data_label = mostSimilarLabelCollect; // The label most similar to the image's contents. - }); - if (this._selectedDocs) { - this._props.Document._type_collection = CollectionViewType.Time; // Change the collection view to a Time view. - this._props.Document.pivotField = 'data_label'; // Sets the pivot to be the 'data_label'. - } + this._props.Document._type_collection = CollectionViewType.Time; // Change the collection view to a Time view. + this._props.Document.pivotField = 'data_label'; // Sets the pivot to be the 'data_label'. }); @undoBatch diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index e4b3a1b9b..3da878a4f 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -173,6 +173,10 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(targetDoc), this.fieldKey); } } + const layoutDoc = de.complete.docDragData?.draggedDocuments[0]; + const targetField = Doc.LayoutFieldKey(layoutDoc); + const targetDoc = layoutDoc[DocData]; + console.log(targetDoc[targetField]); added === false && e.preventDefault(); added !== undefined && e.stopPropagation(); return added; -- cgit v1.2.3-70-g09d2 From 376ff1626b24cbac12b27ad072690424549f05c7 Mon Sep 17 00:00:00 2001 From: IEatChili Date: Tue, 18 Jun 2024 14:33:47 -0400 Subject: feat: added view of labels on docs in freeform --- src/client/views/KeywordBox.tsx | 69 +++++++++++++++++++ src/client/views/StyleProvider.scss | 13 ++++ src/client/views/StyleProvider.tsx | 9 +++ .../collectionFreeForm/ImageLabelBox.tsx | 79 ++++++++++++++++------ src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 9 +++ 6 files changed, 161 insertions(+), 20 deletions(-) create mode 100644 src/client/views/KeywordBox.tsx diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx new file mode 100644 index 000000000..3faddeb64 --- /dev/null +++ b/src/client/views/KeywordBox.tsx @@ -0,0 +1,69 @@ +import { action, makeObservable } from 'mobx'; +import { observer } from 'mobx-react'; +import React from 'react'; +import { Doc } from '../../fields/Doc'; +import { DocData } from '../../fields/DocSymbols'; +import { List } from '../../fields/List'; +import { ObservableReactComponent } from './ObservableReactComponent'; + +interface KeywordBoxProps { + _doc: Doc; + _isEditing: boolean; +} + +@observer +export class KeywordBox extends ObservableReactComponent { + constructor(props: any) { + super(props); + makeObservable(this); + } + + @action + setToEditing = () => { + this._props._isEditing = true; + }; + + @action + setToView = () => { + this._props._isEditing = false; + }; + + submitLabel = () => {}; + + onInputChange = () => {}; + + render() { + const keywordsList = this._props._doc![DocData].data_labels; + return ( +
+ {(keywordsList as List).map(label => { + return ( +
+ {label} +
+ ); + })} + {this._props._isEditing ? ( +
+ { + e.key === 'Enter' ? this.submitLabel() : null; + e.stopPropagation(); + }} + type="text" + placeholder="Input keywords for document..." + aria-label="keyword-input" + className="keyword-input" + style={{ width: '100%', borderRadius: '5px' }} + /> +
+ ) : ( +
+ )} +
+ ); + } +} diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss index ce00f6101..1e2af9a3a 100644 --- a/src/client/views/StyleProvider.scss +++ b/src/client/views/StyleProvider.scss @@ -53,3 +53,16 @@ .styleProvider-treeView-icon { opacity: 0; } + +.keywords-container { + display: flex; + flex-wrap: wrap; +} + +.keyword { + padding: 5px 10px; + background-color: lightblue; + border: 1px solid black; + border-radius: 5px; + white-space: nowrap; +} diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index b7f8a3170..fb509516a 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -12,7 +12,9 @@ import { BsArrowDown, BsArrowDownUp, BsArrowUp } from 'react-icons/bs'; import { FaFilter } from 'react-icons/fa'; import { ClientUtils, DashColor, lightOrDark } from '../../ClientUtils'; import { Doc, Opt, StrListCast } from '../../fields/Doc'; +import { DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; +import { List } from '../../fields/List'; import { ScriptField } from '../../fields/ScriptField'; import { BoolCast, Cast, DocCast, ImageCast, NumCast, ScriptCast, StrCast } from '../../fields/Types'; import { AudioAnnoState } from '../../server/SharedMediaTypes'; @@ -23,6 +25,7 @@ import { SnappingManager } from '../util/SnappingManager'; import { undoBatch, UndoManager } from '../util/UndoManager'; import { TreeSort } from './collections/TreeSort'; import { Colors } from './global/globalEnums'; +import { KeywordBox } from './KeywordBox'; import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; import { FieldViewProps } from './nodes/FieldView'; import { StyleProp } from './StyleProp'; @@ -367,12 +370,18 @@ export function DefaultStyleProvider(doc: Opt, props: Opt ); }; + const keywords = () => { + if (doc && doc![DocData].data_labels && doc![DocData].showLabels) { + return () + } + } return ( <> {paint()} {lock()} {filter()} {audio()} + {keywords()} ); } diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index 571a4504f..cfb81e1a0 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -5,7 +5,7 @@ import { observer } from 'mobx-react'; import React from 'react'; import { Doc, NumListCast, Opt } from '../../../../fields/Doc'; import { Docs } from '../../../documents/Documents'; -import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; +import { DocumentType } from '../../../documents/DocumentTypes'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { FieldView, FieldViewProps } from '../../nodes/FieldView'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; @@ -24,6 +24,9 @@ import { List } from '../../../../fields/List'; import { DragManager } from '../../../util/DragManager'; import { OpenWhere } from '../../nodes/OpenWhere'; import similarity from 'compute-cosine-similarity'; +import { DocumentView } from '../../nodes/DocumentView'; + +export class ImageInformationItem {} export class ImageLabelBoxData { static _instance: ImageLabelBoxData; @@ -101,7 +104,6 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { makeObservable(this); ring.register(); ImageLabelBox.Instance = this; - console.log('Image Box Has Been Initialized'); } // ImageLabelBox.Instance.setData() @@ -127,7 +129,6 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { @action startLoading = () => { this._loading = true; - console.log('Start loading has been called!'); }; @action @@ -138,6 +139,11 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { @action toggleDisplayInformation = () => { this._displayImageInformation = !this._displayImageInformation; + if (this._displayImageInformation) { + this._selectedImages.forEach(doc => (doc[DocData].showLabels = true)); + } else { + this._selectedImages.forEach(doc => (doc[DocData].showLabels = false)); + } }; @action @@ -155,33 +161,58 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { classifyImagesInBox = async () => { this.startLoading(); + // const imageInfos = this._selectedImages.map(async doc => { + // if (!doc[DocData].data_labels) { + // const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); + // return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => + // !hrefBase64 ? undefined : + // gptImageLabel(hrefBase64).then(labels => + // Promise.all(labels.split('\n').map(label => gptGetEmbedding(label))).then(embeddings => + // ({ doc, embeddings, labels }))) ); // prettier-ignore + // } + // }); // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. + const imageInfos = this._selectedImages.map(async doc => { if (!doc[DocData].data_labels) { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => !hrefBase64 ? undefined : gptImageLabel(hrefBase64).then(labels => - Promise.all(labels.split('\n').map(label => gptGetEmbedding(label))).then(embeddings => - ({ doc, embeddings, labels }))) ); // prettier-ignore + + ({ doc, labels }))) ; // prettier-ignore } - }); // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. + }); (await Promise.all(imageInfos)).forEach(imageInfo => { - if (imageInfo && imageInfo.embeddings && Array.isArray(imageInfo.embeddings)) { - imageInfo.doc[DocData].data_labels = imageInfo.labels; + if (imageInfo) { + imageInfo.doc[DocData].data_labels = new List(); const labels = imageInfo.labels.split('\n'); labels.forEach(label => { - label = label.replace(/^\d+\.\s*/, '').trim(); + label = label.replace(/^\d+\.\s*|-|\*/, '').trim(); imageInfo.doc[DocData][`${label}`] = true; - }); - - numberRange(3).forEach(n => { - imageInfo.doc[`data_labels_embedding_${n + 1}`] = new List(imageInfo.embeddings[n]); + (imageInfo.doc[DocData].data_labels as List).push(label); }); } }); // Add the labels as fields to each image. + // (await Promise.all(imageInfos)).forEach(imageInfo => { + // if (imageInfo && imageInfo.embeddings && Array.isArray(imageInfo.embeddings)) { + // imageInfo.doc[DocData].data_labels = new List(); + + // const labels = imageInfo.labels.split('\n'); + // labels.forEach(label => { + // label = label.replace(/^\d+\.\s*|-|\*/, '').trim(); + // imageInfo.doc[DocData][`${label}`] = true; + // (imageInfo.doc[DocData].data_labels as List).push(label); + // }); + + // numberRange(5).forEach(n => { + // imageInfo.doc[`data_labels_embedding_${n + 1}`] = new List(imageInfo.embeddings[n]); + // }); + // } + // }); // Add the labels as fields to each image. + this.endLoading(); }; @@ -189,7 +220,13 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { * Groups images to most similar labels. */ groupImagesInBox = action(async () => { - console.log('Calling!'); + this._selectedImages.forEach(doc => { + (doc[DocData].data_labels as List).forEach(async (label, index) => { + const embedding = await gptGetEmbedding(label); + doc[`data_labels_embedding_${index + 1}`] = new List(embedding); + }); + }); + const labelToEmbedding = new Map(); // Create embeddings for the labels. await Promise.all(this._labelGroups.map(async label => gptGetEmbedding(label).then(labelEmbedding => labelToEmbedding.set(label, labelEmbedding)))); @@ -197,7 +234,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { // For each image, loop through the labels, and calculate similarity. Associate it with the // most similar one. this._selectedImages.forEach(doc => { - const embedLists = numberRange(3).map(n => Array.from(NumListCast(doc[`data_labels_embedding_${n + 1}`]))); + const embedLists = numberRange(5).map(n => Array.from(NumListCast(doc[`data_labels_embedding_${n + 1}`]))); const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map((l, index) => (embedding && (1 - index * 0.1) * similarity(Array.from(embedding), l)!) || 0)); const {label: mostSimilarLabelCollect} = this._labelGroups.map(label => ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) @@ -293,10 +330,14 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { {this._selectedImages.map(doc => { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return ( -
this._props.addDocTab(doc, OpenWhere.addRightKeyvalue)}> - -
- {(doc[DocData].data_labels as string).split('\n').map(label => { +
+ { + await DocumentView.showDocument(doc, { willZoomCentered: true }); + }}> +
this._props.addDocTab(doc, OpenWhere.addRightKeyvalue)}> + {(doc[DocData].data_labels as List).map(label => { return (
{label} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7a1f94948..9ff96c692 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -573,7 +573,7 @@ export class DocumentViewInternal extends DocComponent DocumentView.SetLightboxDoc(this.Document), icon: 'external-link-alt' }); } - appearanceItems.push({ description: 'Pin', event: () => this._props.pinToPres(this.Document, {}), icon: 'eye' }); + appearanceItems.push({ description: 'Pin', event: () => this._props.pinToPres(this.Document, {}), icon: 'map-pin' }); if (this.Document._layout_isFlashcard) { appearanceItems.push({ description: 'Create ChatCard', event: () => this.askGPT(), icon: 'id-card' }); } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 3da878a4f..fb90f907f 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,5 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; +import zIndex from '@mui/material/styles/zIndex'; import { Colors } from 'browndash-components'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction } from 'mobx'; import { observer } from 'mobx-react'; @@ -10,6 +11,7 @@ import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; +import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; @@ -281,6 +283,13 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { }), icon: 'pencil-alt', }); + funcs.push({ + description: 'Toggle Keywords', + event: () => { + this.Document[DocData].showLabels = !this.Document[DocData].showLabels; + }, + icon: 'eye', + }); ContextMenu.Instance?.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' }); } }; -- cgit v1.2.3-70-g09d2 From 3190f1eb07a47a5e1ccdd20e346b47094118292d Mon Sep 17 00:00:00 2001 From: IEatChili Date: Wed, 26 Jun 2024 13:58:20 -0400 Subject: feat: worked more on keyword input for docs --- src/client/views/DocumentButtonBar.tsx | 19 +++ src/client/views/DocumentDecorations.tsx | 1 + src/client/views/KeywordBox.tsx | 168 +++++++++++++++++---- src/client/views/StyleProvider.scss | 31 +++- src/client/views/StyleProvider.tsx | 6 +- .../collectionFreeForm/ImageLabelBox.tsx | 53 ++----- .../collections/collectionFreeForm/MarqueeView.tsx | 28 +++- src/client/views/nodes/ImageBox.tsx | 7 - 8 files changed, 233 insertions(+), 80 deletions(-) diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 487868169..a75c7098c 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -31,6 +31,7 @@ import { DocumentLinksButton } from './nodes/DocumentLinksButton'; import { DocumentView } from './nodes/DocumentView'; import { OpenWhere } from './nodes/OpenWhere'; import { DashFieldView } from './nodes/formattedText/DashFieldView'; +import { DocData } from '../../fields/DocSymbols'; @observer export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (DocumentView | undefined)[]; stack?: any }> { @@ -282,6 +283,23 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( ); } + @computed + get keywordButton() { + const targetDoc = this.view0?.Document; + return !targetDoc ? null : ( + Open keyword menu
}> +
{ + targetDoc[DocData].showLabels = !targetDoc[DocData].showLabels; + }}> + +
+ + ); + } + @observable _isRecording = false; _stopFunc: () => void = emptyFunction; @computed @@ -452,6 +470,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
{this.pinButton}
{this.recordButton}
{this.calendarButton}
+
{this.keywordButton}
{!Doc.UserDoc().documentLinksButton_fullMenu ? null :
{this.shareButton}
}
{this.menuButton}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 93c3e3338..20bf8fd9f 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -88,6 +88,7 @@ export class DocumentDecorations extends ObservableReactComponent center.x+x || this.Bounds.r < center.x+x || this.Bounds.y > center.y+y || this.Bounds.b < center.y+y ))); + })); // prettier-ignore } diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx index 3faddeb64..8c69f446d 100644 --- a/src/client/views/KeywordBox.tsx +++ b/src/client/views/KeywordBox.tsx @@ -1,64 +1,170 @@ -import { action, makeObservable } from 'mobx'; +import { Colors, IconButton } from 'browndash-components'; +import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; import { Doc } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; +import { DragManager, SetupDrag } from '../util/DragManager'; +import { SnappingManager } from '../util/SnappingManager'; +import { DocumentView } from './nodes/DocumentView'; import { ObservableReactComponent } from './ObservableReactComponent'; +interface KeywordItemProps { + doc: Doc; + label: string; + setToEditing: () => void; + isEditing: boolean; +} + +@observer +export class KeywordItem extends ObservableReactComponent { + constructor(props: any) { + super(props); + makeObservable(this); + this.ref = React.createRef(); + } + + private _dropDisposer?: DragManager.DragDropDisposer; + private ref: React.RefObject; + + protected createDropTarget = (ele: HTMLDivElement) => { + this._dropDisposer?.(); + SetupDrag(this.ref, () => undefined); + //ele && (this._dropDisposer = DragManager. (ele, this.onInternalDrop.bind(this), this.layoutDoc)); + //ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc)); + }; + + @action + removeLabel = () => { + if (this._props.doc[DocData].data_labels) { + this._props.doc[DocData].data_labels = (this._props.doc[DocData].data_labels as List).filter(label => label !== this._props.label) as List; + } + }; + + render() { + return ( +
{}} ref={this.ref}> + {this._props.label} + {this.props.isEditing && } +
+ ); + } +} + interface KeywordBoxProps { - _doc: Doc; - _isEditing: boolean; + doc: Doc; + isEditing: boolean; } @observer export class KeywordBox extends ObservableReactComponent { + @observable _currentInput: string = ''; + //private disposer: () => void; + constructor(props: any) { super(props); makeObservable(this); } + // componentDidMount(): void { + // reaction( + // () => ({ + // isDragging: SnappingManager.IsDragging, + // selectedDoc: DocumentView.SelectedDocs().lastElement(), + // isEditing: this._props.isEditing, + // }), + // ({ isDragging, selectedDoc, isEditing }) => { + // if (isDragging || selectedDoc !== this._props.doc || !isEditing) { + // this.setToView(); + // } + // } + // ); + // } + + // componentWillUnmount() { + // this.disposer(); + // } + @action setToEditing = () => { - this._props._isEditing = true; + this._props.isEditing = true; }; @action setToView = () => { - this._props._isEditing = false; + this._props.isEditing = false; }; - submitLabel = () => {}; + submitLabel = () => { + if (this._currentInput.trim()) { + if (!this._props.doc[DocData].data_labels) { + this._props.doc[DocData].data_labels = new List(); + } - onInputChange = () => {}; + (this._props.doc![DocData].data_labels! as List).push(this._currentInput.trim()); + this._currentInput = ''; // Clear the input box + } + }; + + @action + onInputChange = (e: React.ChangeEvent) => { + this._currentInput = e.target.value; + }; render() { - const keywordsList = this._props._doc![DocData].data_labels; + const keywordsList = this._props.doc[DocData].data_labels ? this._props.doc[DocData].data_labels : new List(); + const seldoc = DocumentView.SelectedDocs().lastElement(); + if (SnappingManager.IsDragging || !(seldoc === this._props.doc) || !this._props.isEditing) { + setTimeout( + action(() => { + if ((keywordsList as List).length === 0) { + this._props.doc[DocData].showLabels = false; + } + this.setToView(); + }) + ); + } + return ( -
- {(keywordsList as List).map(label => { - return ( -
- {label} +
+
+ {(keywordsList as List).map(label => { + return ; + })} +
+ {this._props.isEditing ? ( +
+
+ { + e.key === 'Enter' ? this.submitLabel() : null; + e.stopPropagation(); + }} + type="text" + placeholder="Input keywords for document..." + aria-label="keyword-input" + className="keyword-input" + style={{ width: '100%', borderRadius: '5px' }} + /> +
+
+ { + if ((keywordsList as List).length === 0) { + this._props.doc[DocData].showLabels = false; + } else { + this.setToView(); + } + }} + icon={'x'} + style={{ width: '4px' }} + />
- ); - })} - {this._props._isEditing ? ( -
- { - e.key === 'Enter' ? this.submitLabel() : null; - e.stopPropagation(); - }} - type="text" - placeholder="Input keywords for document..." - aria-label="keyword-input" - className="keyword-input" - style={{ width: '100%', borderRadius: '5px' }} - />
) : (
diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss index 1e2af9a3a..7cc06f922 100644 --- a/src/client/views/StyleProvider.scss +++ b/src/client/views/StyleProvider.scss @@ -57,12 +57,41 @@ .keywords-container { display: flex; flex-wrap: wrap; + flex-direction: column; + padding-bottom: 4px; + border: 1px solid; + border-radius: 4px; +} + +.keywords-list { + display: flex; + flex-wrap: wrap; } .keyword { - padding: 5px 10px; + padding: 5px 5px; background-color: lightblue; border: 1px solid black; border-radius: 5px; white-space: nowrap; + display: flex; + align-items: center; +} + +.keyword-editing-box { + margin-top: 8px; +} + +.keyword-input-box { + // display: flex; + // align-items: center; + // align-content: center; + margin: auto; + align-self: center; + width: 90%; +} + +.keyword-buttons { + margin-left: auto; + width: 10%; } diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index fb509516a..f4d73cd1d 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -371,8 +371,10 @@ export function DefaultStyleProvider(doc: Opt, props: Opt { - if (doc && doc![DocData].data_labels && doc![DocData].showLabels) { - return () + if (doc && doc![DocData].showLabels && (!doc[DocData].data_labels || (doc[DocData].data_labels as List).length === 0)){ + return () + } else if (doc && doc![DocData].data_labels && doc![DocData].showLabels) { + return () } } return ( diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index cfb81e1a0..fec4d3e12 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -123,7 +123,6 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { @action groupImages = () => { this.groupImagesInBox(); - MainView.Instance.closeFlyout(); }; @action @@ -161,16 +160,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { classifyImagesInBox = async () => { this.startLoading(); - // const imageInfos = this._selectedImages.map(async doc => { - // if (!doc[DocData].data_labels) { - // const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); - // return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => - // !hrefBase64 ? undefined : - // gptImageLabel(hrefBase64).then(labels => - // Promise.all(labels.split('\n').map(label => gptGetEmbedding(label))).then(embeddings => - // ({ doc, embeddings, labels }))) ); // prettier-ignore - // } - // }); // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. + // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. const imageInfos = this._selectedImages.map(async doc => { if (!doc[DocData].data_labels) { @@ -178,8 +168,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => !hrefBase64 ? undefined : gptImageLabel(hrefBase64).then(labels => - - ({ doc, labels }))) ; // prettier-ignore + ({ doc, labels }))) ; // prettier-ignore } }); @@ -194,24 +183,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { (imageInfo.doc[DocData].data_labels as List).push(label); }); } - }); // Add the labels as fields to each image. - - // (await Promise.all(imageInfos)).forEach(imageInfo => { - // if (imageInfo && imageInfo.embeddings && Array.isArray(imageInfo.embeddings)) { - // imageInfo.doc[DocData].data_labels = new List(); - - // const labels = imageInfo.labels.split('\n'); - // labels.forEach(label => { - // label = label.replace(/^\d+\.\s*|-|\*/, '').trim(); - // imageInfo.doc[DocData][`${label}`] = true; - // (imageInfo.doc[DocData].data_labels as List).push(label); - // }); - - // numberRange(5).forEach(n => { - // imageInfo.doc[`data_labels_embedding_${n + 1}`] = new List(imageInfo.embeddings[n]); - // }); - // } - // }); // Add the labels as fields to each image. + }); this.endLoading(); }; @@ -220,12 +192,15 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { * Groups images to most similar labels. */ groupImagesInBox = action(async () => { - this._selectedImages.forEach(doc => { - (doc[DocData].data_labels as List).forEach(async (label, index) => { + this.startLoading(); + + for (const doc of this._selectedImages) { + for (let index = 0; index < (doc[DocData].data_labels as List).length; index++) { + const label = (doc[DocData].data_labels as List)[index]; const embedding = await gptGetEmbedding(label); doc[`data_labels_embedding_${index + 1}`] = new List(embedding); - }); - }); + } + } const labelToEmbedding = new Map(); // Create embeddings for the labels. @@ -234,8 +209,8 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { // For each image, loop through the labels, and calculate similarity. Associate it with the // most similar one. this._selectedImages.forEach(doc => { - const embedLists = numberRange(5).map(n => Array.from(NumListCast(doc[`data_labels_embedding_${n + 1}`]))); - const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map((l, index) => (embedding && (1 - index * 0.1) * similarity(Array.from(embedding), l)!) || 0)); + const embedLists = numberRange((doc[DocData].data_labels as List).length).map(n => Array.from(NumListCast(doc[`data_labels_embedding_${n + 1}`]))); + const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map((l, index) => (embedding && similarity(Array.from(embedding), l)!) || 0)); const {label: mostSimilarLabelCollect} = this._labelGroups.map(label => ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) .reduce((prev, cur) => cur.similarityScore < 0.3 || cur.similarityScore <= prev.similarityScore ? prev: cur, @@ -243,9 +218,13 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { doc[DocData].data_label = mostSimilarLabelCollect; // The label most similar to the image's contents. }); + this.endLoading(); + if (this._selectedImages) { MarqueeOptionsMenu.Instance.groupImages(); } + + MainView.Instance.closeFlyout(); }); render() { diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index f03a9d62d..197681f62 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -455,8 +455,32 @@ export class MarqueeView extends ObservableReactComponent { - this._props.Document._type_collection = CollectionViewType.Time; // Change the collection view to a Time view. - this._props.Document.pivotField = 'data_label'; // Sets the pivot to be the 'data_label'. + const labelGroups: string[] = ImageLabelBoxData.Instance._labelGroups; + const labelToCollection: Map = new Map(); + const selectedImages = ImageLabelBoxData.Instance._docs; + + // Create new collections associated with each label and get the embeddings for the labels. + let x_offset = 0; + for (const label of labelGroups) { + const newCollection = this.getCollection([], undefined, false); + newCollection._freeform_panX = this.Bounds.left + this.Bounds.width / 2; + newCollection._freeform_panY = this.Bounds.top + this.Bounds.height / 2; + console.log(newCollection._x); + labelToCollection.set(label, newCollection); + this._props.addDocument?.(newCollection); + //newCollection._x = (newCollection._x as number) + x_offset; + //x_offset += newCollection._width as number; + } + + for (const doc of selectedImages) { + if (doc[DocData].data_label) { + Doc.AddDocToList(labelToCollection.get(doc[DocData].data_label as string)!, undefined, doc); + this._props.removeDocument?.(doc); + } + } + + //this._props.Document._type_collection = CollectionViewType.Time; // Change the collection view to a Time view. + //this._props.Document.pivotField = 'data_label'; // Sets the pivot to be the 'data_label'. }); @undoBatch diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index fb90f907f..1c90fae9e 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -283,13 +283,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { }), icon: 'pencil-alt', }); - funcs.push({ - description: 'Toggle Keywords', - event: () => { - this.Document[DocData].showLabels = !this.Document[DocData].showLabels; - }, - icon: 'eye', - }); ContextMenu.Instance?.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' }); } }; -- cgit v1.2.3-70-g09d2 From 7e13e1df797f1d3358f553802527bf42c5574e81 Mon Sep 17 00:00:00 2001 From: IEatChili Date: Thu, 27 Jun 2024 13:55:55 -0400 Subject: feat: added grid of collections when sorting --- src/client/views/KeywordBox.tsx | 2 ++ .../collections/collectionFreeForm/MarqueeView.tsx | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx index 8c69f446d..d94f011f4 100644 --- a/src/client/views/KeywordBox.tsx +++ b/src/client/views/KeywordBox.tsx @@ -39,6 +39,7 @@ export class KeywordItem extends ObservableReactComponent { removeLabel = () => { if (this._props.doc[DocData].data_labels) { this._props.doc[DocData].data_labels = (this._props.doc[DocData].data_labels as List).filter(label => label !== this._props.label) as List; + this._props.doc![DocData][`${this._props.label}`] = false; } }; @@ -103,6 +104,7 @@ export class KeywordBox extends ObservableReactComponent { } (this._props.doc![DocData].data_labels! as List).push(this._currentInput.trim()); + this._props.doc![DocData][`${this._currentInput}`] = true; this._currentInput = ''; // Clear the input box } }; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 197681f62..07e3acb1d 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -461,17 +461,32 @@ export class MarqueeView extends ObservableReactComponent Date: Wed, 17 Jul 2024 15:13:11 -0400 Subject: feat: created smart collections --- src/client/documents/Documents.ts | 9 +- src/client/views/DocumentDecorations.scss | 2 +- src/client/views/DocumentDecorations.tsx | 2 + src/client/views/KeywordBox.tsx | 197 +++++++++++++++++---- src/client/views/StyleProvider.scss | 1 - src/client/views/collections/CollectionSubView.tsx | 4 +- src/client/views/collections/CollectionView.tsx | 1 + .../collectionFreeForm/ImageLabelBox.tsx | 4 +- .../collections/collectionFreeForm/MarqueeView.tsx | 3 - 9 files changed, 174 insertions(+), 49 deletions(-) diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 449347403..3737aa0b5 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -37,12 +37,13 @@ export enum FInfoFieldType { date = 'date', list = 'list', rtf = 'rich text', + map = 'map', } export class FInfo { description: string = ''; readOnly: boolean = false; fieldType?: FInfoFieldType; - values?: FieldType[]; + values?: FieldType[] | Map; filterable?: boolean = true; // can be used as a Filter in FilterPanel // format?: string; // format to display values (e.g, decimal places, $, etc) @@ -143,6 +144,10 @@ class ListInfo extends FInfo { fieldType? = FInfoFieldType.list; values?: List[] = []; } +class MapInfo extends FInfo { + fieldType? = FInfoFieldType.map; + values?: Map = new Map(); +} type BOOLt = BoolInfo | boolean; type NUMt = NumInfo | number; type STRt = StrInfo | string; @@ -155,6 +160,7 @@ type COLLt = CTypeInfo | CollectionViewType; type DROPt = DAInfo | dropActionType; type DATEt = DateInfo | number; type DTYPEt = DTypeInfo | string; +type MAPt = MapInfo | Map; export class DocumentOptions { // coordinate and dimensions depending on view x?: NUMt = new NumInfo('horizontal coordinate in freeform view', false); @@ -481,6 +487,7 @@ export class DocumentOptions { cardSort?: STRt = new StrInfo('way cards are sorted in deck view'); cardSort_customField?: STRt = new StrInfo('field key used for sorting cards'); cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) + keywords?: MAPt = new MapInfo('keywords', true); } export const DocOptions = new DocumentOptions(); diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 239c0a977..67e1054c3 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -512,7 +512,7 @@ $resizeHandler: 8px; justify-content: center; align-items: center; gap: 5px; - top: 4px; + //top: 4px; background: $light-gray; opacity: 0.2; pointer-events: all; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 20bf8fd9f..dc40562e8 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -640,6 +640,7 @@ export class DocumentDecorations extends ObservableReactComponent { @@ -831,6 +832,7 @@ export class DocumentDecorations extends ObservableReactComponent DocumentView.Selected()} /> diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx index d94f011f4..321362299 100644 --- a/src/client/views/KeywordBox.tsx +++ b/src/client/views/KeywordBox.tsx @@ -2,17 +2,26 @@ import { Colors, IconButton } from 'browndash-components'; import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; -import { Doc } from '../../fields/Doc'; +import { returnFalse, setupMoveUpEvents } from '../../ClientUtils'; +import { Doc, DocListCast } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; +import { DocCast, NumCast } from '../../fields/Types'; +import { emptyFunction } from '../../Utils'; +import { Docs } from '../documents/Documents'; +import { DocUtils } from '../documents/DocUtils'; import { DragManager, SetupDrag } from '../util/DragManager'; import { SnappingManager } from '../util/SnappingManager'; +import { CollectionFreeFormView } from './collections/collectionFreeForm'; +import { MainView } from './MainView'; import { DocumentView } from './nodes/DocumentView'; import { ObservableReactComponent } from './ObservableReactComponent'; interface KeywordItemProps { doc: Doc; - label: string; + keyword: string; + keywordDoc: Doc; + keywordCollection: Doc[]; setToEditing: () => void; isEditing: boolean; } @@ -25,28 +34,77 @@ export class KeywordItem extends ObservableReactComponent { this.ref = React.createRef(); } - private _dropDisposer?: DragManager.DragDropDisposer; private ref: React.RefObject; - protected createDropTarget = (ele: HTMLDivElement) => { - this._dropDisposer?.(); - SetupDrag(this.ref, () => undefined); - //ele && (this._dropDisposer = DragManager. (ele, this.onInternalDrop.bind(this), this.layoutDoc)); - //ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc)); + getKeywordCollectionDocs = () => { + for (const doc of DocListCast(Doc.UserDoc().myKeywordCollections)) { + if (doc.title === this._props.keyword) { + return doc[DocData].docs; + } + } + return null; + }; + + createCollection = () => { + const selected = DocListCast(this.getKeywordCollectionDocs()!); + const newEmbeddings = selected.map(doc => Doc.MakeEmbedding(doc)); + const newCollection = ((doc: Doc) => { + const docData = doc[DocData]; + docData.data = new List(newEmbeddings); + docData.title = this._props.keyword; + doc._freeform_panX = doc._freeform_panY = 0; + return doc; + })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true)); + newEmbeddings.forEach(embed => (embed.embedContainer = newCollection)); + newCollection._width = 900; + newCollection._height = 900; + newCollection.layout_fitWidth = true; + //newCollection[DocData].smartCollection = this._props.keywordDoc; + + this._props.keywordDoc.collections = new List([...DocListCast(this._props.keywordDoc.collections), newCollection]); + return newCollection; + }; + + @action + handleDragStart = (e: React.PointerEvent) => { + if (this._props.isEditing) { + const clone = this.ref.current?.cloneNode(true) as HTMLElement; + if (!clone) return; + + setupMoveUpEvents( + this, + e, + () => { + const dragData = new DragManager.DocumentDragData([this.createCollection()]); + DragManager.StartDocumentDrag([this.ref.current!], dragData, e.clientX, e.clientY, {}); + return true; + }, + returnFalse, + emptyFunction + ); + e.preventDefault(); + } }; @action removeLabel = () => { if (this._props.doc[DocData].data_labels) { - this._props.doc[DocData].data_labels = (this._props.doc[DocData].data_labels as List).filter(label => label !== this._props.label) as List; - this._props.doc![DocData][`${this._props.label}`] = false; + const filtered_docs = new List(DocListCast(this.getKeywordCollectionDocs()!).filter(doc => doc !== this._props.doc)); + this._props.keywordDoc[DocData].docs = filtered_docs; + + this._props.doc[DocData].data_labels = (this._props.doc[DocData].data_labels as List).filter(label => label !== this._props.keyword) as List; + this._props.doc![DocData][`${this._props.keyword}`] = false; + + for (const collection of DocListCast(this._props.keywordDoc.collections)) { + collection[DocData].data = new List(DocListCast(collection[DocData].data).filter(doc => !Doc.AreProtosEqual(this._props.doc, doc))); + } } }; render() { return ( -
{}} ref={this.ref}> - {this._props.label} +
+ {this._props.keyword} {this.props.isEditing && }
); @@ -61,31 +119,39 @@ interface KeywordBoxProps { @observer export class KeywordBox extends ObservableReactComponent { @observable _currentInput: string = ''; - //private disposer: () => void; + private height: number = 0; + private ref: React.RefObject; + + @computed + get currentScale() { + return NumCast((this._props.doc.embedContainer as Doc)?._freeform_scale, 1); + } constructor(props: any) { super(props); makeObservable(this); + this.ref = React.createRef(); } - // componentDidMount(): void { - // reaction( - // () => ({ - // isDragging: SnappingManager.IsDragging, - // selectedDoc: DocumentView.SelectedDocs().lastElement(), - // isEditing: this._props.isEditing, - // }), - // ({ isDragging, selectedDoc, isEditing }) => { - // if (isDragging || selectedDoc !== this._props.doc || !isEditing) { - // this.setToView(); - // } - // } - // ); - // } - - // componentWillUnmount() { - // this.disposer(); - // } + componentDidMount(): void { + this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; + this._props.doc._keywordHeight = this.height; + + reaction( + () => this.currentScale, + () => { + if (this.currentScale < 1) { + this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; + this._props.doc._keywordHeight = this.height; + } + } + ); + } + + componentDidUpdate(prevProps: Readonly): void { + this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; + this._props.doc._keywordHeight = this.height; + } @action setToEditing = () => { @@ -97,14 +163,51 @@ export class KeywordBox extends ObservableReactComponent { this._props.isEditing = false; }; + getKeywordCollection = (keyword: string) => { + for (const doc of DocListCast(Doc.UserDoc().myKeywordCollections)) { + if (doc.title === keyword) { + return doc; + } + } + + const keywordCollection = new Doc(); + keywordCollection.title = keyword; + keywordCollection[DocData].docs = new List(); + keywordCollection.collections = new List(); + Doc.UserDoc().myKeywordCollections = new List([...DocListCast(Doc.UserDoc().myKeywordCollections), keywordCollection]); + + return keywordCollection; + }; + submitLabel = () => { - if (this._currentInput.trim()) { + if (!Doc.UserDoc().myKeywordCollections) { + Doc.UserDoc().myKeywordCollections = new List(); + } + + const submittedLabel = this._currentInput.trim(); + if (submittedLabel) { + // If the keyword collection is not in the user doc, add it as a new doc, with the keyword as its title. + const keywordCollection = this.getKeywordCollection(submittedLabel); + + // If the document has no keywords field, create the field. if (!this._props.doc[DocData].data_labels) { this._props.doc[DocData].data_labels = new List(); } - (this._props.doc![DocData].data_labels! as List).push(this._currentInput.trim()); + // Add this document to the keyword's collection of associated documents. + keywordCollection[DocData].docs = new List([...DocListCast(keywordCollection[DocData].docs), this._props.doc]); + + // Push the keyword to the document's keyword list field. + (this._props.doc![DocData].data_labels! as List).push(submittedLabel); this._props.doc![DocData][`${this._currentInput}`] = true; + + // Iterate through the keyword document's collections and add a copy of the document to each collection + for (const collection of DocListCast(keywordCollection.collections)) { + const newEmbedding = Doc.MakeEmbedding(this._props.doc); + collection[DocData].data = new List([...DocListCast(collection.data), newEmbedding]); + newEmbedding.embedContainer = collection; + } + this._currentInput = ''; // Clear the input box } }; @@ -120,19 +223,35 @@ export class KeywordBox extends ObservableReactComponent { if (SnappingManager.IsDragging || !(seldoc === this._props.doc) || !this._props.isEditing) { setTimeout( action(() => { - if ((keywordsList as List).length === 0) { - this._props.doc[DocData].showLabels = false; - } + // if ((keywordsList as List).length === 0) { + // this._props.doc[DocData].showLabels = false; + // } this.setToView(); }) ); } return ( -
+
- {(keywordsList as List).map(label => { - return ; + {(keywordsList as List).map(keyword => { + return ( + + ); })}
{this._props.isEditing ? ( diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss index 7cc06f922..4267762aa 100644 --- a/src/client/views/StyleProvider.scss +++ b/src/client/views/StyleProvider.scss @@ -58,7 +58,6 @@ display: flex; flex-wrap: wrap; flex-direction: column; - padding-bottom: 4px; border: 1px solid; border-radius: 4px; } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index e250d7a90..26528b2b3 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -1,4 +1,4 @@ -import { action, computed, makeObservable, observable } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import * as React from 'react'; import * as rp from 'request-promise'; import { ClientUtils, returnFalse } from '../../../ClientUtils'; @@ -9,7 +9,7 @@ import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; -import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types'; +import { BoolCast, Cast, DocCast, ScriptCast, StrCast } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 5c304b4a9..a750b731a 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -34,6 +34,7 @@ import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMul import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { CollectionSchemaView } from './collectionSchema/CollectionSchemaView'; import { CollectionCardView } from './CollectionCardDeckView'; +import { DocData } from '../../../fields/DocSymbols'; @observer export class CollectionView extends ViewBoxAnnotatableComponent() { diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index fec4d3e12..af01d6cbc 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -238,14 +238,14 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { if (this._selectedImages.length === 0) { return ( -
this.createDropTarget(ele)}> +
this.createDropTarget(ele!)}>

In order to classify and sort images, marquee select the desired images and press the 'Classify and Sort Images' button. Then, add the desired groups for the images to be put in.

); } return ( -
this.createDropTarget(ele)}> +
this.createDropTarget(ele!)}>
Date: Thu, 18 Jul 2024 15:31:13 -0400 Subject: starting to remove anys --- src/ClientUtils.ts | 14 +++++++++---- src/client/util/DocumentManager.ts | 1 - .../collectionFreeForm/CollectionFreeFormView.tsx | 4 ++-- .../views/nodes/CollectionFreeFormDocumentView.tsx | 6 +++--- src/client/views/nodes/DocumentView.tsx | 24 +++++++++++----------- src/client/views/nodes/FieldView.tsx | 6 +++--- .../views/nodes/formattedText/FormattedTextBox.tsx | 4 ++-- 7 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts index 630d7edbc..b890e7bfc 100644 --- a/src/ClientUtils.ts +++ b/src/ClientUtils.ts @@ -479,10 +479,16 @@ export function clearStyleSheetRules(sheet: CSSStyleSheet|null) { return false; } +export class simPointerEvent extends PointerEvent { + dash?: boolean; +} +export class simMouseEvent extends MouseEvent { + dash?: boolean; +} export function simulateMouseClick(element: Element | null | undefined, x: number, y: number, sx: number, sy: number, rightClick = true) { if (!element) return; ['pointerdown', 'pointerup'].forEach(event => { - const me = new PointerEvent(event, { + const me = new simPointerEvent(event, { view: window, bubbles: true, cancelable: true, @@ -493,12 +499,12 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe screenX: sx, screenY: sy, }); - (me as any).dash = true; + me.dash = true; element.dispatchEvent(me); }); if (rightClick) { - const me = new MouseEvent('contextmenu', { + const me = new simMouseEvent('contextmenu', { view: window, bubbles: true, cancelable: true, @@ -510,7 +516,7 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe screenX: sx, screenY: sy, }); - (me as any).dash = true; + me.dash = true; element.dispatchEvent(me); } } diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 96b8b5657..e41546d09 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -356,7 +356,6 @@ export class DocumentManager { if (options.playMedia) docView.ComponentView?.playFrom?.(NumCast(docView.Document._layout_currentTimecode)); if (options.playAudio) DocumentManager.playAudioAnno(docView.Document); if (options.toggleTarget && (!options.didMove || docView.Document.hidden)) docView.Document.hidden = !docView.Document.hidden; - Doc.AddUnHighlightWatcher(() => docView.Document[Animation] = undefined); } } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5b7f09be3..812aa5fa3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -83,7 +83,7 @@ export class CollectionFreeFormView extends CollectionSubView(); public static from(dv?: DocumentView): CollectionFreeFormView | undefined { - const parent = CollectionFreeFormDocumentView.from(dv)?._props.parent; + const parent = CollectionFreeFormDocumentView.from(dv)?._props.reactParent; return parent instanceof CollectionFreeFormView ? parent : undefined; } @@ -1488,7 +1488,7 @@ export class CollectionFreeFormView extends CollectionSubView boolean; isAnyChildContentActive: () => boolean; - parent: any; + reactParent: React.Component; } @observer export class CollectionFreeFormDocumentView extends DocComponent() { @@ -71,7 +71,7 @@ export class CollectionFreeFormDocumentView extends DocComponent (Doc.LayoutFieldKey(doc) ? [Doc.LayoutFieldKey(doc)] : []); // fields that are configured to be animatable using animation frames public static from(dv?: DocumentView): CollectionFreeFormDocumentView | undefined { - return dv?._props.parent instanceof CollectionFreeFormDocumentView ? dv._props.parent : undefined; + return dv?._props.reactParent instanceof CollectionFreeFormDocumentView ? dv._props.reactParent : undefined; } constructor(props: CollectionFreeFormDocumentViewProps & freeFormProps) { @@ -304,7 +304,7 @@ export class CollectionFreeFormDocumentView extends DocComponent val.lower)).omit} // prettier-ignore - parent={this} + reactParent={this} DataTransition={this.DataTransition} LocalRotation={this.localRotation} CollectionFreeFormDocumentView={this.returnThis} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ce7cfa5f4..5bb12d890 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -7,7 +7,7 @@ import { IReactionDisposer, action, computed, makeObservable, observable, reacti import { observer } from 'mobx-react'; import * as React from 'react'; import { Fade, JackInTheBox } from 'react-awesome-reveal'; -import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnFalse, returnVal, simulateMouseClick } from '../../../ClientUtils'; +import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnFalse, returnVal, simMouseEvent, simulateMouseClick } from '../../../ClientUtils'; import { Utils, emptyFunction } from '../../../Utils'; import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../fields/Doc'; import { AclAdmin, AclEdit, AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols'; @@ -89,7 +89,7 @@ export interface DocumentViewProps extends FieldViewSharedProps { dragStarting?: () => void; dragEnding?: () => void; - parent?: any; // parent React component view (see CollectionFreeFormDocumentView) + reactParent?: React.Component; // parent React component view (see CollectionFreeFormDocumentView) } @observer export class DocumentViewInternal extends DocComponent() { @@ -105,7 +105,7 @@ export class DocumentViewInternal extends DocComponent any); + private _singleClickFunc: undefined | (() => void); private _longPressSelector: NodeJS.Timeout | undefined; private _downX: number = 0; private _downY: number = 0; @@ -224,7 +224,7 @@ export class DocumentViewInternal extends DocComponent this.style(this.Document, StyleProp.PointerEvents), + () => this.style(this.Document, StyleProp.PointerEvents) as ("all" | "none" | "visiblePainted" | undefined), pointerevents => { this._pointerEvents = pointerevents; }, @@ -450,7 +450,7 @@ export class DocumentViewInternal extends DocComponent { if (this.Document.type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && this._props.select(false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. setTimeout(() => simulateMouseClick(document.elementFromPoint(e.clientX, e.clientY), e.clientX, e.clientY, e.screenX, e.screenY)); @@ -710,7 +710,7 @@ export class DocumentViewInternal extends DocComponent this._rootSelected; - panelHeight = () => this._props.PanelHeight() - this.headerMargin; + panelHeight = () => this._props.PanelHeight() - Number(this.headerMargin); screenToLocalContent = () => this._props.ScreenToLocalTransform().translate(0, -this.headerMargin); onClickFunc = this.disableClickScriptFunc ? undefined : () => this.onClickHdlr; setHeight = (height: number) => { !this._props.suppressSetHeight && (this.layoutDoc._height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), height)); } // prettier-ignore @@ -722,7 +722,7 @@ export class DocumentViewInternal extends DocComponent this._props.PanelWidth() || 1; anchorPanelHeight = () => this._props.PanelHeight() || 1; - anchorStyleProvider = (doc: Opt, props: Opt, property: string): any => { + anchorStyleProvider = (doc: Opt, props: Opt, property: string) => { // prettier-ignore switch (property.split(':')[0]) { case StyleProp.ShowTitle: return ''; @@ -770,7 +770,7 @@ export class DocumentViewInternal extends DocComponent, props: Opt, property: string) => this._props?.styleProvider?.(doc, props, property + ':caption'); fieldsDropdown = (placeholder: string) => (
{ r && (this._titleDropDownInnerWidth = DivWidth(r));} )} // prettier-ignore + ref=r => { r && runInAction(() => (this._titleDropDownInnerWidth = DivWidth(r);}) )} // prettier-ignore onPointerDown={action(() => { this._changingTitleField = true; })} // prettier-ignore style={{ width: 'max-content', background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor, transformOrigin: 'left', transform: `scale(${this.titleHeight / 30 /* height of Dropdown */})` }}> () {
{DocumentViewInternal.AnimationEffect(
- console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this._htmlOverlayText)} /> + console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this._htmlOverlayText)} />
, { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Expand } as any as Doc, this.Document @@ -1461,7 +1461,7 @@ export class DocumentView extends DocComponent() { }}> Opt; // eslint-disable-next-line no-use-before-define -export type StyleProviderFuncType = (doc: Opt, props: Opt, property: string) => any; +export type StyleProviderFuncType = (doc: Opt, props: Opt, property: string) => Opt |{ clipPath: string; jsx: Element; } | JSX.Element | null; // // these properties get assigned through the render() method of the DocumentView when it creates this node. // However, that only happens because the properties are "defined" in the markup for the field view. @@ -45,7 +45,7 @@ export interface FieldViewSharedProps { containerViewPath?: () => DocumentView[]; fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document isGroupActive?: () => string | undefined; // is this document part of a group that is active - setContentViewBox?: (view: ViewBoxInterface) => any; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox + setContentViewBox?: (view: ViewBoxInterface) => any; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox PanelWidth: () => number; PanelHeight: () => number; isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 5b435e44a..b0c6120d4 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -14,7 +14,7 @@ import { EditorState, NodeSelection, Plugin, Selection, TextSelection, Transacti import { EditorView, NodeViewConstructor } from 'prosemirror-view'; import * as React from 'react'; import { BsMarkdownFill } from 'react-icons/bs'; -import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, StopEvent } from '../../../../ClientUtils'; +import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, returnFalse, returnZero, setupMoveUpEvents, simMouseEvent, smoothScroll, StopEvent } from '../../../../ClientUtils'; import { DateField } from '../../../../fields/DateField'; import { CreateLinkToActiveAudio, Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, DocData, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols'; @@ -821,7 +821,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent node that wraps the hyerlink while (target && !target.dataset?.targethrefs) target = target.parentElement; const editor = this._editorView; - if (editor && target && !(e.nativeEvent as any).dash) { + if (editor && target && !(e.nativeEvent instanceof simMouseEvent ? e.nativeEvent.dash : false)) { const hrefs = (target.dataset?.targethrefs as string) ?.trim() .split(' ') -- cgit v1.2.3-70-g09d2 From ef83179eacbd9cd7296683e9e07b426da18c0647 Mon Sep 17 00:00:00 2001 From: geireann Date: Thu, 18 Jul 2024 15:32:23 -0400 Subject: from last --- src/client/views/StyleProvider.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 8c100f238..618f69221 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -72,7 +72,7 @@ export function SetFilterOpener(func: () => void) { // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // -export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { +export function DefaultStyleProvider(doc: Opt, props: Opt, property: string) { const remoteDocHeader = 'author;author_date;noMargin'; const isCaption = property.includes(':caption'); const isAnchor = property.includes(':anchor'); @@ -110,9 +110,9 @@ export function DefaultStyleProvider(doc: Opt, props: Opt doc && BoolCast(doc._lockedPosition); const titleHeight = () => styleProvider?.(doc, props, StyleProp.TitleHeight); const backgroundCol = () => styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1)); - const color = () => styleProvider?.(doc, props, StyleProp.Color); + const color = () => styleProvider?.(doc, props, StyleProp.Color) as string; const opacity = () => styleProvider?.(doc, props, StyleProp.Opacity); - const layoutShowTitle = () => styleProvider?.(doc, props, StyleProp.ShowTitle); + const layoutShowTitle = () => styleProvider?.(doc, props, StyleProp.ShowTitle) as string; // prettier-ignore switch (property.split(':')[0]) { case StyleProp.TreeViewIcon: { @@ -152,7 +152,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt, props: Opt, props: Opt Date: Thu, 18 Jul 2024 15:32:40 -0400 Subject: from last --- src/client/views/nodes/DocumentView.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 5bb12d890..24cb4ccf6 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -134,15 +134,15 @@ export class DocumentViewInternal extends DocComponent this._animateScaleTime ?? 100; style = (doc: Doc, sprop: StyleProp | string) => this._props.styleProvider?.(doc, this._props, sprop); - @computed get opacity() { return this.style(this.layoutDoc, StyleProp.Opacity); } // prettier-ignore + @computed get opacity() { return this.style(this.layoutDoc, StyleProp.Opacity) as number; } // prettier-ignore @computed get boxShadow() { return this.style(this.layoutDoc, StyleProp.BoxShadow); } // prettier-ignore @computed get borderRounding() { return this.style(this.layoutDoc, StyleProp.BorderRounding); } // prettier-ignore - @computed get widgetDecorations() { return this.style(this.layoutDoc, StyleProp.Decorations); } // prettier-ignore - @computed get backgroundBoxColor(){ return this.style(this.layoutDoc, StyleProp.BackgroundColor + ':docView'); } // prettier-ignore + @computed get widgetDecorations() { return this.style(this.layoutDoc, StyleProp.Decorations) as JSX.Element; } // prettier-ignore + @computed get backgroundBoxColor(){ return this.style(this.layoutDoc, StyleProp.BackgroundColor + ':docView') as string; } // prettier-ignore @computed get showTitle() { return this.style(this.layoutDoc, StyleProp.ShowTitle) as Opt; } // prettier-ignore - @computed get showCaption() { return this.style(this.layoutDoc, StyleProp.ShowCaption) ?? 0; } // prettier-ignore - @computed get headerMargin() { return this.style(this.layoutDoc, StyleProp.HeaderMargin) ?? 0; } // prettier-ignore - @computed get titleHeight() { return this.style(this.layoutDoc, StyleProp.TitleHeight) ?? 0; } // prettier-ignore + @computed get showCaption() { return this.style(this.layoutDoc, StyleProp.ShowCaption) as string ?? ""; } // prettier-ignore + @computed get headerMargin() { return this.style(this.layoutDoc, StyleProp.HeaderMargin) as number ?? 0; } // prettier-ignore + @computed get titleHeight() { return this.style(this.layoutDoc, StyleProp.TitleHeight) as number ?? 0; } // prettier-ignore @computed get docContents() { return this.style(this.Document, StyleProp.DocContents); } // prettier-ignore @computed get highlighting() { return this.style(this.Document, StyleProp.Highlighting); } // prettier-ignore @computed get borderPath() { return this.style(this.Document, StyleProp.BorderPath); } // prettier-ignore @@ -710,7 +710,7 @@ export class DocumentViewInternal extends DocComponent this._rootSelected; - panelHeight = () => this._props.PanelHeight() - Number(this.headerMargin); + panelHeight = () => this._props.PanelHeight() - this.headerMargin; screenToLocalContent = () => this._props.ScreenToLocalTransform().translate(0, -this.headerMargin); onClickFunc = this.disableClickScriptFunc ? undefined : () => this.onClickHdlr; setHeight = (height: number) => { !this._props.suppressSetHeight && (this.layoutDoc._height = Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), height)); } // prettier-ignore @@ -770,7 +770,7 @@ export class DocumentViewInternal extends DocComponent, props: Opt, property: string) => this._props?.styleProvider?.(doc, props, property + ':caption'); fieldsDropdown = (placeholder: string) => (
{ r && runInAction(() => (this._titleDropDownInnerWidth = DivWidth(r);}) )} // prettier-ignore + ref={r => { r && runInAction(() => (this._titleDropDownInnerWidth = DivWidth(r)));}} // prettier-ignore onPointerDown={action(() => { this._changingTitleField = true; })} // prettier-ignore style={{ width: 'max-content', background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor, transformOrigin: 'left', transform: `scale(${this.titleHeight / 30 /* height of Dropdown */})` }}> Date: Mon, 22 Jul 2024 15:26:27 -0400 Subject: adding type fixes to avoid 'any's --- .env.swo | Bin 0 -> 12288 bytes .eslintrc.json | 2 +- package-lock.json | 1544 ++++++++++---------- package.json | 2 +- src/ClientUtils.ts | 10 +- src/client/views/InkingStroke.tsx | 17 +- src/client/views/StyleProvider.tsx | 3 +- .../views/collections/CollectionCarousel3DView.tsx | 10 +- .../views/collections/CollectionDockingView.tsx | 7 +- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 13 +- src/client/views/collections/TreeView.tsx | 8 +- .../CollectionFreeFormLayoutEngines.tsx | 20 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 77 +- src/client/views/nodes/DocumentView.tsx | 85 +- src/client/views/nodes/FieldView.tsx | 26 +- .../views/nodes/RecordingBox/RecordingView.tsx | 14 +- src/client/views/nodes/ScreenshotBox.tsx | 1 - 18 files changed, 938 insertions(+), 903 deletions(-) create mode 100644 .env.swo diff --git a/.env.swo b/.env.swo new file mode 100644 index 000000000..1a66a7865 Binary files /dev/null and b/.env.swo differ diff --git a/.eslintrc.json b/.eslintrc.json index 2e4da56b8..e0298fd5f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -47,7 +47,7 @@ "no-underscore-dangle": "off", "no-nested-ternary": "off", "lines-between-class-members": "off", - "no-explicit-any": "off", + "no-explicit-any": "on", // Note: you must disable the base rule as it can report incorrect errors "no-shadow": "off", "@typescript-eslint/no-shadow": "warn", diff --git a/package-lock.json b/package-lock.json index f11d8a462..0187d7952 100644 --- a/package-lock.json +++ b/package-lock.json @@ -101,7 +101,7 @@ "express-session": "^1.17.3", "express-validator": "^7.0.1", "extract-colors": "^4.0.2", - "ffmpeg": "0.0.4", + "ffmpeg": "^0.0.4", "file-loader": "^6.2.0", "file-saver": "^2.0.5", "find-in-files": "^0.5.0", @@ -541,9 +541,9 @@ } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.1.tgz", - "integrity": "sha512-ExPSbgjwCoht6kB7B4MeZoBAxcQSIl29r/bPeazZJx50ej4JJCByimLOrZoIsurISNyJQQHf30b3JfqC3Hb88A==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.2.tgz", + "integrity": "sha512-Hnhm/PG9/SQ07JJyLDv3l9Qr8V3xgAe1hFoBYzt6LaalMxfL/ZqFaZf/bz5VN3pMcleCPwl8ivlS2Fjxq/iC8Q==", "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-auth": "^1.4.0", @@ -581,9 +581,9 @@ } }, "node_modules/@azure/core-util": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.0.tgz", - "integrity": "sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.1.tgz", + "integrity": "sha512-OLsq0etbHO1MA7j6FouXFghuHrAFGk+5C1imcpQ2e+0oZhYF07WLA+NW2Vqs70R7d+zOAWiWM3tbE1sXcDN66g==", "dependencies": { "@azure/abort-controller": "^2.0.0", "tslib": "^2.6.2" @@ -616,9 +616,9 @@ } }, "node_modules/@azure/logger": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.2.tgz", - "integrity": "sha512-l170uE7bsKpIU6B/giRc9i4NI0Mj+tANMMMxf7Zi/5cKzEqPayP7+X1WPrG7e+91JgY8N+7K7nF2WOi7iVhXvg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.3.tgz", + "integrity": "sha512-J8/cIKNQB1Fc9fuYqBVnrppiUtW+5WWJPCj/tAokC5LdSTwkWWttN+jsRgw9BLYD7JDBx7PceiqOBxJJ1tQz3Q==", "dependencies": { "tslib": "^2.6.2" }, @@ -662,29 +662,29 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", + "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", + "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", + "@babel/generator": "^7.24.9", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-module-transforms": "^7.24.9", + "@babel/helpers": "^7.24.8", + "@babel/parser": "^7.24.8", "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -700,11 +700,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.24.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", + "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", "dependencies": { - "@babel/types": "^7.24.7", + "@babel/types": "^7.24.9", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -737,13 +737,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -752,14 +752,14 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.8.tgz", + "integrity": "sha512-4f6Oqnmyp2PP3olgUMmOwC3akxSm5aBYraQ6YDdKy7NcAMkDECHWG0DEnV6M2UAkERgIBhYt8S27rURPg7SxWA==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", "@babel/helper-optimise-call-expression": "^7.24.7", "@babel/helper-replace-supers": "^7.24.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", @@ -839,12 +839,12 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -863,9 +863,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", + "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", @@ -892,9 +892,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "engines": { "node": ">=6.9.0" } @@ -967,9 +967,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "engines": { "node": ">=6.9.0" } @@ -983,9 +983,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "engines": { "node": ">=6.9.0" } @@ -1005,13 +1005,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", + "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", "peer": true, "dependencies": { "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1032,9 +1032,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1451,15 +1451,15 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.8.tgz", + "integrity": "sha512-VXy91c47uujj758ud9wx+OMgheXm4qJfyhj1P18YvlrQkNOSrwsteHk+EFS3OMGfhMhpZa0A+81eE7G4QC+3CA==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.8", "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-replace-supers": "^7.24.7", "@babel/helper-split-export-declaration": "^7.24.7", "globals": "^11.1.0" @@ -1495,11 +1495,11 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1687,12 +1687,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-simple-access": "^7.24.7" }, "engines": { @@ -1841,11 +1841,11 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, @@ -2064,11 +2064,11 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -2137,14 +2137,14 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", - "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.8.tgz", + "integrity": "sha512-vObvMZB6hNWuDxhSaEPTKCwcqkAIuDtE+bQGn4XMXne1DSLzFVY8Vmj1bm+mUQXYNN8NmaQEO+r8MMbzPr1jBQ==", + "dependencies": { + "@babel/compat-data": "^7.24.8", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", @@ -2175,9 +2175,9 @@ "@babel/plugin-transform-block-scoping": "^7.24.7", "@babel/plugin-transform-class-properties": "^7.24.7", "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.7", + "@babel/plugin-transform-classes": "^7.24.8", "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-dotall-regex": "^7.24.7", "@babel/plugin-transform-duplicate-keys": "^7.24.7", "@babel/plugin-transform-dynamic-import": "^7.24.7", @@ -2190,7 +2190,7 @@ "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", "@babel/plugin-transform-member-expression-literals": "^7.24.7", "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-modules-systemjs": "^7.24.7", "@babel/plugin-transform-modules-umd": "^7.24.7", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", @@ -2200,7 +2200,7 @@ "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-object-super": "^7.24.7", "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", @@ -2211,7 +2211,7 @@ "@babel/plugin-transform-spread": "^7.24.7", "@babel/plugin-transform-sticky-regex": "^7.24.7", "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", "@babel/plugin-transform-unicode-escapes": "^7.24.7", "@babel/plugin-transform-unicode-property-regex": "^7.24.7", "@babel/plugin-transform-unicode-regex": "^7.24.7", @@ -2220,7 +2220,7 @@ "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.4", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", + "core-js-compat": "^3.37.1", "semver": "^6.3.1" }, "engines": { @@ -2268,9 +2268,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2279,9 +2279,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.7.tgz", - "integrity": "sha512-eytSX6JLBY6PVAeQa2bFlDx/7Mmln/gaEpsit5a3WEvjGfiIytEsgAwuIXCPM0xvw0v0cJn3ilq0/TvXrW0kgA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.8.tgz", + "integrity": "sha512-DXG/BhegtMHhnN7YPIvxWd303/9aXvYFD1TjNL3CD6tUrhI2LVsg3Lck0aql5TRH29n4sj3emcROypkZVUfSuA==", "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" @@ -2304,18 +2304,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", + "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", + "@babel/generator": "^7.24.8", "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-function-name": "^7.24.7", "@babel/helper-hoist-variables": "^7.24.7", "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/parser": "^7.24.8", + "@babel/types": "^7.24.8", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2332,11 +2332,11 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", + "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -2385,15 +2385,15 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", - "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/serialize": "^1.1.2", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", @@ -2408,47 +2408,47 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/@emotion/cache": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", - "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", - "dependencies": { - "@emotion/memoize": "^0.8.1", - "@emotion/sheet": "^1.2.2", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.0.tgz", + "integrity": "sha512-hPV345J/tH0Cwk2wnU/3PBzORQ9HeX+kQSbwI+jslzpRCHE6fSGTohswksA/Ensr8znPzwfzKZCmAM9Lmlhp7g==", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", "stylis": "4.2.0" } }, "node_modules/@emotion/hash": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", - "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", - "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", + "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", "dependencies": { - "@emotion/memoize": "^0.8.1" + "@emotion/memoize": "^0.9.0" } }, "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" }, "node_modules/@emotion/react": { - "version": "11.11.4", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", - "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", + "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.3", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { @@ -2461,33 +2461,33 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", - "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", + "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", "dependencies": { - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/unitless": "^0.8.1", - "@emotion/utils": "^1.2.1", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.9.0", + "@emotion/utils": "^1.4.0", "csstype": "^3.0.2" } }, "node_modules/@emotion/sheet": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" }, "node_modules/@emotion/styled": { - "version": "11.11.5", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz", - "integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/is-prop-valid": "^1.2.2", - "@emotion/serialize": "^1.1.4", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1" + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" }, "peerDependencies": { "@emotion/react": "^11.0.0-rc.0", @@ -2506,27 +2506,27 @@ "peer": true }, "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", + "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" }, "node_modules/@emotion/weak-memoize": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", @@ -2634,9 +2634,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.6.0.tgz", - "integrity": "sha512-D9B0/3vNg44ZeWbYMpBoXqNP4j6eQD5vNwIlGAuFRRzK/WtT/jvDQW3Bi9kkf3PMDMlM7Yi+73VLUsn5bJcl8A==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", + "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2670,29 +2670,29 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz", - "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", + "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", "dependencies": { - "@floating-ui/utils": "^0.2.4" + "@floating-ui/utils": "^0.2.5" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz", - "integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", + "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", "dependencies": { "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.4" + "@floating-ui/utils": "^0.2.5" } }, "node_modules/@floating-ui/react": { - "version": "0.26.19", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.19.tgz", - "integrity": "sha512-Jk6zITdjjIvjO/VdQFvpRaD3qPwOHH6AoDHxjhpy+oK4KFgaSP871HYWUAPdnLmx1gQ+w/pB312co3tVml+BXA==", + "version": "0.26.20", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.20.tgz", + "integrity": "sha512-RixKJJG92fcIsVoqrFr4Onpzh7hlOx4U7NV4aLhMLmtvjZ5oTB/WzXaANYUZATKqXvvW7t9sCxtzejip26N5Ag==", "dependencies": { "@floating-ui/react-dom": "^2.1.1", - "@floating-ui/utils": "^0.2.4", + "@floating-ui/utils": "^0.2.5", "tabbable": "^6.0.0" }, "peerDependencies": { @@ -2713,9 +2713,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", - "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", + "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" }, "node_modules/@formatjs/ecma402-abstract": { "version": "2.0.0", @@ -2762,57 +2762,52 @@ } }, "node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz", - "integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==", - "hasInstallScript": true, + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz", + "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==", "engines": { "node": ">=6" } }, "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz", - "integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==", - "hasInstallScript": true, + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz", + "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.5.2" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-brands-svg-icons": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.2.tgz", - "integrity": "sha512-zi5FNYdmKLnEc0jc0uuHH17kz/hfYTg4Uei0wMGzcoCL/4d3WM3u1VMc0iGGa31HuhV5i7ZK8ZlTCQrHqRHSGQ==", - "hasInstallScript": true, + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz", + "integrity": "sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ==", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.5.2" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-regular-svg-icons": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz", - "integrity": "sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw==", - "hasInstallScript": true, + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.6.0.tgz", + "integrity": "sha512-Yv9hDzL4aI73BEwSEh20clrY8q/uLxawaQ98lekBx6t9dQKDHcDzzV1p2YtBGTtolYtNqcWdniOnhzB+JPnQEQ==", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.5.2" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-solid-svg-icons": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz", - "integrity": "sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==", - "hasInstallScript": true, + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz", + "integrity": "sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA==", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.5.2" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { "node": ">=6" @@ -2831,30 +2826,30 @@ } }, "node_modules/@fullcalendar/core": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.14.tgz", - "integrity": "sha512-hIPRBevm0aMc2aHy1hRIJgXmI1QTvQM1neQa9oxtuqUmF1+ApYC3oAdwcQMTuI7lHHw3pKJDyJFkKLPPnL6HXA==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.15.tgz", + "integrity": "sha512-BuX7o6ALpLb84cMw1FCB9/cSgF4JbVO894cjJZ6kP74jzbUZNjtwffwRdA+Id8rrLjT30d/7TrkW90k4zbXB5Q==", "dependencies": { "preact": "~10.12.1" } }, "node_modules/@fullcalendar/daygrid": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.14.tgz", - "integrity": "sha512-DSyjiA1dEM8k3bOCrZpZOmAOZu71KGtH02ze+4QKuhxkmn/zQghmmLRdfzpOrcyJg6xGKkoB4pBcO+2lXar8XQ==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.15.tgz", + "integrity": "sha512-j8tL0HhfiVsdtOCLfzK2J0RtSkiad3BYYemwQKq512cx6btz6ZZ2RNc/hVnIxluuWFyvx5sXZwoeTJsFSFTEFA==", "peerDependencies": { - "@fullcalendar/core": "~6.1.14" + "@fullcalendar/core": "~6.1.15" } }, "node_modules/@fullcalendar/multimonth": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/@fullcalendar/multimonth/-/multimonth-6.1.14.tgz", - "integrity": "sha512-el2vbZZgTkdufgOvRxqx61czjRMfEK50449g4SkqbagtS3ITNMAv84KHFcsbXVbd9Nh3UhbXDuYZuzJZpvY7mQ==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@fullcalendar/multimonth/-/multimonth-6.1.15.tgz", + "integrity": "sha512-sEZY6jbOYkeF9TwhUldG+UUVv+hiPlGkS8zZEgPR7ypcjhipyA03c5rPjx7N6huOHqh6lCMH59zlohLooQRlaw==", "dependencies": { - "@fullcalendar/daygrid": "~6.1.14" + "@fullcalendar/daygrid": "~6.1.15" }, "peerDependencies": { - "@fullcalendar/core": "~6.1.14" + "@fullcalendar/core": "~6.1.15" } }, "node_modules/@googlemaps/js-api-loader": { @@ -3717,9 +3712,9 @@ } }, "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -3777,57 +3772,26 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz", - "integrity": "sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz", + "integrity": "sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==", "dependencies": { "sparse-bitfield": "^3.0.3" } }, - "node_modules/@mui/base": { - "version": "5.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", - "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@floating-ui/react-dom": "^2.0.8", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.15.14", - "@popperjs/core": "^2.11.8", - "clsx": "^2.1.0", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.0.tgz", - "integrity": "sha512-8SLffXYPRVpcZx5QzxNE8fytTqzp+IuU3deZbQWg/vSaTlDpR5YVrQ4qQtXTi5cRdhOufV5INylmwlKK+//nPw==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.4.tgz", + "integrity": "sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.0.tgz", - "integrity": "sha512-6ISoOhkp9w5gD0PEW9JklrcbyARDkFWNTBdwXZ1Oy5IGlyu9B0zG0hnUIe4H17IaF1Vgj6C8VI+v4tkSdK0veg==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.4.tgz", + "integrity": "sha512-j9/CWctv6TH6Dou2uR2EH7UOgu79CW/YcozxCYVLJ7l03pCsiOlJ5sBArnWJxJ+nGkFwyL/1d1k8JEPMDR125A==", "dependencies": { "@babel/runtime": "^7.23.9" }, @@ -3850,21 +3814,21 @@ } }, "node_modules/@mui/material": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.0.tgz", - "integrity": "sha512-DbR1NckTLpjt9Zut9EGQ70th86HfN0BYQgyYro6aXQrNfjzSwe3BJS1AyBQ5mJ7TdL6YVRqohfukxj9JlqZZUg==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.4.tgz", + "integrity": "sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.40", - "@mui/core-downloads-tracker": "^5.16.0", - "@mui/system": "^5.16.0", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.16.0", + "@mui/core-downloads-tracker": "^5.16.4", + "@mui/system": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", + "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.0", "csstype": "^3.1.3", "prop-types": "^15.8.1", - "react-is": "^18.2.0", + "react-is": "^18.3.1", "react-transition-group": "^4.4.5" }, "engines": { @@ -3894,12 +3858,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.0.tgz", - "integrity": "sha512-sYpubkO1MZOnxNyVOClrPNOTs0MfuRVVnAvCeMaOaXt6GimgQbnUcshYv2pSr6PFj+Mqzdff/FYOBceK8u5QgA==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz", + "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.16.0", + "@mui/utils": "^5.16.4", "prop-types": "^15.8.1" }, "engines": { @@ -3920,9 +3884,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.15.14", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", - "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", + "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", "dependencies": { "@babel/runtime": "^7.23.9", "@emotion/cache": "^11.11.0", @@ -3951,15 +3915,15 @@ } }, "node_modules/@mui/system": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.0.tgz", - "integrity": "sha512-9YbkC2m3+pNumAvubYv+ijLtog6puJ0fJ6rYfzfLCM47pWrw3m+30nXNM8zMgDaKL6vpfWJcCXm+LPaWBpy7sw==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz", + "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.16.0", - "@mui/styled-engine": "^5.15.14", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.16.0", + "@mui/private-theming": "^5.16.4", + "@mui/styled-engine": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", "clsx": "^2.1.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -3990,9 +3954,9 @@ } }, "node_modules/@mui/types": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", - "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", + "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0" }, @@ -4003,14 +3967,15 @@ } }, "node_modules/@mui/utils": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.0.tgz", - "integrity": "sha512-kLLi5J1xY+mwtUlMb8Ubdxf4qFAA1+U7WPBvjM/qQ4CIwLCohNb0sHo1oYPufjSIH/Z9+dhVxD7dJlfGjd1AVA==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", + "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", "dependencies": { "@babel/runtime": "^7.23.9", - "@types/prop-types": "^15.7.11", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "react-is": "^18.3.1" }, "engines": { "node": ">=12.0.0" @@ -4117,9 +4082,9 @@ "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" }, "node_modules/@octokit/request": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.1.tgz", - "integrity": "sha512-pyAguc0p+f+GbQho0uNetNQMmLG1e80WjkIaqqgUkihqUp0boRU6nKItXO4VWnr+nbZiLGEyy4TeKRwqaLvYgw==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.3.tgz", + "integrity": "sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==", "dependencies": { "@octokit/endpoint": "^10.0.0", "@octokit/request-error": "^6.0.1", @@ -4131,9 +4096,9 @@ } }, "node_modules/@octokit/request-error": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.1.tgz", - "integrity": "sha512-1mw1gqT3fR/WFvnoVpY/zUM2o/XkMs/2AszUUG9I69xn0JFLv6PGkPhNk5lbfvROs79wiS0bqiJNxfCZcRJJdg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.4.tgz", + "integrity": "sha512-VpAhIUxwhWZQImo/dWAN/NpPqqojR6PSLgLYAituLM6U+ddx9hCioFGwBr5Mi+oi5CLeJkcAs3gJ0PYYzU6wUg==", "dependencies": { "@octokit/types": "^13.0.0" }, @@ -6150,25 +6115,25 @@ } }, "node_modules/@react-spring/animated": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz", - "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==", + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.4.tgz", + "integrity": "sha512-7As+8Pty2QlemJ9O5ecsuPKjmO0NKvmVkRR1n6mEotFgWar8FKuQt2xgxz3RTgxcccghpx1YdS1FCdElQNexmQ==", "dependencies": { - "@react-spring/shared": "~9.7.3", - "@react-spring/types": "~9.7.3" + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/@react-spring/core": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz", - "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==", + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.4.tgz", + "integrity": "sha512-GzjA44niEJBFUe9jN3zubRDDDP2E4tBlhNlSIkTChiNf9p4ZQlgXBg50qbXfSXHQPHak/ExYxwhipKVsQ/sUTw==", "dependencies": { - "@react-spring/animated": "~9.7.3", - "@react-spring/shared": "~9.7.3", - "@react-spring/types": "~9.7.3" + "@react-spring/animated": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" }, "funding": { "type": "opencollective", @@ -6178,31 +6143,37 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@react-spring/rafz": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.4.tgz", + "integrity": "sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==" + }, "node_modules/@react-spring/shared": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz", - "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==", + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.4.tgz", + "integrity": "sha512-bEPI7cQp94dOtCFSEYpxvLxj0+xQfB5r9Ru1h8OMycsIq7zFZon1G0sHrBLaLQIWeMCllc4tVDYRTLIRv70C8w==", "dependencies": { - "@react-spring/types": "~9.7.3" + "@react-spring/rafz": "~9.7.4", + "@react-spring/types": "~9.7.4" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/@react-spring/types": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz", - "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw==" + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.4.tgz", + "integrity": "sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==" }, "node_modules/@react-spring/web": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz", - "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==", + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.4.tgz", + "integrity": "sha512-UMvCZp7I5HCVIleSa4BwbNxynqvj+mJjG2m20VO2yPoi2pnCYANy58flvz9v/YcXTAvsmL655FV3pm5fbr6akA==", "dependencies": { - "@react-spring/animated": "~9.7.3", - "@react-spring/core": "~9.7.3", - "@react-spring/shared": "~9.7.3", - "@react-spring/types": "~9.7.3" + "@react-spring/animated": "~9.7.4", + "@react-spring/core": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0", @@ -7169,9 +7140,9 @@ } }, "node_modules/@swc/helpers": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.11.tgz", - "integrity": "sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==", + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.12.tgz", + "integrity": "sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==", "dependencies": { "tslib": "^2.4.0" } @@ -8025,25 +7996,6 @@ "url": "https://opencollective.com/turf" } }, - "node_modules/@turf/line-overlap/node_modules/deep-equal": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz", - "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", - "dependencies": { - "is-arguments": "^1.1.1", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.5.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/@turf/line-segment": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@turf/line-segment/-/line-segment-6.5.0.tgz", @@ -9448,11 +9400,26 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.6", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.6.tgz", - "integrity": "sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==", + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", "dev": true }, + "node_modules/@types/mapbox__point-geometry": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", + "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==" + }, + "node_modules/@types/mapbox__vector-tile": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", + "dependencies": { + "@types/geojson": "*", + "@types/mapbox__point-geometry": "*", + "@types/pbf": "*" + } + }, "node_modules/@types/mapbox-gl": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.1.0.tgz", @@ -9493,9 +9460,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", "dependencies": { "undici-types": "~5.26.4" } @@ -9593,6 +9560,11 @@ "@types/passport": "*" } }, + "node_modules/@types/pbf": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==" + }, "node_modules/@types/pdf-parse": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/pdf-parse/-/pdf-parse-1.1.4.tgz", @@ -9915,9 +9887,9 @@ } }, "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "version": "8.5.11", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", + "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", "dev": true, "dependencies": { "@types/node": "*" @@ -9943,16 +9915,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz", - "integrity": "sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/type-utils": "7.16.0", - "@typescript-eslint/utils": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -9976,14 +9948,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz", - "integrity": "sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==", - "dependencies": { - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", + "dependencies": { + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "engines": { @@ -10003,12 +9975,12 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", - "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -10019,13 +9991,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz", - "integrity": "sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.0", - "@typescript-eslint/utils": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -10046,9 +10018,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", "engines": { "node": "^18.18.0 || >=20.0.0" }, @@ -10058,12 +10030,12 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -10085,9 +10057,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -10096,15 +10068,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", - "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0" + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -10118,11 +10090,11 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", "dependencies": { - "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/types": "7.16.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -10139,55 +10111,55 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@vue/compiler-core": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.31.tgz", - "integrity": "sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.33.tgz", + "integrity": "sha512-MoIREbkdPQlnGfSKDMgzTqzqx5nmEjIc0ydLVYlTACGBsfvOJ4tHSbZXKVF536n6fB+0eZaGEOqsGThPpdvF5A==", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/shared": "3.4.31", + "@vue/shared": "3.4.33", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.31.tgz", - "integrity": "sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.33.tgz", + "integrity": "sha512-GzB8fxEHKw0gGet5BKlpfXEqoBnzSVWwMnT+dc25wE7pFEfrU/QsvjZMP9rD4iVXHBBoemTct8mN0GJEI6ZX5A==", "dependencies": { - "@vue/compiler-core": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/compiler-core": "3.4.33", + "@vue/shared": "3.4.33" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.31.tgz", - "integrity": "sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.33.tgz", + "integrity": "sha512-7rk7Vbkn21xMwIUpHQR4hCVejwE6nvhBOiDgoBcR03qvGqRKA7dCBSsHZhwhYUsmjlbJ7OtD5UFIyhP6BY+c8A==", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/compiler-core": "3.4.31", - "@vue/compiler-dom": "3.4.31", - "@vue/compiler-ssr": "3.4.31", - "@vue/shared": "3.4.31", + "@vue/compiler-core": "3.4.33", + "@vue/compiler-dom": "3.4.33", + "@vue/compiler-ssr": "3.4.33", + "@vue/shared": "3.4.33", "estree-walker": "^2.0.2", "magic-string": "^0.30.10", - "postcss": "^8.4.38", + "postcss": "^8.4.39", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.31.tgz", - "integrity": "sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.33.tgz", + "integrity": "sha512-0WveC9Ai+eT/1b6LCV5IfsufBZ0HP7pSSTdDjcuW302tTEgoBw8rHVHKPbGUtzGReUFCRXbv6zQDDgucnV2WzQ==", "dependencies": { - "@vue/compiler-dom": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/compiler-dom": "3.4.33", + "@vue/shared": "3.4.33" } }, "node_modules/@vue/shared": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.31.tgz", - "integrity": "sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==" + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.33.tgz", + "integrity": "sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA==" }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", @@ -10519,14 +10491,14 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -10736,6 +10708,38 @@ "deep-equal": "^2.0.5" } }, + "node_modules/aria-query/node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", @@ -10888,18 +10892,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, "node_modules/array.prototype.tosorted": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", @@ -11080,6 +11072,38 @@ "deep-equal": "^2.0.5" } }, + "node_modules/axobject-query/node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/b4a": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", @@ -11620,6 +11644,13 @@ "which", "write-file-atomic" ], + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^6.5.0", @@ -13529,19 +13560,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/readable-stream": { - "version": "3.6.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/signal-exit": { "version": "3.0.7", "inBundle": true, @@ -13987,6 +14005,19 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/browndash-components/node_modules/npm/node_modules/readable-stream": { + "version": "3.6.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/browndash-components/node_modules/npm/node_modules/retry": { "version": "0.12.0", "inBundle": true, @@ -14872,9 +14903,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001641", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz", - "integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==", + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", "funding": [ { "type": "opencollective", @@ -15559,6 +15590,11 @@ "tinyqueue": "^2.0.3" } }, + "node_modules/concaveman/node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + }, "node_modules/concaveman/node_modules/rbush": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", @@ -15887,9 +15923,9 @@ } }, "node_modules/css-loader/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -16061,9 +16097,9 @@ "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==" }, "node_modules/cytoscape": { - "version": "3.30.0", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.0.tgz", - "integrity": "sha512-l590mjTHT6/Cbxp13dGPC2Y7VXdgc+rUeF8AnF/JPzhjNevbDJfObnJgaSjlldOgBQZbue+X6IUZ7r5GAgvauQ==", + "version": "3.30.1", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.1.tgz", + "integrity": "sha512-TRJc3HbBPkHd50u9YfJh2FxD1lDLZ+JXnJoyBn5LkncoeuT7fapO/Hq/Ed8TdFclaKshzInge2i30bg7VKeoPQ==", "engines": { "node": ">=0.10" } @@ -16627,9 +16663,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" + "version": "1.11.12", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz", + "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==" }, "node_modules/debug": { "version": "4.3.5", @@ -16725,29 +16761,16 @@ } }, "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz", + "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", "is-date-object": "^1.0.5", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", "object-is": "^1.1.5", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" + "regexp.prototype.flags": "^1.5.1" }, "engines": { "node": ">= 0.4" @@ -16951,9 +16974,9 @@ } }, "node_modules/depcheck/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -17226,9 +17249,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.823", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.823.tgz", - "integrity": "sha512-4h+oPeAiGQOHFyUJOqpoEcPj/xxlicxBzOErVeYVMMmAiXUXsGpsFd0QXBMaUUbnD8hhSfLf9uw+MlsoIA7j5w==" + "version": "1.4.832", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.832.tgz", + "integrity": "sha512-cTen3SB0H2SGU7x467NRe1eVcQgcuS6jckKfWJHia2eo0cHIGOqHoAxevIYZD4eRHcWjkvFzo93bi3vJ9W+1lA==" }, "node_modules/elkjs": { "version": "0.9.3", @@ -17309,9 +17332,9 @@ } }, "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "engines": { "node": ">=10.0.0" } @@ -18828,13 +18851,13 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" + "synckit": "^0.9.1" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -18858,35 +18881,35 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", - "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==", + "version": "7.35.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", + "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", "dev": true, "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.8", "object.fromentries": "^2.0.8", - "object.hasown": "^1.1.4", "object.values": "^1.2.0", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11" + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { @@ -19596,6 +19619,11 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" + }, "node_modules/fast-xml-parser": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", @@ -20226,9 +20254,9 @@ } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -20570,25 +20598,6 @@ "deep-equal": "^1.0.0" } }, - "node_modules/geojson-equality/node_modules/deep-equal": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz", - "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", - "dependencies": { - "is-arguments": "^1.1.1", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.5.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/geojson-rbush": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/geojson-rbush/-/geojson-rbush-3.2.0.tgz", @@ -20606,6 +20615,11 @@ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==" }, + "node_modules/geojson-rbush/node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + }, "node_modules/geojson-rbush/node_modules/rbush": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", @@ -20704,9 +20718,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", - "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", + "integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -21959,8 +21973,7 @@ "node_modules/image-size-stream/node_modules/image-size": { "version": "0.3.5", "resolved": "git+ssh://git@github.com/netroy/image-size.git#da2c863807a3e9602617bdd357b0de3ab4a064c1", - "integrity": "sha512-nF4/PT7i5t72LJKRBAXfM8PCzUDQurOUzPsNUjQDpUhFpLNuCpSY0+XIHNcc/LtoU3GqSCK3wQDU+CCty3Bfcw==", - "license": "MIT", + "integrity": "sha512-bOV/01RFEAMM7OJU4alHoipipEYAdVk1W9rto2aN1ZnEZsZ1A1OCVJJ2iMaaJIKidVXGZNbP9knmW/3wWTZ4/Q==", "bin": { "image-size": "bin/image-size" }, @@ -21995,9 +22008,9 @@ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" }, "node_modules/immutable": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", - "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==" + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==" }, "node_modules/import-fresh": { "version": "3.3.0", @@ -22023,9 +22036,9 @@ } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -22591,9 +22604,9 @@ } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", "dependencies": { "hasown": "^2.0.2" }, @@ -23108,15 +23121,12 @@ } }, "node_modules/jackspeak": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.2.tgz", - "integrity": "sha512-qH3nOSj8q/8+Eg8LUPOq3C+6HWkpUioIjDsq1+D4zY91oZvpPttw8GwtF1nReRYKXl+1AORyFqtm2f5Q1SB6/Q==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": "14 >=14.21 || 16 >=16.20 || >=18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -23356,9 +23366,9 @@ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "node_modules/jsdom": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", - "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", + "version": "24.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz", + "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==", "dev": true, "dependencies": { "cssstyle": "^4.0.1", @@ -23367,11 +23377,11 @@ "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.4", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.10", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.4", @@ -23380,7 +23390,7 @@ "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.17.0", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "engines": { @@ -24175,9 +24185,13 @@ "dev": true }, "node_modules/mapbox-gl": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.5.1.tgz", - "integrity": "sha512-sf4N18vl5FHS8lPRWZjTZShgIziDqSxan3MazHClvYYXezsAPn6hApRvAS2HEMTq7MXzRcvvt4sYgQWLubwnBw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.5.2.tgz", + "integrity": "sha512-KUrmDmLFKPp3MSsWGNTH5uvtYwJknV+eFJ+vxiN6hqKpzbme37z+JfYs5Mehs3CgFaIV/pUdnEV9UPUZJPuS+Q==", + "workspaces": [ + "src/style-spec", + "test/build/typings" + ], "dependencies": { "@mapbox/jsonlint-lines-primitives": "^2.0.2", "@mapbox/mapbox-gl-supported": "^3.0.0", @@ -24186,6 +24200,8 @@ "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^1.3.1", "@mapbox/whoots-js": "^3.1.0", + "@types/geojson": "^7946.0.14", + "@types/mapbox__vector-tile": "^1.3.4", "cheap-ruler": "^4.0.0", "csscolorparser": "~1.0.3", "earcut": "^3.0.0", @@ -24198,12 +24214,12 @@ "murmurhash-js": "^1.0.0", "pbf": "^3.2.1", "potpack": "^2.0.0", - "quickselect": "^2.0.0", + "quickselect": "^3.0.0", "rw": "^1.3.3", "serialize-to-js": "^3.1.2", "supercluster": "^8.0.1", - "tiny-lru": "^11.2.6", - "tinyqueue": "^2.0.3", + "tiny-lru": "^11.2.11", + "tinyqueue": "^3.0.0", "tweakpane": "^4.0.4", "vt-pbf": "^3.1.3" } @@ -24213,6 +24229,11 @@ "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", "integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==" }, + "node_modules/mapbox-gl/node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==" + }, "node_modules/markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -30807,9 +30828,9 @@ "integrity": "sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g==" }, "node_modules/mobx": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.13.0.tgz", - "integrity": "sha512-1laWODrBWmB7mDJ8EClCjUQTyLwJ0ydJgE4FtK7t9r3JnjXgc9OhmYs2P4RtHrY1co5+4T6cKP2UswX2SU29mA==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.13.1.tgz", + "integrity": "sha512-ekLRxgjWJr8hVxj9ZKuClPwM/iHckx3euIJ3Np7zLVNtqJvfbbq7l370W/98C8EabdQ1pB5Jd3BbDWxJPNnaOg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" @@ -30872,9 +30893,9 @@ } }, "node_modules/mocha": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", - "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", + "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", "dev": true, "dependencies": { "ansi-colors": "^4.1.3", @@ -31064,9 +31085,9 @@ } }, "node_modules/mongoose": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.0.tgz", - "integrity": "sha512-iGgZvgO+fIgX1AQMehkG+Wj8qrWc9it8vUZrSKWjrebgfwHTqUcIdTgWK8mT1us1xd83NOQxiuGbg9ZJtLxs2Q==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.1.tgz", + "integrity": "sha512-OhVcwVl91A1G6+XpjDcpkGP7l7ikZkxa0DylX7NT/lcEqAjggzSdqDxb48A+xsDxqNAr0ntSJ1yiE3+KJTOd5Q==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", @@ -31401,9 +31422,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" }, "node_modules/node-stream-zip": { "version": "1.15.0", @@ -31473,9 +31494,9 @@ } }, "node_modules/nodemon/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -31522,9 +31543,9 @@ } }, "node_modules/npm": { - "version": "10.8.1", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.1.tgz", - "integrity": "sha512-Dp1C6SvSMYQI7YHq/y2l94uvI+59Eqbu1EpuKQHQ8p16txXRuRit5gH3Lnaagk2aXDIjg/Iru9pd05bnneKgdw==", + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.2.tgz", + "integrity": "sha512-x/AIjFIKRllrhcb48dqUNAAZl0ig9+qMuN91RpZo3Cb2+zuibfh+KISl6+kVVyktDz230JKc208UkQwwMqyB+w==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -31595,15 +31616,22 @@ "which", "write-file-atomic" ], + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.5.3", - "@npmcli/config": "^8.3.3", + "@npmcli/arborist": "^7.5.4", + "@npmcli/config": "^8.3.4", "@npmcli/fs": "^3.1.1", "@npmcli/map-workspaces": "^3.0.6", - "@npmcli/package-json": "^5.1.1", + "@npmcli/package-json": "^5.2.0", "@npmcli/promise-spawn": "^7.0.2", - "@npmcli/redact": "^2.0.0", + "@npmcli/redact": "^2.0.1", "@npmcli/run-script": "^8.1.0", "@sigstore/tuf": "^2.3.4", "abbrev": "^2.0.0", @@ -31614,7 +31642,7 @@ "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.4.1", + "glob": "^10.4.2", "graceful-fs": "^4.2.11", "hosted-git-info": "^7.0.2", "ini": "^4.1.3", @@ -31622,30 +31650,30 @@ "is-cidr": "^5.1.0", "json-parse-even-better-errors": "^3.0.2", "libnpmaccess": "^8.0.6", - "libnpmdiff": "^6.1.3", - "libnpmexec": "^8.1.2", - "libnpmfund": "^5.0.11", + "libnpmdiff": "^6.1.4", + "libnpmexec": "^8.1.3", + "libnpmfund": "^5.0.12", "libnpmhook": "^10.0.5", "libnpmorg": "^6.0.6", - "libnpmpack": "^7.0.3", + "libnpmpack": "^7.0.4", "libnpmpublish": "^9.0.9", "libnpmsearch": "^7.0.6", "libnpmteam": "^6.0.5", "libnpmversion": "^6.0.3", "make-fetch-happen": "^13.0.1", - "minimatch": "^9.0.4", + "minimatch": "^9.0.5", "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", "node-gyp": "^10.1.0", "nopt": "^7.2.1", - "normalize-package-data": "^6.0.1", + "normalize-package-data": "^6.0.2", "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.3.0", "npm-package-arg": "^11.0.2", - "npm-pick-manifest": "^9.0.1", + "npm-pick-manifest": "^9.1.0", "npm-profile": "^10.0.0", - "npm-registry-fetch": "^17.0.1", + "npm-registry-fetch": "^17.1.0", "npm-user-validate": "^2.0.1", "p-map": "^4.0.0", "pacote": "^18.0.6", @@ -31768,7 +31796,7 @@ } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.5.3", + "version": "7.5.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -31816,16 +31844,16 @@ } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.3.3", + "version": "8.3.4", "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/package-json": "^5.1.1", "ci-info": "^4.0.0", "ini": "^4.1.2", "nopt": "^7.2.1", "proc-log": "^4.2.0", - "read-package-json-fast": "^3.0.2", "semver": "^7.3.5", "walk-up-path": "^3.0.1" }, @@ -31845,11 +31873,12 @@ } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.7", + "version": "5.0.8", "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", "lru-cache": "^10.0.1", "npm-pick-manifest": "^9.0.0", "proc-log": "^4.0.0", @@ -31923,7 +31952,7 @@ } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.1.1", + "version": "5.2.0", "inBundle": true, "license": "ISC", "dependencies": { @@ -31962,7 +31991,7 @@ } }, "node_modules/npm/node_modules/@npmcli/redact": { - "version": "2.0.0", + "version": "2.0.1", "inBundle": true, "license": "ISC", "engines": { @@ -32334,7 +32363,7 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.4", + "version": "4.3.5", "inBundle": true, "license": "MIT", "dependencies": { @@ -32408,7 +32437,7 @@ } }, "node_modules/npm/node_modules/foreground-child": { - "version": "3.1.1", + "version": "3.2.1", "inBundle": true, "license": "ISC", "dependencies": { @@ -32433,16 +32462,8 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/function-bind": { - "version": "1.1.2", - "inBundle": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/npm/node_modules/glob": { - "version": "10.4.1", + "version": "10.4.2", "inBundle": true, "license": "ISC", "dependencies": { @@ -32450,6 +32471,7 @@ "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { @@ -32467,17 +32489,6 @@ "inBundle": true, "license": "ISC" }, - "node_modules/npm/node_modules/hasown": { - "version": "2.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/npm/node_modules/hosted-git-info": { "version": "7.0.2", "inBundle": true, @@ -32507,7 +32518,7 @@ } }, "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.4", + "version": "7.0.5", "inBundle": true, "license": "MIT", "dependencies": { @@ -32616,17 +32627,6 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/is-core-module": { - "version": "2.13.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/npm/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "inBundle": true, @@ -32646,7 +32646,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/jackspeak": { - "version": "3.1.2", + "version": "3.4.0", "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -32714,11 +32714,11 @@ } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.1.3", + "version": "6.1.4", "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.3", + "@npmcli/arborist": "^7.5.4", "@npmcli/installed-package-contents": "^2.1.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", @@ -32732,11 +32732,11 @@ } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "8.1.2", + "version": "8.1.3", "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.3", + "@npmcli/arborist": "^7.5.4", "@npmcli/run-script": "^8.1.0", "ci-info": "^4.0.0", "npm-package-arg": "^11.0.2", @@ -32752,11 +32752,11 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.11", + "version": "5.0.12", "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.3" + "@npmcli/arborist": "^7.5.4" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -32787,11 +32787,11 @@ } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "7.0.3", + "version": "7.0.4", "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.3", + "@npmcli/arborist": "^7.5.4", "@npmcli/run-script": "^8.1.0", "npm-package-arg": "^11.0.2", "pacote": "^18.0.6" @@ -32887,7 +32887,7 @@ } }, "node_modules/npm/node_modules/minimatch": { - "version": "9.0.4", + "version": "9.0.5", "inBundle": true, "license": "ISC", "dependencies": { @@ -32957,26 +32957,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/minipass-json-stream": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { - "version": "3.3.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", "inBundle": true, @@ -33122,12 +33102,11 @@ } }, "node_modules/npm/node_modules/normalize-package-data": { - "version": "6.0.1", + "version": "6.0.2", "inBundle": true, "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, @@ -33199,7 +33178,7 @@ } }, "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "9.0.1", + "version": "9.1.0", "inBundle": true, "license": "ISC", "dependencies": { @@ -33225,15 +33204,15 @@ } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "17.0.1", + "version": "17.1.0", "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", "make-fetch-happen": "^13.0.0", "minipass": "^7.0.2", "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", "npm-package-arg": "^11.0.0", "proc-log": "^4.0.0" @@ -33264,6 +33243,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm/node_modules/package-json-from-dist": { + "version": "1.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0" + }, "node_modules/npm/node_modules/pacote": { "version": "18.0.6", "inBundle": true, @@ -33534,13 +33518,13 @@ } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.3", + "version": "8.0.4", "inBundle": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.1", "debug": "^4.3.4", - "socks": "^2.7.1" + "socks": "^2.8.3" }, "engines": { "node": ">= 14" @@ -33951,9 +33935,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", - "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", + "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", "dev": true }, "node_modules/oauth": { @@ -34134,23 +34118,6 @@ "node": ">= 0.4" } }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -34240,9 +34207,9 @@ } }, "node_modules/openai": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.52.5.tgz", - "integrity": "sha512-qqH8GsyPE3z06took/2uWOGqRcrZNlRoPAsihpg4jsl0+2Dfelnw6HDDMep0EI2Cfzw75nn3vHRZehep/IZzxg==", + "version": "4.52.7", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.52.7.tgz", + "integrity": "sha512-dgxA6UZHary6NXUHEDj5TWt8ogv0+ibH+b4pT5RrWMjiRZVylNwLcw/2ubDrX5n0oUmHX/ZgudMJeemxzOvz7A==", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", @@ -34258,9 +34225,9 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", - "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", + "version": "18.19.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz", + "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==", "dependencies": { "undici-types": "~5.26.4" } @@ -35067,9 +35034,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -35106,9 +35073,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -35260,17 +35227,17 @@ } }, "node_modules/prosemirror-model": { - "version": "1.21.3", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.21.3.tgz", - "integrity": "sha512-nt2Xs/RNGepD9hrrkzXvtCm1mpGJoQfFSPktGa0BF/aav6XsnmVGZ9sTXNWRLupAz5SCLa3EyKlFeK7zJWROKg==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.2.tgz", + "integrity": "sha512-I4lS7HHIW47D0Xv/gWmi4iUWcQIDYaJKd8Hk4+lcSps+553FlQrhmxtItpEvTr75iAruhzVShVp6WUwsT6Boww==", "dependencies": { "orderedmap": "^2.0.0" } }, "node_modules/prosemirror-schema-list": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.0.tgz", - "integrity": "sha512-nZOIq/AkBSzCENxUyLm5ltWE53e2PLk65ghMN8qLQptOmDVixZlPqtMeQdiNw0odL9vNpalEjl3upgRkuJ/Jyw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.1.tgz", + "integrity": "sha512-jbDyaP/6AFfDfu70VzySsD75Om2t3sXTOdl5+31Wlxlg62td1haUpty/ybajSfJ1pkGadlOfwQq9kgW5IMo1Rg==", "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -35296,9 +35263,9 @@ } }, "node_modules/prosemirror-view": { - "version": "1.33.8", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.8.tgz", - "integrity": "sha512-4PhMr/ufz2cdvFgpUAnZfs+0xij3RsFysreeG9V/utpwX7AJtYCDVyuRxzWoMJIEf4C7wVihuBNMPpFLPCiLQw==", + "version": "1.33.9", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.9.tgz", + "integrity": "sha512-xV1A0Vz9cIcEnwmMhKKFAOkfIp8XmJRnaZoPqNXrPS7EK5n11Ov8V76KhR0RsfQd/SIzmWY+bg+M44A2Lx/Nnw==", "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -35563,9 +35530,9 @@ } }, "node_modules/quickselect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==" }, "node_modules/random-bytes": { "version": "1.0.0", @@ -35930,9 +35897,9 @@ } }, "node_modules/react-intersection-observer": { - "version": "9.10.3", - "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.10.3.tgz", - "integrity": "sha512-9NYfKwPZRovB6QJee7fDg0zz/SyYrqXtn5xTZU0vwLtLVBtfu9aZt1pVmr825REE49VPDZ7Lm5SNHjJBOTZHpA==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.13.0.tgz", + "integrity": "sha512-y0UvBfjDiXqC8h0EWccyaj4dVBWMxgEx0t5RGNzQsvkfvZwugnKwxpu70StY4ivzYuMajavwUDjH4LJyIki9Lw==", "peerDependencies": { "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -37492,11 +37459,12 @@ } }, "node_modules/rimraf": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.0.tgz", - "integrity": "sha512-u+yqhM92LW+89cxUQK0SRyvXYQmyuKHx0jkx4W7KfwLGLqJnQM5031Uv1trE4gB9XEXBM/s6MxKlfW95IidqaA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", "dependencies": { - "glob": "^11.0.0" + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" }, "bin": { "rimraf": "dist/esm/bin.mjs" @@ -37737,9 +37705,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { - "version": "1.77.7", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.7.tgz", - "integrity": "sha512-9ywH75cO+rLjbrZ6en3Gp8qAMwPGBapFtlsMJoDTkcMU/bSe5a6cjKVUn5Jr4Gzg5GbP3HE8cm+02pLCgcoMow==", + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -37835,14 +37803,14 @@ } }, "node_modules/schema-utils/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -38346,9 +38314,9 @@ } }, "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -38926,6 +38894,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", @@ -39130,9 +39108,9 @@ } }, "node_modules/styled-components": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.11.tgz", - "integrity": "sha512-Ui0jXPzbp1phYij90h12ksljKGqF8ncGx+pjrNPsSPhbUUjWT2tD1FwGo2LF6USCnbrsIhNngDfodhxbegfEOA==", + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.12.tgz", + "integrity": "sha512-n/O4PzRPhbYI0k1vKKayfti3C/IGcPf+DqcrOB7O/ab9x4u/zjqraneT5N45+sIe87cxrCApXM8Bna7NYxwoTA==", "dependencies": { "@emotion/is-prop-valid": "1.2.2", "@emotion/unitless": "0.8.1", @@ -39156,6 +39134,24 @@ "react-dom": ">= 16.8.0" } }, + "node_modules/styled-components/node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/styled-components/node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, "node_modules/styled-components/node_modules/postcss": { "version": "8.4.38", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", @@ -39235,9 +39231,9 @@ "dev": true }, "node_modules/synckit": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", - "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", "dev": true, "dependencies": { "@pkgr/core": "^0.1.0", @@ -39383,9 +39379,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/terser": { - "version": "5.31.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.2.tgz", - "integrity": "sha512-LGyRZVFm/QElZHy/CPr/O4eNZOZIzsrQ92y4v9UJe/pFJjypje2yI3C2FmPtvUEnhadlSbmG2nXtdcjHOjCfxw==", + "version": "5.31.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", + "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -39849,9 +39845,9 @@ } }, "node_modules/ts-loader/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -40373,9 +40369,9 @@ } }, "node_modules/type-fest": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.21.0.tgz", - "integrity": "sha512-ADn2w7hVPcK6w1I0uWnM//y1rLXZhzB9mr0a3OirzclKF1Wp6VzevUmzz/NRAWunOT6E8HrnpGY7xOfc6K57fA==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.23.0.tgz", + "integrity": "sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==", "engines": { "node": ">=16" }, @@ -40486,14 +40482,14 @@ "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==" }, "node_modules/typescript-eslint": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.0.tgz", - "integrity": "sha512-kaVRivQjOzuoCXU6+hLnjo3/baxyzWVO5GrnExkFzETRYJKVHYkrJglOu2OCm8Hi9RPDWX1PTNNTpU5KRV0+RA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.1.tgz", + "integrity": "sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "7.16.0", - "@typescript-eslint/parser": "7.16.0", - "@typescript-eslint/utils": "7.16.0" + "@typescript-eslint/eslint-plugin": "7.16.1", + "@typescript-eslint/parser": "7.16.1", + "@typescript-eslint/utils": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -41122,9 +41118,9 @@ } }, "node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.2.tgz", + "integrity": "sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==", "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0", @@ -41136,9 +41132,9 @@ } }, "node_modules/vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" @@ -41324,9 +41320,9 @@ } }, "node_modules/webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", @@ -41441,9 +41437,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.2.1.tgz", - "integrity": "sha512-hRLz+jPQXo999Nx9fXVdKlg/aehsw1ajA9skAneGmT03xwmyuhvF93p6HUKKbWhXdcERtGTzUCtIQr+2IQegrA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.3.0.tgz", + "integrity": "sha512-xD2qnNew+F6KwOGZR7kWdbIou/ud7cVqLEXeK1q0nHcNsX/u7ul/fSdlOTX4ntSL5FNFy7ZJJXbf0piF591JYw==", "dependencies": { "colorette": "^2.0.10", "memfs": "^4.6.0", diff --git a/package.json b/package.json index a614d108e..56800edfc 100644 --- a/package.json +++ b/package.json @@ -186,7 +186,7 @@ "express-session": "^1.17.3", "express-validator": "^7.0.1", "extract-colors": "^4.0.2", - "ffmpeg": "0.0.4", + "ffmpeg": "^0.0.4", "file-loader": "^6.2.0", "file-saver": "^2.0.5", "find-in-files": "^0.5.0", diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts index b890e7bfc..fc415d589 100644 --- a/src/ClientUtils.ts +++ b/src/ClientUtils.ts @@ -7,11 +7,11 @@ import { CollectionViewType, DocumentType } from './client/documents/DocumentTyp import { Colors } from './client/views/global/globalEnums'; import { CreateImage } from './client/views/nodes/WebBoxRenderer'; -export function DashColor(color: string) { +export function DashColor(color: string | undefined) { try { return color ? Color(color.toLowerCase()) : Color('transparent'); } catch (e) { - if (color.includes('gradient')) console.log("using color 'white' in place of :" + color); + if (color?.includes('gradient')) console.log("using color 'white' in place of :" + color); else console.log('COLOR error:', e); return Color('white'); } @@ -455,7 +455,7 @@ export function addStyleSheet() { const sheets = document.head.appendChild(style); return sheets.sheet; } -export function addStyleSheetRule(sheet: CSSStyleSheet | null, selector: string, css: string | {[key:string]: string}, selectorPrefix = '.') { +export function addStyleSheetRule(sheet: CSSStyleSheet | null, selector: string, css: string | { [key: string]: string }, selectorPrefix = '.') { const propText = typeof css === 'string' ? css @@ -464,14 +464,14 @@ export function addStyleSheetRule(sheet: CSSStyleSheet | null, selector: string, .join(';'); return sheet?.insertRule(selectorPrefix + selector + '{' + propText + '}', sheet.cssRules.length); } -export function removeStyleSheetRule(sheet: CSSStyleSheet|null, rule: number) { +export function removeStyleSheetRule(sheet: CSSStyleSheet | null, rule: number) { if (sheet?.rules.length) { sheet.removeRule(rule); return true; } return false; } -export function clearStyleSheetRules(sheet: CSSStyleSheet|null) { +export function clearStyleSheetRules(sheet: CSSStyleSheet | null) { if (sheet?.rules.length) { numberRange(sheet.rules.length).map(() => sheet.removeRule(0)); return true; diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 55f28f415..784d252a3 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -47,6 +47,7 @@ import { FormattedTextBox, FormattedTextBoxProps } from './nodes/formattedText/F import { PinDocView, PinProps } from './PinFuncs'; import { StyleProp } from './StyleProp'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const { INK_MASK_SIZE } = require('./global/globalCssVariables.module.scss'); // prettier-ignore @observer @@ -292,7 +293,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() * @param boundsTop the screen space top coordinate of the ink stroke * @returns the JSX controls for displaying an editing UI for the stroke (control point & tangent handles) */ - componentUI = (boundsLeft: number, boundsTop: number) => { + componentUI = (boundsLeft: number, boundsTop: number): null | JSX.Element => { const inkDoc = this.Document; const { inkData, inkStrokeWidth } = this.inkScaledData(); const screenSpaceCenterlineStrokeWidth = Math.min(3, inkStrokeWidth * this.ScreenToLocalBoxXf().inverse().Scale); // the width of the blue line widget that shows the centerline of the ink stroke @@ -344,12 +345,12 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() }; @computed get fillColor(): string { const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask); - return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FillColor) ?? 'transparent'; + return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : ((this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FillColor) as 'string') ?? 'transparent'); } @computed get strokeColor() { const { inkData } = this.inkScaledData(); const { fillColor } = this; - return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) ?? StrCast(this.layoutDoc.color); + return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : ((this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as 'string') ?? StrCast(this.layoutDoc.color)); } render() { TraceMobx(); @@ -370,8 +371,8 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() }); } const highlight = !this.controlUndo && this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting); - const highlightIndex = highlight?.highlightIndex; - const highlightColor = !this._props.isSelected() && !isInkMask && highlight?.highlightIndex ? highlight?.highlightColor : undefined; + const { highlightIndex, highlightColor: hColor } = (highlight as { highlightIndex?: number; highlightColor?: string }) ?? { highlightIndex: undefined, highlightColor: undefined }; + const highlightColor = !this._props.isSelected() && !isInkMask && highlightIndex ? hColor : undefined; const color = StrCast(this.layoutDoc.stroke_outlineColor, !closed && fillColor && fillColor !== 'transparent' ? StrCast(this.layoutDoc.color, 'transparent') : 'transparent'); // Visually renders the polygonal line made by the user. @@ -401,12 +402,12 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() ); const higlightMargin = Math.min(12, Math.max(2, 0.3 * inkStrokeWidth)); // Invisible polygonal line that enables the ink to be selected by the user. - const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, mask: boolean = false): any => + const clickableLine = (downHdlr?: (e: React.PointerEvent) => void, mask: boolean = false) => InteractionUtils.CreatePolyline( inkData, inkLeft, inkTop, - mask && color === 'transparent' ? this.strokeColor : highlightColor ?? color, + mask && color === 'transparent' ? this.strokeColor : (highlightColor ?? color), inkStrokeWidth, inkStrokeWidth + NumCast(this.layoutDoc.stroke_borderWidth) + (fillColor ? (closed ? higlightMargin : (highlightIndex ?? 0) + higlightMargin) : higlightMargin), StrCast(this.layoutDoc.stroke_lineJoin), @@ -420,7 +421,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() inkScaleX, inkScaleY, '', - this._props.pointerEvents?.() ?? 'visiblepainted', + this._props.pointerEvents?.() ?? 'visiblePainted', 0.0, false, downHdlr, diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 618f69221..9cb52aacf 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -144,7 +144,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt, props: Opt void) { diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 38f681e87..c799eb3c8 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; @@ -15,7 +13,7 @@ import { StyleProp } from '../StyleProp'; import { DocumentView } from '../nodes/DocumentView'; import { FocusViewOptions } from '../nodes/FocusViewOptions'; import './CollectionCarousel3DView.scss'; -import { CollectionSubView } from './CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; // eslint-disable-next-line @typescript-eslint/no-var-requires const { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } = require('../global/globalCssVariables.module.scss'); @@ -25,7 +23,7 @@ export class CollectionCarousel3DView extends CollectionSubView() { @computed get scrollSpeed() { return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; // default scroll speed } - constructor(props: any) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); } @@ -181,8 +179,8 @@ export class CollectionCarousel3DView extends CollectionSubView() { className="collectionCarousel3DView-outer" ref={this.createDashEventsTarget} style={{ - background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor), - color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color), + background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string, + color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string, }}>
{this.content} diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 2a36e96bf..5a142cc6e 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { action, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -28,7 +29,7 @@ import { OverlayView } from '../OverlayView'; import { ScriptingRepl } from '../ScriptingRepl'; import { UndoStack } from '../UndoStack'; import './CollectionDockingView.scss'; -import { CollectionSubView } from './CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; const _global = (window /* browser */ || global) /* node */ as any; @@ -40,7 +41,7 @@ export class CollectionDockingView extends CollectionSubView() { * configuring golden layout to render its documents using the specified React component * @param ele - typically would be set to TabDocView */ - public static Init(ele: any) { + public static Init(ele: JSX.Element | null) { this.tabClass = ele; DocumentView.addSplit = CollectionDockingView.AddSplit; } @@ -60,7 +61,7 @@ export class CollectionDockingView extends CollectionSubView() { private _goldenLayout: any = null; static _highlightStyleSheet = addStyleSheet(); - constructor(props: any) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); if (this._props.renderDepth < 0) CollectionDockingView.Instance = this; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index e250d7a90..b7169ece0 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -67,7 +67,7 @@ export function CollectionSubView() { private gestureDisposer?: GestureUtils.GestureEventDisposer; protected _mainCont?: HTMLDivElement; - constructor(props: any) { + constructor(props: X & SubCollectionViewProps) { super(props); makeObservable(this); } diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 46f61290e..f50f7394b 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -14,7 +14,7 @@ import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { FieldId } from '../../../fields/RefField'; import { ComputedField } from '../../../fields/ScriptField'; -import { Cast, DocCast, NumCast, StrCast, toList } from '../../../fields/Types'; +import { Cast, NumCast, StrCast, toList } from '../../../fields/Types'; import { DocServer } from '../../DocServer'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; @@ -67,7 +67,7 @@ class TabMiniThumb extends React.Component { } @observer export class TabMinimapView extends ObservableReactComponent { - static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { + static miniStyleProvider = (doc: Opt, props: Opt, property: string) => { if (doc) { switch (property.split(':')[0]) { case StyleProp.PointerEvents: return 'none'; @@ -274,7 +274,7 @@ export class TabDocView extends ObservableReactComponent { } static Activate = (tabDoc: Doc) => { - const tab = Array.from(CollectionDockingView.Instance?.tabMap!).find(findTab => findTab.DashDoc === tabDoc && !findTab.contentItem.config.props.keyValue); + const tab = Array.from(CollectionDockingView.Instance?.tabMap ?? []).find(findTab => findTab.DashDoc === tabDoc && !findTab.contentItem.config.props.keyValue); tab?.header.parent.setActiveContentItem(tab.contentItem); // glr: Panning does not work when this is set - (this line is for trying to make a tab that is not topmost become topmost) return tab !== undefined; }; @@ -286,7 +286,7 @@ export class TabDocView extends ObservableReactComponent { // } // return undefined; // } - constructor(props: any) { + constructor(props: TabDocViewProps) { super(props); makeObservable(this); DocumentView.activateTabView = TabDocView.Activate; @@ -399,9 +399,10 @@ export class TabDocView extends ObservableReactComponent { tab._disposers.color = reaction( () => ({ variant: SnappingManager.userVariantColor, degree: Doc.GetBrushStatus(doc), highlight: DefaultStyleProvider(this._document, undefined, StyleProp.Highlighting) }), ({ variant, degree, highlight }) => { - const color = highlight?.highlightIndex === Doc.DocBrushStatus.highlighted ? highlight.highlightColor : degree ? ['transparent', variant, variant, 'orange'][degree] : variant; + const { highlightIndex, highlightColor } = (highlight as { highlightIndex: number; highlightColor: string }) ?? { highlightIndex: undefined, highlightColor: undefined }; + const color = highlightIndex === Doc.DocBrushStatus.highlighted ? highlightColor : degree ? ['transparent', variant, variant, 'orange'][degree] : variant; - const textColor = color === variant ? SnappingManager.userColor ?? '' : lightOrDark(color); + const textColor = color === variant ? (SnappingManager.userColor ?? '') : lightOrDark(color); titleEle.style.color = textColor; iconWrap.style.color = textColor; closeWrap.style.color = textColor; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index f69aea2a7..161d93788 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -472,7 +472,7 @@ export class TreeView extends ObservableReactComponent { refTransform = (ref: HTMLElement | undefined | null) => { if (!ref) return this.ScreenToLocalTransform(); const { translateX, translateY, scale } = ClientUtils.GetScreenTransform(ref); - return new Transform(-translateX, -translateY, 1).scale(1/scale); + return new Transform(-translateX, -translateY, 1).scale(1 / scale); }; docTransform = () => this.refTransform(this._dref?.ContentDiv); getTransform = () => this.refTransform(this._tref.current); @@ -777,7 +777,7 @@ export class TreeView extends ObservableReactComponent { @computed get renderBullet() { TraceMobx(); - const iconType = this.treeView._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':treeOpen' : !this.childDocs.length ? ':empty' : '')) || 'question'; + const iconType = (this.treeView._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':treeOpen' : !this.childDocs.length ? ':empty' : '')) as string) || 'question'; const color = SettingsManager.userColor; const checked = this.onCheckedClick ? this.Document.treeView_Checked ?? 'unchecked' : undefined; return ( @@ -923,7 +923,7 @@ export class TreeView extends ObservableReactComponent { style={{ // just render a title for a tree view label (identified by treeViewDoc being set in 'props') maxWidth: props?.PanelWidth() || undefined, - background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor), + background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor) as string, outline: SnappingManager.IsDragging ? undefined: `solid ${highlightColor} ${highlightIndex}px`, paddingLeft: NumCast(treeView.Document.childXPadding, NumCast(treeView._props.childXPadding, Doc.IsComicStyle(doc)?20:0)), paddingRight: NumCast(treeView.Document.childXPadding, NumCast(treeView._props.childXPadding, Doc.IsComicStyle(doc)?20:0)), @@ -1179,7 +1179,7 @@ export class TreeView extends ObservableReactComponent { @computed get renderBorder() { const sorting = StrCast(this.Document.treeView_SortCriterion, TreeSort.WhenAdded); - const sortings = (this._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewSortings) ?? {}) as { [key: string]: { color: string; label: string } }; + const sortings = (this._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewSortings) ?? {}) as { [key: string]: { color: string; icon: JSX.Element } }; return (
{!this.treeViewOpen ? null : this.renderContent} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx index de51cc73c..79aad0ef2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx @@ -9,7 +9,7 @@ import { aggregateBounds } from '../../../../Utils'; export interface ViewDefBounds { type: string; - payload: any; + payload: unknown; x: number; y: number; z?: number; @@ -72,11 +72,15 @@ function toLabel(target: FieldResult) { */ function getTextWidth(text: string, font: string): number { // re-use canvas object for better performance - const canvas = (getTextWidth as any).canvas || ((getTextWidth as any).canvas = document.createElement('canvas')); + const selfStoreHack = getTextWidth as unknown as { canvas: Element }; + const canvas = (selfStoreHack.canvas = (selfStoreHack.canvas as unknown as HTMLCanvasElement) ?? document.createElement('canvas')); const context = canvas.getContext('2d'); - context.font = font; - const metrics = context.measureText(text); - return metrics.width; + if (context) { + context.font = font; + const metrics = context.measureText(text); + return metrics.width; + } + return 0; } interface PivotColumn { @@ -131,13 +135,13 @@ export function computeStarburstLayout(poolData: Map, pivotDoc return normalizeResults(burstDiam, 12, docMap, poolData, viewDefsToJSX, [], 0, [divider]); } -export function computePivotLayout(poolData: Map, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) { +export function computePivotLayout(poolData: Map, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: unknown) { const docMap = new Map(); const fieldKey = 'data'; const pivotColumnGroups = new Map, PivotColumn>(); let nonNumbers = 0; - const pivotFieldKey = toLabel(engineProps?.pivotField ?? pivotDoc._pivotField) || 'author'; + const pivotFieldKey = toLabel((engineProps as { pivotField?: string })?.pivotField ?? pivotDoc._pivotField) || 'author'; childPairs.forEach(pair => { const listValue = Cast(pair.layout[pivotFieldKey], listSpec('string'), null); @@ -265,7 +269,7 @@ export function computePivotLayout(poolData: Map, pivotDoc: Do y: -maxColHeight + pivotAxisWidth, width: pivotAxisWidth * numCols * expander, height: maxColHeight, - payload: pivotColumnGroups.get(key)!.filters, + payload: pivotColumnGroups.get(key)?.filters, })); groupNames.push(...dividers); // eslint-disable-next-line no-use-before-define diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 812aa5fa3..39c3da7a5 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,6 +1,4 @@ /* eslint-disable react/jsx-props-no-spreading */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ import { Bezier } from 'bezier-js'; import { Colors } from 'browndash-components'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; @@ -9,7 +7,7 @@ import { computedFn } from 'mobx-utils'; import * as React from 'react'; import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils'; import { DateField } from '../../../../fields/DateField'; -import { Doc, DocListCast, Field, FieldType, Opt } from '../../../../fields/Doc'; +import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc'; import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveEraserWidth, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, SetActiveInkColor, SetActiveInkWidth } from '../../nodes/DocumentView'; import { DocData, Height, Width } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; @@ -46,7 +44,7 @@ import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { OpenWhere, OpenWhereMod } from '../../nodes/OpenWhere'; import { PinDocView, PinProps } from '../../PinFuncs'; import { StyleProp } from '../../StyleProp'; -import { CollectionSubView } from '../CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import { TreeViewType } from '../CollectionTreeViewType'; import { CollectionFreeFormBackgroundGrid } from './CollectionFreeFormBackgroundGrid'; import { CollectionFreeFormClusters } from './CollectionFreeFormClusters'; @@ -71,7 +69,7 @@ export interface collectionFreeformViewProps { childPointerEvents?: () => string | undefined; viewField?: string; noOverlay?: boolean; // used to suppress docs in the overlay (z) layer (ie, for minimap since overlay doesn't scale) - engineProps?: any; + engineProps?: unknown; getScrollHeight?: () => number | undefined; } @@ -123,14 +121,14 @@ export class CollectionFreeFormView extends CollectionSubView(); @observable _brushedView: { width: number; height: number; panX: number; panY: number } | undefined = undefined; // highlighted region of freeform canvas used by presentations to indicate a region @observable GroupChildDrag: boolean = false; // child document view being dragged. needed to update drop areas of groups when a group item is dragged. - @observable _childPointerEvents: 'none' | 'all' | 'visiblepainted' | undefined = undefined; + @observable _childPointerEvents: 'none' | 'all' | 'visiblePainted' | undefined = undefined; @observable _lightboxDoc: Opt = undefined; @observable _paintedId = 'id' + Utils.GenerateGuid().replace(/-/g, ''); @observable _keyframeEditing = false; @observable _eraserX: number = 0; @observable _eraserY: number = 0; @observable _showEraserCircle: boolean = false; // to determine whether the radius eraser should show - constructor(props: collectionFreeformViewProps) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); } @@ -140,12 +138,12 @@ export class CollectionFreeFormView extends CollectionSubView ele.bounds && !ele.bounds.z && ele.inkMask !== -1 && ele.inkMask !== undefined).map(ele => ele.ele); @@ -185,7 +183,7 @@ export class CollectionFreeFormView extends CollectionSubView { + focus = (anchor: Doc, options: FocusViewOptions) => { if (anchor.isGroup && !options.docTransform && options.contextPath?.length) { // don't focus on group if there's a context path because we're about to focus on a group item // which will override any group focus. (If we allowed the group to focus, it would mark didMove even if there were no net movement) @@ -374,14 +372,14 @@ export class CollectionFreeFormView extends CollectionSubView { + // eslint-disable-next-line @typescript-eslint/no-explicit-any if ((curve as any)._linear) { // bezier.js doesn't intersect properly if the curve is actually a line -- so get intersect other curve against this line, then figure out the t coordinates of the intersection on this line const intersections = otherCurve.lineIntersects({ p1: curve.points[0], p2: curve.points[3] }); @@ -1187,6 +1186,7 @@ export class CollectionFreeFormView extends CollectionSubView this._childPointerEvents; - childContentsActive = () => (this._props.childContentsActive ?? this.isContentActive() === false ? returnFalse : emptyFunction)(); + childContentsActive = () => ((this._props.childContentsActive ?? this.isContentActive() === false) ? returnFalse : emptyFunction)(); getChildDocView(entry: PoolData) { const childLayout = entry.pair.layout; const childData = entry.pair.data; @@ -1603,7 +1603,7 @@ export class CollectionFreeFormView extends CollectionSubView { + onViewDefDivClick = (e: React.MouseEvent, payload: unknown) => { (this._props.viewDefDivClick || ScriptCast(this.Document.onViewDefDivClick))?.script.run({ this: this.Document, payload }); e.stopPropagation(); }; @@ -1637,7 +1637,7 @@ export class CollectionFreeFormView extends CollectionSubView this.onViewDefDivClick(e, viewDef)} style={{ width, height, backgroundColor: color, transform }} @@ -1658,7 +1658,7 @@ export class CollectionFreeFormView extends CollectionSubView, - engine: (poolData: Map, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) => ViewDefResult[] + engine: (poolData: Map, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: unknown) => ViewDefResult[] ) { return engine(poolData, this.Document, this.childLayoutPairs, [this._props.PanelWidth(), this._props.PanelHeight()], this.viewDefsToJSX, this._props.engineProps); } @@ -1688,7 +1688,7 @@ export class CollectionFreeFormView extends CollectionSubView elements.push({ ele: this.getChildDocView(entry[1]), - bounds: (entry[1].opacity === 0 ? { payload:undefined, type:"", ...entry[1], width: 0, height: 0 } : { payload:undefined, type:"",...entry[1] }), + bounds: entry[1].opacity === 0 ? { payload: undefined, type: '', ...entry[1], width: 0, height: 0 } : { payload: undefined, type: '', ...entry[1] }, inkMask: BoolCast(entry[1].pair.layout.stroke_isInkMask) ? NumCast(entry[1].pair.layout.opacity, 1) : -1, }) ); @@ -1771,7 +1771,7 @@ export class CollectionFreeFormView extends CollectionSubView this.childPointerEvents, pointerevents => { - this._childPointerEvents = pointerevents as any; + this._childPointerEvents = pointerevents as 'none' | 'all' | 'visiblePainted' | undefined; }, { fireImmediately: true } ); @@ -1812,24 +1812,25 @@ export class CollectionFreeFormView extends CollectionSubView { const contentDiv = this.DocumentView?.().ContentDiv; - contentDiv && UpdateIcon( - this.layoutDoc[Id] + '-icon' + new Date().getTime(), - contentDiv, - NumCast(this.layoutDoc._width), - NumCast(this.layoutDoc._height), - this._props.PanelWidth(), - this._props.PanelHeight(), - 0, - 1, - false, - '', - (iconFile, nativeWidth, nativeHeight) => { - this.dataDoc.icon = new ImageField(iconFile); - this.dataDoc.icon_nativeWidth = nativeWidth; - this.dataDoc.icon_nativeHeight = nativeHeight; - } - ); - } + contentDiv && + UpdateIcon( + this.layoutDoc[Id] + '-icon' + new Date().getTime(), + contentDiv, + NumCast(this.layoutDoc._width), + NumCast(this.layoutDoc._height), + this._props.PanelWidth(), + this._props.PanelHeight(), + 0, + 1, + false, + '', + (iconFile, nativeWidth, nativeHeight) => { + this.dataDoc.icon = new ImageField(iconFile); + this.dataDoc.icon_nativeWidth = nativeWidth; + this.dataDoc.icon_nativeHeight = nativeHeight; + } + ); + }; @action onCursorMove = (e: React.PointerEvent) => { @@ -2134,7 +2135,7 @@ export class CollectionFreeFormView extends CollectionSubView e.preventDefault()} onContextMenu={this.onContextMenu} style={{ - pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : (this._props.pointerEvents?.() as any), + pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : this._props.pointerEvents?.(), textAlign: this.isAnnotationOverlay ? 'initial' : undefined, transform: `scale(${this.nativeDimScaling})`, width: `${100 / this.nativeDimScaling}%`, diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 24cb4ccf6..0f2905d5b 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,6 +1,5 @@ /* eslint-disable no-use-before-define */ /* eslint-disable react/jsx-props-no-spreading */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { Howl } from 'howler'; import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; @@ -55,13 +54,6 @@ import { PresEffect, PresEffectDirection } from './trails/PresEnums'; import SpringAnimation from './trails/SlideEffect'; import { SpringType, springMappings } from './trails/SpringUtils'; -interface Window { - MediaRecorder: MediaRecorder; -} -declare class MediaRecorder { - constructor(e: any); // whatever MediaRecorder has -} - export interface DocumentViewProps extends FieldViewSharedProps { hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected hideResizeHandles?: boolean; // whether to suppress resized handles on doc decorations when this document is selected @@ -135,15 +127,15 @@ export class DocumentViewInternal extends DocComponent this._animateScaleTime ?? 100; style = (doc: Doc, sprop: StyleProp | string) => this._props.styleProvider?.(doc, this._props, sprop); @computed get opacity() { return this.style(this.layoutDoc, StyleProp.Opacity) as number; } // prettier-ignore - @computed get boxShadow() { return this.style(this.layoutDoc, StyleProp.BoxShadow); } // prettier-ignore - @computed get borderRounding() { return this.style(this.layoutDoc, StyleProp.BorderRounding); } // prettier-ignore + @computed get boxShadow() { return this.style(this.layoutDoc, StyleProp.BoxShadow) as string; } // prettier-ignore + @computed get borderRounding() { return this.style(this.layoutDoc, StyleProp.BorderRounding) as string; } // prettier-ignore @computed get widgetDecorations() { return this.style(this.layoutDoc, StyleProp.Decorations) as JSX.Element; } // prettier-ignore @computed get backgroundBoxColor(){ return this.style(this.layoutDoc, StyleProp.BackgroundColor + ':docView') as string; } // prettier-ignore @computed get showTitle() { return this.style(this.layoutDoc, StyleProp.ShowTitle) as Opt; } // prettier-ignore @computed get showCaption() { return this.style(this.layoutDoc, StyleProp.ShowCaption) as string ?? ""; } // prettier-ignore @computed get headerMargin() { return this.style(this.layoutDoc, StyleProp.HeaderMargin) as number ?? 0; } // prettier-ignore @computed get titleHeight() { return this.style(this.layoutDoc, StyleProp.TitleHeight) as number ?? 0; } // prettier-ignore - @computed get docContents() { return this.style(this.Document, StyleProp.DocContents); } // prettier-ignore + @computed get docContents() { return this.style(this.Document, StyleProp.DocContents) as JSX.Element; } // prettier-ignore @computed get highlighting() { return this.style(this.Document, StyleProp.Highlighting); } // prettier-ignore @computed get borderPath() { return this.style(this.Document, StyleProp.BorderPath); } // prettier-ignore @@ -164,13 +156,13 @@ export class DocumentViewInternal extends DocComponent this.style(this.Document, StyleProp.PointerEvents) as ("all" | "none" | "visiblePainted" | undefined), + () => this.style(this.Document, StyleProp.PointerEvents) as 'all' | 'none' | 'visiblePainted' | undefined, pointerevents => { this._pointerEvents = pointerevents; }, @@ -450,7 +442,11 @@ export class DocumentViewInternal extends DocComponent - ); + )); }; render() { TraceMobx(); const { highlighting, borderPath } = this; + const { highlightIndex, highlightStyle, highlightColor, highlightStroke } = (highlighting as { highlightIndex: number; highlightStyle: string; highlightColor: string; highlightStroke: boolean }) ?? { + highlightIndex: undefined, + highlightStyle: undefined, + highlightColor: undefined, + highlightStroke: undefined, + }; + const { clipPath, jsx } = (borderPath as { clipPath: string; jsx: JSX.Element }) ?? { clipPath: undefined, jsx: undefined }; const boxShadow = !highlighting ? this.boxShadow - : highlighting && this.borderRounding && highlighting.highlightStyle !== 'dashed' - ? `0 0 0 ${highlighting.highlightIndex}px ${highlighting.highlightColor}` + : highlighting && this.borderRounding && highlightStyle !== 'dashed' + ? `0 0 0 ${highlightIndex}px ${highlightColor}` : this.boxShadow || (this.Document.isTemplateForField ? 'black 0.2vw 0.2vw 0.8vw' : undefined); const renderDoc = this.renderDoc({ borderRadius: this.borderRounding, - outline: highlighting && !this.borderRounding && !highlighting.highlightStroke ? `${highlighting.highlightColor} ${highlighting.highlightStyle} ${highlighting.highlightIndex}px` : 'solid 0px', - border: highlighting && this.borderRounding && highlighting.highlightStyle === 'dashed' ? `${highlighting.highlightStyle} ${highlighting.highlightColor} ${highlighting.highlightIndex}px` : undefined, + outline: highlighting && !this.borderRounding && !highlightStroke ? `${highlightColor} ${highlightStyle} ${highlightIndex}px` : 'solid 0px', + border: highlighting && this.borderRounding && highlightStyle === 'dashed' ? `${highlightStyle} ${highlightColor} ${highlightIndex}px` : undefined, boxShadow, - clipPath: borderPath?.clipPath, + clipPath, }); return ( - // eslint-disable-next-line jsx-a11y/click-events-have-key-events
- {this._componentView?.isUnstyledView?.() || this.Document.type === DocumentType.CONFIG ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)} - {borderPath?.jsx} + {this._componentView?.isUnstyledView?.() || this.Document.type === DocumentType.CONFIG || !renderDoc ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)} + {jsx}
); } @@ -968,7 +970,22 @@ export class DocumentViewInternal extends DocComponent, root: Doc) { + public static AnimationEffect( + renderDoc: JSX.Element, + presEffectDoc: Opt< + | Doc + | { + presentation_effectDirection?: string; + followLinkAnimDirection?: string; + presentation_transition?: number; + followLinkTransitionTime?: number; + presentation_effectTiming?: number; + presentation_effect?: string; + followLinkAnimEffect?: string; + } + >, + root: Doc + ) { const dir = ((presEffectDoc?.presentation_effectDirection ?? presEffectDoc?.followLinkAnimDirection) || PresEffectDirection.Center) as PresEffectDirection; const duration = Cast(presEffectDoc?.presentation_transition, 'number', Cast(presEffectDoc?.followLinkTransitionTime, 'number', null)); const effectProps = { @@ -982,7 +999,7 @@ export class DocumentViewInternal extends DocComponent() { public static allViews: () => DocumentView[]; public static addView: (dv: DocumentView) => void | undefined; public static removeView: (dv: DocumentView) => void | undefined; - public static addViewRenderedCb: (doc: Opt, func: (dv: DocumentView) => any) => boolean; + public static addViewRenderedCb: (doc: Opt, func: (dv: DocumentView) => void) => boolean; public static getViews = (doc?: Doc) => Array.from(doc?.[DocViews] ?? []) as DocumentView[]; public static getFirstDocumentView: (toFind: Doc) => DocumentView | undefined; public static getDocumentView: (target: Doc | undefined, preferredCollection?: DocumentView) => Opt; @@ -1107,7 +1124,7 @@ export class DocumentView extends DocComponent() { @observable private _htmlOverlayText: Opt = undefined; @observable private _isHovering = false; @observable private _selected = false; - @observable public static CurrentlyPlaying: DocumentView[] = []; // audio or video media views that are currently playing + @observable public static CurrentlyPlaying: DocumentView[] = []; // audio or video media views that are currently playing @computed private get shouldNotScale() { return (this.layout_fitWidth && !this.nativeWidth) || this.ComponentView?.isUnstyledView?.(); @@ -1254,7 +1271,6 @@ export class DocumentView extends DocComponent() { } public playAnnotation = () => { - const self = this; const audioAnnoState = this.dataDoc.audioAnnoState ?? AudioAnnoState.stopped; const audioAnnos = Cast(this.dataDoc[this.LayoutFieldKey + '_audioAnnotations'], listSpec(AudioField), null); const anno = audioAnnos?.lastElement(); @@ -1267,7 +1283,7 @@ export class DocumentView extends DocComponent() { autoplay: true, loop: false, volume: 0.5, - onend: action(() => { self.dataDoc.audioAnnoState = AudioAnnoState.stopped; }), // prettier-ignore + onend: action(() => { this.dataDoc.audioAnnoState = AudioAnnoState.stopped; }), // prettier-ignore }); this.dataDoc.audioAnnoState = AudioAnnoState.playing; break; @@ -1426,9 +1442,10 @@ export class DocumentView extends DocComponent() {
{DocumentViewInternal.AnimationEffect(
- console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this._htmlOverlayText)} /> + {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} + console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this._htmlOverlayText)} />
, - { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Expand } as any as Doc, + { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Expand }, this.Document )}
@@ -1457,7 +1474,7 @@ export class DocumentView extends DocComponent() { style={{ transform: `translate(${this.centeringX}px, ${this.centeringY}px)`, width: xshift ?? `${this._props.PanelWidth() - this.Xshift * 2}px`, - height: this._props.forceAutoHeight ? undefined : yshift ?? (this.layout_fitWidth ? `${this.panelHeight}px` : `${(this.effectiveNativeHeight / this.effectiveNativeWidth) * this._props.PanelWidth()}px`), + height: this._props.forceAutoHeight ? undefined : (yshift ?? (this.layout_fitWidth ? `${this.panelHeight}px` : `${(this.effectiveNativeHeight / this.effectiveNativeWidth) * this._props.PanelWidth()}px`)), }}> Opt; // eslint-disable-next-line no-use-before-define -export type StyleProviderFuncType = (doc: Opt, props: Opt, property: string) => Opt |{ clipPath: string; jsx: Element; } | JSX.Element | null; +export type StyleProviderFuncType = ( + doc: Opt, + props: Opt, + property: string +) => + | Opt + | { clipPath: string; jsx: JSX.Element } + | JSX.Element + | null + | { + [key: string]: + | { + color: string; + icon: JSX.Element | string; + } + | undefined; + } + | { highlightStyle: string; highlightColor: string; highlightIndex: number; highlightStroke: boolean } + | undefined; // // these properties get assigned through the render() method of the DocumentView when it creates this node. // However, that only happens because the properties are "defined" in the markup for the field view. @@ -30,7 +48,7 @@ export interface FieldViewSharedProps { LayoutTemplateString?: string; LayoutTemplate?: () => Opt; renderDepth: number; - scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document + scriptContext?: unknown; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document xPadding?: number; yPadding?: number; dontRegisterView?: boolean; @@ -45,7 +63,7 @@ export interface FieldViewSharedProps { containerViewPath?: () => DocumentView[]; fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document isGroupActive?: () => string | undefined; // is this document part of a group that is active - setContentViewBox?: (view: ViewBoxInterface) => any; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox + setContentViewBox?: (view: ViewBoxInterface) => void; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox PanelWidth: () => number; PanelHeight: () => number; isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events @@ -76,7 +94,7 @@ export interface FieldViewSharedProps { bringToFront?: (doc: Doc, sendToBack?: boolean) => void; waitForDoubleClickToClick?: () => 'never' | 'always' | undefined; defaultDoubleClick?: () => 'default' | 'ignore' | undefined; - pointerEvents?: () => Opt; + pointerEvents?: () => Opt<'none' | 'all' | 'visiblePainted'>; suppressSetHeight?: boolean; } diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx index b8451fe60..37ffca2d6 100644 --- a/src/client/views/nodes/RecordingBox/RecordingView.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx @@ -1,6 +1,4 @@ -/* eslint-disable jsx-a11y/label-has-associated-control */ /* eslint-disable react/button-has-type */ -/* eslint-disable jsx-a11y/control-has-associated-label */ import * as React from 'react'; import { useEffect, useRef, useState } from 'react'; import { IconContext } from 'react-icons'; @@ -14,7 +12,7 @@ import { ProgressBar } from './ProgressBar'; import './RecordingView.scss'; export interface MediaSegment { - videoChunks: any[]; + videoChunks: Blob[]; endTime: number; startTime: number; presentation?: Presentation; @@ -91,15 +89,15 @@ export function RecordingView(props: IRecordingViewProps) { }, []); useEffect(() => { - let interval: any = null; + let interval: null | NodeJS.Timeout = null; if (recording) { interval = setInterval(() => { setRecordingTimer(unit => unit + 1); }, 10); } else if (!recording && recordingTimer !== 0) { - clearInterval(interval); + interval && clearInterval(interval); } - return () => clearInterval(interval); + return interval ? () => clearInterval(interval!) : undefined; }, [recording]); const setVideoProgressHelper = (curProgrss: number) => { @@ -127,9 +125,9 @@ export function RecordingView(props: IRecordingViewProps) { if (!videoRecorder.current) videoRecorder.current = new MediaRecorder(await startShowingStream()); // temporary chunks of video - let videoChunks: any = []; + let videoChunks: Blob[] = []; - videoRecorder.current.ondataavailable = (event: any) => { + videoRecorder.current.ondataavailable = (event: BlobEvent) => { if (event.data.size > 0) videoChunks.push(event.data); }; diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 3be50f5e6..9ef1071f7 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,4 +1,3 @@ -/* eslint-disable jsx-a11y/media-has-caption */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import * as React from 'react'; // import { Canvas } from '@react-three/fiber'; -- cgit v1.2.3-70-g09d2 From ff1840832e1da2e0b0510045574354970a88decc Mon Sep 17 00:00:00 2001 From: geireann Date: Wed, 24 Jul 2024 17:03:16 -0400 Subject: more update of anys --- package-lock.json | 42 +++++++++++++++++++++++++----------- package.json | 2 ++ src/client/views/StyleProvider.tsx | 29 +++++++++++-------------- src/client/views/nodes/FieldView.tsx | 1 + 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0187d7952..ae5f01daa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -220,6 +220,7 @@ "styled-components": "^6.1.1", "supercluster": "^8.0.1", "textarea-caret": "^3.1.0", + "textfit": "^2.4.0", "tough-cookie": "^4.1.3", "tslint": "^6.1.3", "tslint-loader": "^3.5.4", @@ -283,6 +284,7 @@ "@types/request": "^2.48.12", "@types/request-promise": "^4.1.51", "@types/shelljs": "^0.8.15", + "@types/textfit": "^2.4.4", "@types/uuid": "^10.0.0", "@types/valid-url": "^1.0.7", "@types/webpack": "^5.28.5", @@ -9824,6 +9826,15 @@ "@types/geojson": "*" } }, + "node_modules/@types/textfit": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/textfit/-/textfit-2.4.4.tgz", + "integrity": "sha512-AYlNcJ5j/WspQfbHIhoF0Wo63F5+REnX/VPFSH5unUUuwRcr6IoXxZki3vYhG4DRVUQe51AsFYyRxml5u+qaAg==", + "dev": true, + "dependencies": { + "@types/jquery": "*" + } + }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -13560,6 +13571,19 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/readable-stream": { + "version": "3.6.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/browndash-components/node_modules/npm/node_modules/node-gyp/node_modules/signal-exit": { "version": "3.0.7", "inBundle": true, @@ -14005,19 +14029,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/browndash-components/node_modules/npm/node_modules/readable-stream": { - "version": "3.6.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/browndash-components/node_modules/npm/node_modules/retry": { "version": "0.12.0", "inBundle": true, @@ -39503,6 +39514,11 @@ "resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.1.0.tgz", "integrity": "sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q==" }, + "node_modules/textfit": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/textfit/-/textfit-2.4.0.tgz", + "integrity": "sha512-/x4aoY5+/tJmu+iwpBH1yw75TFp86M6X15SvaaY/Eep7YySQYtqdOifEtfvVyMwzl7SZ+G4RQw00FD9g5R6i1Q==" + }, "node_modules/thingies": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", diff --git a/package.json b/package.json index 56800edfc..d58bf3e9f 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "@types/request": "^2.48.12", "@types/request-promise": "^4.1.51", "@types/shelljs": "^0.8.15", + "@types/textfit": "^2.4.4", "@types/uuid": "^10.0.0", "@types/valid-url": "^1.0.7", "@types/webpack": "^5.28.5", @@ -305,6 +306,7 @@ "styled-components": "^6.1.1", "supercluster": "^8.0.1", "textarea-caret": "^3.1.0", + "textfit": "^2.4.0", "tough-cookie": "^4.1.3", "tslint": "^6.1.3", "tslint-loader": "^3.5.4", diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 9cb52aacf..8a07a6bd7 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -1,6 +1,3 @@ -/* eslint-disable jsx-a11y/alt-text */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; @@ -24,7 +21,7 @@ import { undoBatch, UndoManager } from '../util/UndoManager'; import { TreeSort } from './collections/TreeSort'; import { Colors } from './global/globalEnums'; import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; -import { FieldViewProps } from './nodes/FieldView'; +import { FieldViewProps, StyleProviderFuncType } from './nodes/FieldView'; import { StyleProp } from './StyleProp'; import './StyleProvider.scss'; @@ -43,9 +40,9 @@ function togglePaintView(e: React.MouseEvent, doc: Opt, props: Opt + const replacer = (match: string, expr: string) => // bcz: this executes a script to convert a property expression string: { script } into a value ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: doc, scale }).result?.toString() ?? ''; divKeys.forEach((prop: string) => { @@ -72,7 +69,7 @@ export function SetFilterOpener(func: () => void) { // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // -export function DefaultStyleProvider(doc: Opt, props: Opt, property: string) { +export function DefaultStyleProvider(doc: Opt, props: Opt, property: string) : StyleProviderFuncType { const remoteDocHeader = 'author;author_date;noMargin'; const isCaption = property.includes(':caption'); const isAnchor = property.includes(':anchor'); @@ -297,8 +294,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt, props: Opt
} closeOnSelect - setSelectedVal={((dv: DocumentView) => { + setSelectedVal={((dvValue: unknown) => { + const dv = dvValue as DocumentView; dv.select(false); SnappingManager.SetPropertiesWidth(250); _filterOpener?.(); - }) as any // Dropdown assumes values are strings or numbers.. + }) // Dropdown assumes values are strings or numbers.. } size={Size.XSMALL} width={15} @@ -345,11 +342,9 @@ export function DefaultStyleProvider(doc: Opt, props: Opt StrListCast(dv?.Document.childFilters).length || StrListCast(dv?.Document.childRangeFilters).length) - .map(dv => ({ - text: StrCast(dv?.Document.title), - val: dv as any, - style: {color:SnappingManager.userColor, background:SnappingManager.userBackgroundColor}, - } as IListItemProps)) } + .map(dv => ({ text: StrCast(dv?.Document.title), + val: dv as unknown, + style: {color:SnappingManager.userColor, background:SnappingManager.userBackgroundColor} } as IListItemProps)) } />
); @@ -387,7 +382,7 @@ export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp, } + icon={} onClick={undoBatch( action((e: React.MouseEvent) => { e.stopPropagation(); diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index c77f5a136..fc59e9e26 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -26,6 +26,7 @@ export type StyleProviderFuncType = ( | Opt | { clipPath: string; jsx: JSX.Element } | JSX.Element + | JSX.IntrinsicElements | null | { [key: string]: -- cgit v1.2.3-70-g09d2 From e1db06d59d580aa640212a0d3a6aeecb9122bdf0 Mon Sep 17 00:00:00 2001 From: geireann Date: Thu, 25 Jul 2024 15:06:01 -0400 Subject: lots more 'any' cleanup and more. --- src/client/views/MarqueeAnnotator.tsx | 21 +- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 6 +- src/client/views/nodes/ImageBox.tsx | 6 +- src/client/views/nodes/VideoBox.tsx | 16 +- src/client/views/nodes/WebBox.tsx | 48 ++-- .../views/nodes/formattedText/FormattedTextBox.tsx | 260 ++++++++------------- .../formattedText/FormattedTextBoxComment.tsx | 10 +- .../views/nodes/formattedText/RichTextMenu.tsx | 91 ++++---- src/client/views/pdf/AnchorMenu.tsx | 4 +- src/client/views/pdf/PDFViewer.tsx | 34 ++- 10 files changed, 213 insertions(+), 283 deletions(-) diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index c18ac6738..8aed34d24 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -27,7 +27,7 @@ export interface MarqueeAnnotatorProps { containerOffset?: () => number[]; marqueeContainer: HTMLDivElement; docView: () => DocumentView; - savedAnnotations: () => ObservableMap; + savedAnnotations: () => ObservableMap; selectionText: () => string; annotationLayer: HTMLDivElement; addDocument: (doc: Doc) => boolean; @@ -41,7 +41,7 @@ export interface MarqueeAnnotatorProps { export class MarqueeAnnotator extends ObservableReactComponent { private _start: { x: number; y: number } = { x: 0, y: 0 }; - constructor(props: any) { + constructor(props: MarqueeAnnotatorProps) { super(props); makeObservable(this); } @@ -60,13 +60,13 @@ export class MarqueeAnnotator extends ObservableReactComponent): Opt => { + makeAnnotationDocument = (color: string, isLinkButton?: boolean, savedAnnotations?: ObservableMap): Opt => { const savedAnnoMap = savedAnnotations?.values() && Array.from(savedAnnotations?.values()).length ? savedAnnotations : this.props.savedAnnotations(); if (savedAnnoMap.size === 0) return undefined; const savedAnnos = Array.from(savedAnnoMap.values())[0]; const doc = this.props.Document; const scale = (this.props.annotationLayerScaling?.() || 1) * NumCast(doc._freeform_scale, 1); - if (savedAnnos.length && (savedAnnos[0] as any).marqueeing) { + if (savedAnnos.length && savedAnnos[0].marqueeing) { const anno = savedAnnos[0]; const containerOffset = this.props.containerOffset?.() || [0, 0]; const marqueeAnno = Docs.Create.FreeformDocument([], { @@ -86,8 +86,9 @@ export class MarqueeAnnotator extends ObservableReactComponent, annotationLayer: HTMLDivElement, div: HTMLDivElement, page: number) => { + public static previewNewAnnotation = action((savedAnnotations: ObservableMap, annotationLayer: HTMLDivElement & { marqueeing?: boolean}, div: HTMLDivElement, page: number) => { div.style.backgroundColor = '#ACCEF7'; div.style.opacity = '0.5'; annotationLayer.append(div); @@ -264,17 +265,17 @@ export class MarqueeAnnotator extends ObservableReactComponent { - copy.style[prop as any] = marqueeStyle[prop as any]; + copy.style[prop as unknown as number] = marqueeStyle[prop as unknown as number]; // bcz: hack to get around TS type checking for array index with strings }); copy.className = 'marqueeAnnotator-annotationBox'; copy.style.top = parseInt(marqueeStyle.top.toString().replace('px', '')) / scale + this.props.scrollTop + 'px'; copy.style.left = parseInt(marqueeStyle.left.toString().replace('px', '')) / scale + 'px'; copy.style.width = parseInt(marqueeStyle.width.toString().replace('px', '')) / scale + 'px'; copy.style.height = parseInt(marqueeStyle.height.toString().replace('px', '')) / scale + 'px'; - (copy as any).marqueeing = true; + copy.marqueeing = true; MarqueeAnnotator.previewNewAnnotation(this.props.savedAnnotations(), this.props.annotationLayer, copy, this.props.getPageFromScroll?.(this.top) || 0); AnchorMenu.Instance.jumpTo(x, y); } diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index 4d5f15a3e..baf8693ca 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -50,7 +50,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { sidebarAddDoc: ((doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean) | undefined; crop: ((region: Doc | undefined, addCrop?: boolean) => Doc | undefined) | undefined; @observable _marqueeing: number[] | undefined = undefined; - @observable _savedAnnotations = new ObservableMap(); + @observable _savedAnnotations = new ObservableMap(); constructor(props: FieldViewProps) { super(props); @@ -376,8 +376,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { this._props.select(false); MarqueeAnnotator.clearAnnotations(this._savedAnnotations); this._marqueeing = [e.clientX, e.clientY]; - const target = e.target as any; - if (e.target && (target.className.includes('endOfContent') || (target.parentElement.className !== 'textLayer' && target.parentElement.parentElement?.className !== 'textLayer'))) { + const target = e.target as HTMLElement; + if (e.target && (target.className.includes('endOfContent') || (target.parentElement?.className !== 'textLayer' && target.parentElement?.parentElement?.className !== 'textLayer'))) { /* empty */ } else { // if textLayer is hit, then we select text instead of using a marquee so clear out the marquee. diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 68c313480..ce7552047 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -73,7 +73,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { private _marqueeref = React.createRef(); private _mainCont: React.RefObject = React.createRef(); private _annotationLayer: React.RefObject = React.createRef(); - @observable _savedAnnotations = new ObservableMap(); + @observable _savedAnnotations = new ObservableMap(); @observable _curSuffix = ''; @observable _error = ''; @observable _isHovering = false; // flag to switch between primary and alternate images on hover @@ -356,7 +356,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { @computed get content() { TraceMobx(); - const backColor = DashColor(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) ?? Colors.WHITE); + const backColor = DashColor(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string ?? Colors.WHITE); const backAlpha = backColor.red() === 0 && backColor.green() === 0 && backColor.blue() === 0 ? backColor.alpha() : 1; const srcpath = this.layoutDoc.hideImage ? '' : this.paths[0]; const fadepath = this.layoutDoc.hideImage ? '' : this.paths.lastElement(); @@ -456,7 +456,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { savedAnnotations = () => this._savedAnnotations; render() { TraceMobx(); - const borderRad = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BorderRounding); + const borderRad = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BorderRounding) as string; const borderRadius = borderRad?.includes('px') ? `${Number(borderRad.split('px')[0]) / (this._props.NativeDimScaling?.() || 1)}px` : borderRad; return (
() { private _marqueeref = React.createRef(); private _mainCont: React.RefObject = React.createRef(); // outermost div private _annotationLayer: React.RefObject = React.createRef(); - private _playRegionTimer: any = null; // timeout for playback - private _controlsFadeTimer: any = null; // timeout for controls fade + private _playRegionTimer: NodeJS.Timeout | undefined; // timeout for playback + private _controlsFadeTimer: NodeJS.Timeout | undefined; // timeout for controls fade private _ffref = React.createRef(); constructor(props: FieldViewProps) { @@ -142,7 +141,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { switch (e.key) { case 'ArrowLeft': case 'ArrowRight': - clearTimeout(this._controlsFadeTimer); + this._controlsFadeTimer && clearTimeout(this._controlsFadeTimer); this._scrubbing = true; this._controlsFadeTimer = setTimeout( action(() => { @@ -217,7 +216,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { this._playTimer = undefined; this.updateTimecode(); if (!this._finished) { - clearTimeout(this._playRegionTimer); // if paused in the middle of playback, prevents restart on next play + this._playRegionTimer && clearTimeout(this._playRegionTimer); // if paused in the middle of playback, prevents restart on next play } this._playRegionTimer = undefined; }; @@ -420,7 +419,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { this._videoRef = vref; if (vref) { this._videoRef!.ontimeupdate = this.updateTimecode; - // @ts-ignore // vref.onfullscreenchange = action((e) => this._fullScreen = vref.webkitDisplayingFullscreen); this._disposers.reactionDisposer?.(); this._disposers.reactionDisposer = reaction( @@ -469,7 +467,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { runInAction(() => { this._screenCapture = !this._screenCapture; }); - this._videoRef!.srcObject = !this._screenCapture ? undefined : await (navigator.mediaDevices as any).getDisplayMedia({ video: true }); + this._videoRef!.srcObject = !this._screenCapture ? null : await (navigator.mediaDevices).getDisplayMedia({ video: true }); }, icon: 'expand-arrows-alt', }); @@ -877,7 +875,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { return (
{ + ref={action((r: CollectionStackedTimeline) => { this._stackedTimeline = r; })} // eslint-disable-next-line react/jsx-props-no-spreading @@ -968,7 +966,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { focus = (anchor: Doc, options: FocusViewOptions) => (anchor.type === DocumentType.CONFIG ? undefined : this._ffref.current?.focus(anchor, options)); savedAnnotations = () => this._savedAnnotations; render() { - const borderRad = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BorderRounding); + const borderRad = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BorderRounding) as string; const borderRadius = borderRad?.includes('px') ? `${Number(borderRad.split('px')[0]) / this.scaling()}px` : borderRad; return (
() { private _sidebarRef = React.createRef(); private _searchRef = React.createRef(); private _searchString = ''; - private _scrollTimer: any; + private _scrollTimer: NodeJS.Timeout | undefined; private _getAnchor: (savedAnnotations: Opt>, addAsAnnotation: boolean) => Opt = () => undefined; @observable private _webUrl = ''; // url of the src parameter of the embedded iframe but not necessarily the rendered page - eg, when following a link, the rendered page changes but we don't want the src parameter to also change as that would cause an unnecessary re-render. @@ -85,7 +83,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { this._marqueeing = val; } @observable private _iframe: HTMLIFrameElement | null = null; - @observable private _savedAnnotations = new ObservableMap(); + @observable private _savedAnnotations = new ObservableMap(); @observable private _scrollHeight = NumCast(this.layoutDoc.scrollHeight); @computed get _url() { return this.webField?.toString() || ''; @@ -361,8 +359,8 @@ export class WebBox extends ViewBoxAnnotatableComponent() { return anchor; }; - _textAnnotationCreator: (() => ObservableMap) | undefined; - savedAnnotationsCreator: () => ObservableMap = () => this._textAnnotationCreator?.() || this._savedAnnotations; + _textAnnotationCreator: (() => ObservableMap) | undefined; + savedAnnotationsCreator: () => ObservableMap = () => this._textAnnotationCreator?.() || this._savedAnnotations; @action iframeMove = (e: PointerEvent) => { @@ -399,7 +397,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { .transformPoint(e.clientX, e.clientY - NumCast(this.layoutDoc.layout_scrollTop)); if (!this._marqueeref.current?.isEmpty) this._marqueeref.current?.onEnd(theclick[0], theclick[1]); else { - if (!(e.target as any)?.tagName?.includes('INPUT')) this.finishMarquee(theclick[0], theclick[1]); + if (!(e.target as HTMLElement)?.tagName?.includes('INPUT')) this.finishMarquee(theclick[0], theclick[1]); this._getAnchor = AnchorMenu.Instance?.GetAnchor; this.marqueeing = undefined; } @@ -430,7 +428,8 @@ export class WebBox extends ViewBoxAnnotatableComponent() { this._setPreviewCursor?.(e.clientX, e.clientY, false, true, this.Document); MarqueeAnnotator.clearAnnotations(this._savedAnnotations); - if (!word && !(e.target as any)?.className?.includes('rangeslider') && !(e.target as any)?.onclick && !(e.target as any)?.parentNode?.onclick) { + const target = e.target as HTMLElement; + if (!word && !target?.className?.includes('rangeslider') && !target?.onclick && !target?.parentElement?.onclick) { if (e.button !== 2) this.marqueeing = [e.clientX, e.clientY]; e.preventDefault(); } @@ -470,7 +469,8 @@ export class WebBox extends ViewBoxAnnotatableComponent() { .transformPoint(e.clientX, e.clientY - NumCast(this.layoutDoc.layout_scrollTop)); MarqueeAnnotator.clearAnnotations(this._savedAnnotations); const word = getWordAtPoint(e.target, e.clientX, e.clientY); - if (!word && !(e.target as any)?.className?.includes('rangeslider') && !(e.target as any)?.onclick && !(e.target as any)?.parentNode?.onclick) { + const target = e.target as HTMLElement; + if (!word && !target?.className?.includes('rangeslider') && !target?.onclick && !target?.parentElement?.onclick) { this.marqueeing = theclick; this._marqueeref.current?.onInitiateSelection(this.marqueeing); this._iframe?.contentDocument?.addEventListener('pointermove', this.iframeMove); @@ -479,16 +479,16 @@ export class WebBox extends ViewBoxAnnotatableComponent() { }; isFirefox = () => 'InstallTrigger' in window; // navigator.userAgent.indexOf("Chrome") !== -1; - addWebStyleSheet(document: any, styleType: string = 'text/css') { + addWebStyleSheet(document: Document | null | undefined, styleType: string = 'text/css') { if (document) { const style = document.createElement('style'); style.type = styleType; const sheets = document.head.appendChild(style); - return (sheets as any).sheet; + return sheets.sheet; } return undefined; } - addWebStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = '.') { + addWebStyleSheetRule(sheet: CSSStyleSheet | null | undefined, selector: string, css: {[key:string]: string}, selectorPrefix = '.') { const propText = typeof css === 'string' ? css @@ -498,7 +498,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { return sheet?.insertRule(selectorPrefix + selector + '{' + propText + '}', sheet.cssRules.length); } - _iframetimeout: any = undefined; + _iframetimeout: NodeJS.Timeout|undefined = undefined; @observable _warning = 0; @action iframeLoaded = () => { @@ -520,7 +520,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { if (requrlraw !== this._url.toString()) { if (requrlraw.match(/q=.*&/)?.length && this._url.toString().match(/q=.*&/)?.length) { const matches = requrlraw.match(/[^a-zA-z]q=[^&]*/g); - const newsearch = matches?.lastElement()!; + const newsearch = matches?.lastElement() || ""; if (matches) { requrlraw = requrlraw.substring(0, requrlraw.indexOf(newsearch)); for (let i = 1; i < Array.from(matches)?.length; i++) { @@ -570,8 +570,10 @@ export class WebBox extends ViewBoxAnnotatableComponent() { undoBatch( action((e: MouseEvent) => { let eleHref = ''; - for (let ele = e.target as any; ele; ele = ele.parentElement) { - eleHref = (typeof ele.href === 'string' ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || eleHref; + for (let ele = e.target as HTMLElement | Element | null; ele; ele = ele.parentElement) { + if (ele instanceof HTMLAnchorElement) { + eleHref = (typeof ele.href === 'string' ? ele.href : eleHref) || (ele.parentElement && ("href" in ele.parentElement) ? ele.parentElement.href as string: eleHref); + } } const origin = this.webField?.origin; if (eleHref && origin) { @@ -850,10 +852,10 @@ export class WebBox extends ViewBoxAnnotatableComponent() { return ( { + ref={action((r: HTMLSpanElement) => { if (r) { this._scrollHeight = DivHeight(r); - this.lighttext = Array.from(r.children).some((c: any) => c instanceof HTMLElement && lightOrDark(getComputedStyle(c).color) !== Colors.WHITE); + this.lighttext = Array.from(r.children).some((c: Element) => c instanceof HTMLElement && lightOrDark(getComputedStyle(c).color) !== Colors.WHITE); } })} contentEditable @@ -1001,7 +1003,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { }; _innerCollectionView: CollectionFreeFormView | undefined; zoomScaling = () => this._innerCollectionView?.zoomScaling() ?? 1; - setInnerContent = (component: ViewBoxInterface) => { + setInnerContent = (component: ViewBoxInterface) => { this._innerCollectionView = component as CollectionFreeFormView; }; @@ -1083,7 +1085,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { @computed get webpage() { TraceMobx(); const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; - const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as any); + const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as "none" | "all" | "visiblePainted" | undefined) const scale = previewScale * (this._props.NativeDimScaling?.() || 1); return (
() { anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; transparentFilter = () => [...this._props.childFilters(), ClientUtils.TransparentBackgroundFilter]; opaqueFilter = () => [...this._props.childFilters(), ClientUtils.noDragDocsFilter, ...(SnappingManager.CanEmbed ? [] : [ClientUtils.OpaqueBackgroundFilter])]; - childStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { + childStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (doc instanceof Doc && property === StyleProp.PointerEvents) { if (this.inlineTextAnnotations.includes(doc)) return 'none'; } @@ -1168,7 +1170,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { render() { TraceMobx(); const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; - const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as any); + const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as 'none' | 'all' | 'visiblePainted' | undefined); const scale = previewScale * (this._props.NativeDimScaling?.() || 1); return (
() { pointerEvents: this.pointerEvents(), // position: SnappingManager.IsDragging ? 'absolute' : undefined, }}> -
+
(); private _sidebarTagRef = React.createRef(); private _ref: React.RefObject = React.createRef(); private _scrollRef: HTMLDivElement | null = null; - private _editorView: Opt; + private _editorView: Opt; public _applyingChange: string = ''; private _inDrop = false; private _finishingLink = false; @@ -108,79 +108,40 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent; - private _keymap: any = undefined; + private _keymap: KeyMap | undefined = undefined; private _rules: RichTextRules | undefined; private _forceUncollapse = true; // if the cursor doesn't move between clicks, then the selection will disappear for some reason. This flags the 2nd click as happening on a selection which allows bullet points to toggle private _break = true; public ProseRef?: HTMLDivElement; - public get EditorView() { - return this._editorView; - } - public get SidebarKey() { - return this.fieldKey + '_sidebar'; - } - @computed get allSidebarDocs() { - return DocListCast(this.dataDoc[this.SidebarKey]); - } - - @computed get noSidebar() { - return this.DocumentView?.()._props.hideDecorationTitle || this._props.noSidebar || this.Document._layout_noSidebar; - } - @computed get layout_sidebarWidthPercent() { - return this._showSidebar ? '20%' : StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); - } - @computed get sidebarColor() { - return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this.fieldKey + '_backgroundColor'], '#e4e4e4')); - } - @computed get layout_autoHeight() { - return (this._props.forceAutoHeight || this.layoutDoc._layout_autoHeight) && !this._props.ignoreAutoHeight; - } - @computed get textHeight() { - return NumCast(this.dataDoc[this.fieldKey + '_height']); - } - @computed get scrollHeight() { - return NumCast(this.dataDoc[this.fieldKey + '_scrollHeight']); - } - @computed get sidebarHeight() { - return !this.sidebarWidth() ? 0 : NumCast(this.dataDoc[this.SidebarKey + '_height']); - } - @computed get titleHeight() { - return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin) || 0; - } - @computed get layout_autoHeightMargins() { - return this.titleHeight + NumCast(this.layoutDoc._layout_autoHeightMargins); - } - @computed get _recordingDictation() { - return this.dataDoc?.mediaState === mediaState.Recording; - } - set _recordingDictation(value) { - !this.dataDoc[`${this.fieldKey}_recordingSource`] && (this.dataDoc.mediaState = value ? mediaState.Recording : undefined); - } + set _recordingDictation(value) { !this.dataDoc[`${this.fieldKey}_recordingSource`] && (this.dataDoc.mediaState = value ? mediaState.Recording : undefined); } + @computed get _recordingDictation() { return this.dataDoc?.mediaState === mediaState.Recording; } // prettier-ignore + @computed get allSidebarDocs() { return DocListCast(this.dataDoc[this.SidebarKey]); } // prettier-ignore + @computed get noSidebar() { return this.DocumentView?.()._props.hideDecorationTitle || this._props.noSidebar || this.Document._layout_noSidebar; } // prettier-ignore + @computed get layout_sidebarWidthPercent() { return this._showSidebar ? '20%' : StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); } // prettier-ignore + @computed get sidebarColor() { return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this.fieldKey + '_backgroundColor'], '#e4e4e4')); } // prettier-ignore + @computed get layout_autoHeight() { return (this._props.forceAutoHeight || this.layoutDoc._layout_autoHeight) && !this._props.ignoreAutoHeight; } // prettier-ignore + @computed get textHeight() { return NumCast(this.dataDoc[this.fieldKey + '_height']); } // prettier-ignore + @computed get scrollHeight() { return NumCast(this.dataDoc[this.fieldKey + '_scrollHeight']); } // prettier-ignore + @computed get sidebarHeight() { return !this.sidebarWidth() ? 0 : NumCast(this.dataDoc[this.SidebarKey + '_height']); } // prettier-ignore + @computed get titleHeight() { return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin) as number || 0; } // prettier-ignore + @computed get layout_autoHeightMargins() { return this.titleHeight + NumCast(this.layoutDoc._layout_autoHeightMargins); } // prettier-ignore @computed get config() { this._keymap = buildKeymap(schema, this._props); this._rules = new RichTextRules(this.Document, this); - return { - schema, - plugins: [ - inputRules(this._rules.inpRules), - this.richTextMenuPlugin(), - history(), - keymap(this._keymap), - keymap(baseKeymap), - new Plugin({ props: { attributes: { class: 'ProseMirror-example-setup-style' } } }), - new Plugin({ - view(/* editorView */) { - return new FormattedTextBoxComment(); - }, - }), - ], - }; + return { schema, + plugins: [ + inputRules(this._rules.inpRules), + this.richTextMenuPlugin(), + history(), + keymap(this._keymap), + keymap(baseKeymap), + new Plugin({ props: { attributes: { class: 'ProseMirror-example-setup-style' } } }), + new Plugin({ view: () => new FormattedTextBoxComment() }), + ] }; } - // State for GPT - @observable - private gptRes: string = ''; - + public get EditorView() { return this._editorView; } + public get SidebarKey() { return this.fieldKey + '_sidebar'; } public makeAIFlashcards: () => void = unimplementedFunction; public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined; @@ -205,9 +166,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - const foundLinkAnchors = findLinkMark(node.marks)?.attrs.allAnchors.filter((a: any) => a.anchorId === a1[Id] || a.anchorId === a2[Id]) || []; + let allFoundLinkAnchors: { href: string; title: string; anchorId: string }[] = []; + state.doc.nodesBetween(0, state.doc.nodeSize - 2, (node: Node /* , pos: number, parent: any */) => { + const foundLinkAnchors = findLinkMark(node.marks)?.attrs.allAnchors.filter((a: { href: string; title: string; anchorId: string }) => a.anchorId === a1[Id] || a.anchorId === a2[Id]) || []; allFoundLinkAnchors = foundLinkAnchors.length ? foundLinkAnchors : allFoundLinkAnchors; return true; }); @@ -255,7 +216,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent void = emptyFunction; const targetData = target[DocData]; targetData.mediaState = mediaState.Recording; DictationManager.recordAudioAnnotation(targetData, Doc.LayoutFieldKey(target), stop => { stopFunc = stop }); // prettier-ignore @@ -273,10 +234,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - this._editorView?.state && RichTextMenu.Instance?.setFontField(color, 'fontHighlight'); - return undefined; - }, 'highlght text'); + AnchorMenu.Instance.Highlight = undoable((color: string) => this._editorView?.state && RichTextMenu.Instance?.setFontField(color, 'fontHighlight'), 'highlght text'); AnchorMenu.Instance.onMakeAnchor = () => this.getAnchor(true); AnchorMenu.Instance.StartCropDrag = unimplementedFunction; /** @@ -292,7 +250,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent this.getAnchor(true), targetCreator), e.pageX, e.pageY); + const docView = this.DocumentView?.(); + docView && DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(docView, () => this.getAnchor(true), targetCreator), e.pageX, e.pageY); }); AnchorMenu.Instance.setSelectedText(window.getSelection()?.toString() ?? ''); @@ -345,7 +304,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + state.tr.doc.nodesBetween(0, state.doc.content.size, (node: Node /* , pos: number, parent: any */) => { if (node.type === schema.nodes.dashField && node.attrs.fieldKey.startsWith('#')) { accumTags.push(node.attrs.fieldKey); } @@ -410,8 +369,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent) => { + hyperlinkTerm = (trIn: Transaction, target: Doc, newAutoLinks: Set) => { let tr = trIn; const editorView = this._editorView; if (editorView && !Doc.AreProtosEqual(target, this.Document)) { @@ -493,7 +452,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + tr.doc.nodesBetween(sel.from, sel.to, (node: Node, pos: number /* , parent: any */) => { if (node.firstChild === null && !node.marks.find((m: Mark) => m.type.name === schema.marks.noAutoLinkAnchor.name) && node.marks.find((m: Mark) => m.type.name === schema.marks.splitter.name)) { alink = alink ?? @@ -646,15 +605,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { const cm = ContextMenu.Instance; - let target = e.target as any; // hrefs are stored on the database of the node that wraps the hyerlink - while (target && !target.dataset?.targethrefs) target = target.parentElement; + let target:Element|HTMLElement|null = e.target as HTMLElement; // hrefs are stored on the database of the node that wraps the hyerlink + while (target && (!(target instanceof HTMLElement) || !target.dataset?.targethrefs)) target = target.parentElement; const editor = this._editorView; if (editor && target && !(e.nativeEvent instanceof simMouseEvent ? e.nativeEvent.dash : false)) { const hrefs = (target.dataset?.targethrefs as string) @@ -1107,7 +1066,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + tr.doc.nodesBetween(selection.from, selection.to, (node: Node, pos: number /* , parent: any */) => { if (node.firstChild === null && node.marks.find((m: Mark) => m.type.name === schema.marks.splitter.name)) { const allAnchors = [{ href, title, anchorId: anchor[Id] }]; allAnchors.push(...(node.marks.find((m: Mark) => m.type.name === schema.marks.linkAnchor.name)?.attrs.allAnchors ?? [])); @@ -1184,17 +1143,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent= 0) { + const firstChild = ret.frag.childCount ? ret.frag.child(0) : undefined; + if (ret.start >= 0 && (ret.frag.size || (firstChild && [state.schema.nodes.dashDoc, state.schema.nodes.audioTag].includes(firstChild.type)))) { !options.instant && (this._focusSpeed = focusSpeed); - let selection = TextSelection.near(editor.state.doc.resolve(ret.start)); // default to near the start + let selection = TextSelection.near(state.doc.resolve(ret.start)); // default to near the start if (ret.frag.firstChild) { - selection = TextSelection.between(editor.state.doc.resolve(ret.start), editor.state.doc.resolve(ret.start + ret.frag.firstChild.nodeSize)); // bcz: looks better to not have the target selected + selection = TextSelection.between(state.doc.resolve(ret.start), state.doc.resolve(ret.start + ret.frag.firstChild.nodeSize)); // bcz: looks better to not have the target selected } - editor.dispatch(editor.state.tr.setSelection(new TextSelection(selection.$from, selection.$from)).scrollIntoView()); + this._editorView.dispatch(state.tr.setSelection(new TextSelection(selection.$from, selection.$from)).scrollIntoView()); const escAnchorId = textAnchorId[0] >= '0' && textAnchorId[0] <= '9' ? `\\3${textAnchorId[0]} ${textAnchorId.substr(1)}` : textAnchorId; addStyleSheetRule(FormattedTextBox._highlightStyleSheet, `${escAnchorId}`, { background: 'yellow', transform: 'scale(3)', 'transform-origin': 'left bottom' }); setTimeout(() => { @@ -1405,41 +1364,36 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - self._props.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView); - }); + return new Plugin({view : action((newView: EditorView) => { + this._props.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView); return new RichTextMenuPlugin({ editorProps: this._props }); - }, - }); - } + })}); + }; _didScroll = false; _scrollStopper: undefined | (() => void); + // eslint-disable-next-line @typescript-eslint/no-explicit-any setupEditor(config: any, fieldKey: string) { const curText = Cast(this.dataDoc[this.fieldKey], RichTextField, null) || StrCast(this.dataDoc[this.fieldKey]); const rtfField = Cast((!curText && this.layoutDoc[this.fieldKey]) || this.dataDoc[fieldKey], RichTextField); if (this.ProseRef) { - const self = this; this._editorView?.destroy(); this._editorView = new EditorView(this.ProseRef, { state: rtfField?.Data ? EditorState.fromJSON(config, JSON.parse(rtfField.Data)) : EditorState.create(config), handleScrollToSelection: editorView => { const docPos = editorView.coordsAtPos(editorView.state.selection.to); - const viewRect = self._ref.current!.getBoundingClientRect(); - const scrollRef = self._scrollRef; + const viewRect = this._ref.current!.getBoundingClientRect(); + const scrollRef = this._scrollRef; const topOff = docPos.top < viewRect.top ? docPos.top - viewRect.top : undefined; const botOff = docPos.bottom > viewRect.bottom ? docPos.bottom - viewRect.bottom : undefined; if (((topOff && Math.abs(Math.trunc(topOff)) > 0) || (botOff && Math.abs(Math.trunc(botOff)) > 0)) && scrollRef) { const shift = Math.min(topOff ?? Number.MAX_VALUE, botOff ?? Number.MAX_VALUE); - const scrollPos = scrollRef.scrollTop + shift * self.ScreenToLocalBoxXf().Scale; + const scrollPos = scrollRef.scrollTop + shift * this.ScreenToLocalBoxXf().Scale; if (this._focusSpeed !== undefined) { setTimeout(() => { scrollPos && (this._scrollStopper = smoothScroll(this._focusSpeed || 0, scrollRef, scrollPos, 'ease', this._scrollStopper)); @@ -1470,7 +1424,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - if ((e.nativeEvent as any).handledByInnerReactInstance) { - return; // e.stopPropagation(); - } - (e.nativeEvent as any).handledByInnerReactInstance = true; - if (this.Document.forceActive) e.stopPropagation(); this.tryUpdateScrollHeight(); // if a doc a fitWidth doc is being viewed in different embedContainer (eg freeform & lightbox), then it will have conflicting heights. so when the doc is clicked on, we want to make sure it has the appropriate height for the selected view. - if ((e.target as any).tagName === 'AUDIOTAG') { + const target = e.target as HTMLElement; + if (target.tagName === 'AUDIOTAG') { e.preventDefault(); e.stopPropagation(); - const timecode = Number((e.target as any)?.dataset?.timecode); - DocServer.GetRefField((e.target as any)?.dataset?.audioid || 0).then(anchor => { + const timecode = Number(target.dataset?.timecode); + DocServer.GetRefField(target.dataset?.audioid || "").then(anchor => { if (anchor instanceof Doc) { // const timecode = NumCast(anchor.timecodeToShow, 0); const audiodoc = anchor.annotationOn as Doc; @@ -1583,7 +1533,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent node that wraps the hyerlink - for (let { target } = e as any; target && !target.dataset?.targethrefs; target = target.parentElement); - while (clickTarget && !clickTarget.dataset?.targethrefs) clickTarget = clickTarget.parentElement; - FormattedTextBoxComment.update(this, this.EditorView!, undefined, clickTarget?.dataset?.targethrefs, clickTarget?.dataset.linkdoc, clickTarget?.dataset.nopreview === 'true'); + let clickTarget:HTMLElement|Element|null = e.target as HTMLElement; // hrefs are stored on the dataset of the node that wraps the hyerlink + for (let target:HTMLElement|Element|null = clickTarget as HTMLElement; target instanceof HTMLElement && !target.dataset?.targethrefs; target = target.parentElement); + while (clickTarget instanceof HTMLElement && !clickTarget.dataset?.targethrefs) clickTarget = clickTarget.parentElement; + const dataset = clickTarget instanceof HTMLElement ? clickTarget?.dataset : undefined; + FormattedTextBoxComment.update(this, this.EditorView!, undefined, dataset?.targethrefs, dataset?.linkdoc, dataset?.nopreview === 'true'); } }; @action @@ -1626,27 +1577,24 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { const pos = ipos ?? (this._editorView?.state.selection.$from.pos || 1); setTimeout(() => this._editorView?.dispatch(this._editorView.state.tr.setSelection(TextSelection.near(this._editorView.state.doc.resolve(pos)))), 100); - setTimeout(() => (this.ProseRef?.children?.[0] as any).focus(), 200); + setTimeout(() => (this.ProseRef?.children?.[0] as HTMLElement).focus(), 200); }; @action onFocused = (e: React.FocusEvent): void => { // applyDevTools.applyDevTools(this._editorView); - this.ProseRef?.children[0] === e.nativeEvent.target && this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this._props, this.layoutDoc); e.stopPropagation(); }; onClick = (e: React.MouseEvent): void => { if (!this._props.isContentActive()) return; - if ((e.nativeEvent as any).handledByInnerReactInstance) { - e.stopPropagation(); - return; - } - if (!this._forceUncollapse || (this._editorView!.root as any).getSelection().isCollapsed) { + const editorView = this._editorView; + const editorRoot = editorView?.root instanceof Document ?editorView.root : undefined; + if (editorView && (!this._forceUncollapse || editorRoot?.getSelection()?.isCollapsed)) { // this is a hack to allow the cursor to be placed at the end of a document when the document ends in an inline dash comment. Apparently Chrome on Windows has a bug/feature which breaks this when clicking after the end of the text. - const pcords = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY }); - const node = pcords && this._editorView!.state.doc.nodeAt(pcords.pos); // get what prosemirror thinks the clicked node is (if it's null, then we didn't click on any text) - if (pcords && node?.type === this._editorView!.state.schema.nodes.dashComment) { - this._editorView!.dispatch(this._editorView!.state.tr.setSelection(TextSelection.create(this._editorView!.state.doc, pcords.pos + 2))); + const pcords = editorView.posAtCoords({ left: e.clientX, top: e.clientY }); + const node = pcords && editorView.state.doc.nodeAt(pcords.pos); // get what prosemirror thinks the clicked node is (if it's null, then we didn't click on any text) + if (pcords && node?.type === editorView.state.schema.nodes.dashComment) { + this._editorView!.dispatch(editorView.state.tr.setSelection(TextSelection.create(editorView.state.doc, pcords.pos + 2))); e.preventDefault(); } if (!node && this.ProseRef) { @@ -1654,19 +1602,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent boundsRect.left && e.clientX < boundsRect.right && e.clientY > boundsRect.bottom) { // if we clicked below the last prosemirror div, then set the selection to be the end of the document - this._editorView?.focus(); - this._editorView!.dispatch(this._editorView!.state.tr.setSelection(TextSelection.create(this._editorView!.state.doc, this._editorView!.state.doc.content.size))); + editorView.focus(); + editorView.dispatch(editorView.state.tr.setSelection(TextSelection.create(editorView.state.doc, editorView.state.doc.content.size))); } - } else if (node && [this._editorView!.state.schema.nodes.ordered_list, this._editorView!.state.schema.nodes.listItem].includes(node.type) && node !== (this._editorView!.state.selection as NodeSelection)?.node && pcords) { - this._editorView!.dispatch(this._editorView!.state.tr.setSelection(NodeSelection.create(this._editorView!.state.doc, pcords.pos))); + } else if (node && [editorView.state.schema.nodes.ordered_list, editorView.state.schema.nodes.listItem].includes(node.type) && node !== (editorView.state.selection as NodeSelection)?.node && pcords) { + editorView.dispatch(editorView.state.tr.setSelection(NodeSelection.create(editorView.state.doc, pcords.pos))); } } - if (this._props.rootSelected?.()) { + if (editorView && this._props.rootSelected?.()) { // if text box is selected, then it consumes all click events - (e.nativeEvent as any).handledByInnerReactInstance = true; - this.hitBulletTargets(e.clientX, e.clientY, !this._editorView?.state.selection.empty || this._forceUncollapse, false, e.shiftKey); + e.stopPropagation(); + this.hitBulletTargets(e.clientX, e.clientY, !editorView.state.selection.empty || this._forceUncollapse, false, e.shiftKey); } - this._forceUncollapse = !(this._editorView!.root as any).getSelection().isCollapsed; + this._forceUncollapse = !editorRoot?.getSelection()?.isCollapsed; }; // this hackiness handles clicking on the list item bullets to do expand/collapse. the bullets are ::before pseudo elements so there's no real way to hit test against them. hitBulletTargets(x: number, y: number, collapse: boolean, highlightOnly: boolean, selectOrderedList: boolean = false) { @@ -1682,9 +1630,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent 3) { + if ($olistPos && $olistPos.depth) { olistNode = $olistPos.parent; - $olistPos = this._editorView?.state.doc.resolve(($olistPos as any).path[($olistPos as any).path.length - 4]); + $olistPos = this._editorView?.state.doc.resolve($olistPos.start($olistPos.depth - 1)); } } const maxSize = this._editorView?.state.doc.content.size ?? 0; @@ -1715,7 +1663,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + onBlur = (e: React.FocusEvent) => { if (this.ProseRef?.children[0] !== e.nativeEvent.target) return; if (!(this.EditorView?.state.selection instanceof NodeSelection) || this.EditorView.state.selection.node.type !== this.EditorView.state.schema.nodes.footnote) { const stordMarks = this._editorView?.state.storedMarks?.slice(); @@ -1780,7 +1728,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent d?.author).length; const color = !annotated ? Colors.WHITE : Colors.BLACK; - const backgroundColor = !annotated ? (this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK) : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.WidgetColor + (annotated ? ':annotated' : '')); + const backgroundColor = !annotated ? (this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK) : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.WidgetColor + (annotated ? ':annotated' : '')) as string; return !annotated && (!this._props.isContentActive() || SnappingManager.IsDragging || Doc.ActiveTool !== InkTool.None) ? null : (
{ + // eslint-disable-next-line @typescript-eslint/no-explicit-any const ComponentTag: any = tag === CollectionViewType.Tree ? CollectionTreeView : tag === 'translation' ? FormattedTextBox : CollectionStackingView; return ComponentTag === CollectionStackingView ? ( { + let child: Node | undefined; + state.doc.nodesBetween(state.selection.from, state.selection.to, (node: Node /* , pos: number, parent: any */) => { !child && node.marks.length && (child = node); }); const mark = child && findOtherUserMark(child.marks); diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index a612f3c65..247b7c097 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -5,7 +5,7 @@ import { observer } from 'mobx-react'; import { lift, wrapIn } from 'prosemirror-commands'; import { Mark, MarkType } from 'prosemirror-model'; import { wrapInList } from 'prosemirror-schema-list'; -import { EditorState, NodeSelection, TextSelection } from 'prosemirror-state'; +import { EditorState, NodeSelection, TextSelection, Transaction } from 'prosemirror-state'; import { EditorView } from 'prosemirror-view'; import * as React from 'react'; import { Doc } from '../../../../fields/Doc'; @@ -17,7 +17,7 @@ import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocumentView } from '../DocumentView'; import { EquationBox } from '../EquationBox'; import { FieldViewProps } from '../FieldView'; -import { FormattedTextBox } from './FormattedTextBox'; +import { FormattedTextBox, FormattedTextBoxProps } from './FormattedTextBox'; import { updateBullets } from './ProsemirrorExampleTransfer'; import './RichTextMenu.scss'; import { schema } from './schema_rts'; @@ -35,8 +35,8 @@ export class RichTextMenu extends AntimodeMenu { private _linkToRef = React.createRef(); layoutDoc: Doc | undefined; - @observable public view?: EditorView = undefined; - public editorProps: FieldViewProps | undefined; + @observable public view?: EditorView & { TextView ?: FormattedTextBox } = undefined; + public editorProps: FieldViewProps | AntimodeMenuProps |undefined; public _brushMap: Map> = new Map(); @@ -114,17 +114,17 @@ export class RichTextMenu extends AntimodeMenu { } _disposer: IReactionDisposer | undefined; componentDidMount() { - this._disposer = reaction( - () => DocumentView.Selected().slice(), - () => this.updateMenu(undefined, undefined, undefined, undefined) - ); + // this._disposer = reaction( + // () => DocumentView.Selected().slice(), + // () => this.updateMenu(undefined, undefined, undefined, undefined) + // ); } componentWillUnmount() { this._disposer?.(); } @action - public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any, layoutDoc: Doc | undefined) { + public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: FormattedTextBoxProps|AntimodeMenuProps|undefined, layoutDoc: Doc | undefined) { if (this._linkToRef.current?.getBoundingClientRect().width) { return; } @@ -158,7 +158,7 @@ export class RichTextMenu extends AntimodeMenu { this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle)); } - setMark = (mark: Mark, state: EditorState, dispatch: any, dontToggle: boolean = false) => { + setMark = (mark: Mark, state: EditorState, dispatch: (tr:Transaction) => void, dontToggle: boolean = false) => { if (mark) { const newPos = state.selection.$anchor.node()?.type === schema.nodes.ordered_list ? state.selection.from : state.selection.from; const node = (state.selection as NodeSelection).node ?? (newPos >= 0 ? state.doc.nodeAt(newPos) : undefined); @@ -177,17 +177,18 @@ export class RichTextMenu extends AntimodeMenu { toggleMark(mark.type, mark.attrs)(state, dispatch); } } - this.updateMenu(this.view, undefined, undefined, this.layoutDoc); + // this.updateMenu(this.view, undefined, undefined, this.layoutDoc); } }; // finds font sizes and families in selection - getActiveAlignment() { + getActiveAlignment = () => { if (this.view && this.TextView?._props.rootSelected?.()) { - const { path } = this.view.state.selection.$from as any; - for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) { - if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) { - return path[i].attrs.align || 'left'; + const from = this.view.state.selection.$from; + for (let i = from.depth; i >= 0; i--) { + const node = from.node(i); + if (node.type === this.view.state.schema.nodes.paragraph || node.type === this.view.state.schema.nodes.heading) { + return node.attrs.align || 'left'; } } } @@ -195,7 +196,7 @@ export class RichTextMenu extends AntimodeMenu { } // finds font sizes and families in selection - getActiveListStyle() { + getActiveListStyle = () => { const state = this.view?.state; if (state) { const pos = state.selection.$anchor; @@ -321,7 +322,7 @@ export class RichTextMenu extends AntimodeMenu { if (this.view) { const mark = this.view.state.schema.mark(this.view.state.schema.marks.noAutoLinkAnchor); this.setMark(mark, this.view.state, this.view.dispatch, false); - this.TextView.autoLink(); + this.TextView?.autoLink(); this.view.focus(); } }; @@ -350,7 +351,7 @@ export class RichTextMenu extends AntimodeMenu { }; setFontField = (value: string, fontField: 'fontSize' | 'fontFamily' | 'fontColor' | 'fontHighlight') => { - if (this.view) { + if (this.TextView && this.view) { const { text, paragraph } = this.view.state.schema.nodes; const selNode = this.view.state.selection.$anchor.node(); if (this.view.state.selection.from === 1 && this.view.state.selection.empty && [undefined, text, paragraph].includes(selNode?.type)) { @@ -360,11 +361,11 @@ export class RichTextMenu extends AntimodeMenu { const attrs: { [key: string]: string } = {}; attrs[fontField] = value; const fmark = this.view?.state.schema.marks['pF' + fontField.substring(1)].create(attrs); - this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true); + this.setMark(fmark, this.view.state, (tx: Transaction) => this.view!.dispatch(tx.addStoredMark(fmark)), true); this.view.focus(); } else { Doc.UserDoc()[fontField] = value; - this.updateMenu(this.view, undefined, this.props, this.layoutDoc); + // this.updateMenu(this.view, undefined, this.props, this.layoutDoc); } }; @@ -383,17 +384,17 @@ export class RichTextMenu extends AntimodeMenu { marks && tx2.setStoredMarks([...marks]); this.view.dispatch(tx2); } else - !wrapInList(schema.nodes.ordered_list)(this.view.state, (tx2: any) => { + !wrapInList(schema.nodes.ordered_list)(this.view.state, (tx2: Transaction) => { const tx3 = updateBullets(tx2, schema, newMapStyle, this.view!.state.selection.from - 1, this.view!.state.selection.to + 1); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); this.view!.dispatch(tx3); }); this.view.focus(); - this.updateMenu(this.view, undefined, this.props, this.layoutDoc); + // this.updateMenu(this.view, undefined, this.props, this.layoutDoc); }; - insertSummarizer(state: EditorState, dispatch: any) { + insertSummarizer(state: EditorState, dispatch: (tr:Transaction) => void) { if (state.selection.empty) return false; const mark = state.schema.marks.summarize.create(); const { tr } = state; @@ -407,7 +408,7 @@ export class RichTextMenu extends AntimodeMenu { vcenterToggle = () => { this.layoutDoc && (this.layoutDoc._layout_centered = !this.layoutDoc._layout_centered); }; - align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => { + align = (view: EditorView, dispatch: (tr:Transaction) => void, alignment: 'left' | 'right' | 'center') => { if (this.TextView?._props.rootSelected?.()) { let { tr } = view.state; view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos) => { @@ -423,7 +424,7 @@ export class RichTextMenu extends AntimodeMenu { } }; - paragraphSetup(state: EditorState, dispatch: any, field: 'inset' | 'indent', value?: 0 | 10 | -10) { + paragraphSetup(state: EditorState, dispatch: (tr:Transaction) => void, field: 'inset' | 'indent', value?: 0 | 10 | -10) { let { tr } = state; state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => { if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) { @@ -439,9 +440,9 @@ export class RichTextMenu extends AntimodeMenu { return true; } - insertBlockquote(state: EditorState, dispatch: any) { - const { path } = state.selection.$from as any; - if (path.length > 6 && path[path.length - 6].type === schema.nodes.blockquote) { + insertBlockquote(state: EditorState, dispatch: (tr:Transaction) => void) { + const node = state.selection.$from.depth ? state.selection.$from.node(state.selection.$from.depth-1): undefined; + if (node?.type === schema.nodes.blockquote) { lift(state, dispatch); } else { wrapIn(schema.nodes.blockquote)(state, dispatch); @@ -449,7 +450,7 @@ export class RichTextMenu extends AntimodeMenu { return true; } - insertHorizontalRule(state: EditorState, dispatch: any) { + insertHorizontalRule(state: EditorState, dispatch: (tr:Transaction) => void) { dispatch(state.tr.replaceSelectionWith(state.schema.nodes.horizontal_rule.create()).scrollIntoView()); return true; } @@ -497,7 +498,7 @@ export class RichTextMenu extends AntimodeMenu { } get TextView() { - return (this.view as any)?.TextView as FormattedTextBox; + return this.view?.TextView; } get TextViewFieldKey() { return this.TextView?._props.fieldKey; @@ -512,11 +513,9 @@ export class RichTextMenu extends AntimodeMenu { } createLinkButton() { - const self = this; - - function onLinkChange(e: React.ChangeEvent) { - self.TextView?.endUndoTypingBatch(); - UndoManager.RunInBatch(() => self.setCurrentLink(e.target.value), 'link change'); + const onLinkChange = (e: React.ChangeEvent) => { + this.TextView?.endUndoTypingBatch(); + UndoManager.RunInBatch(() => this.setCurrentLink(e.target.value), 'link change'); } const link = this.currentLink ? this.currentLink : ''; @@ -524,7 +523,6 @@ export class RichTextMenu extends AntimodeMenu { const button = ( set hyperlink
} placement="bottom"> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label @@ -589,7 +587,7 @@ export class RichTextMenu extends AntimodeMenu { // TODO: should check for valid URL @undoBatch makeLinkToURL = (target: string) => { - ((this.view as any)?.TextView as FormattedTextBox).makeLinkAnchor(undefined, 'onRadd:rightight', target, target); + this.TextView?.makeLinkAnchor(undefined, 'onRadd:rightight', target, target); }; @undoBatch @@ -597,12 +595,12 @@ export class RichTextMenu extends AntimodeMenu { if (this.view) { const linkAnchor = this.view.state.selection.$from.nodeAfter?.marks.find(m => m.type === this.view!.state.schema.marks.linkAnchor); if (linkAnchor) { - const allAnchors = linkAnchor.attrs.allAnchors.slice(); - this.TextView.RemoveAnchorFromSelection(allAnchors); + const allAnchors = (linkAnchor.attrs.allAnchors as { href: string; title: string; linkId: string; targetId: string; }[]).slice(); + this.TextView?.RemoveAnchorFromSelection(allAnchors); // bcz: Argh ... this will remove the link from the document even it's anchored somewhere else in the text which happens if only part of the anchor text was selected. allAnchors - .filter((aref: any) => aref?.href.indexOf(Doc.localServerPath()) === 0) - .forEach((aref: any) => { + .filter(aref => aref?.href.indexOf(Doc.localServerPath()) === 0) + .forEach(aref => { const anchorId = aref.href.replace(Doc.localServerPath(), '').split('?')[0]; anchorId && DocServer.GetRefField(anchorId).then(linkDoc => Doc.DeleteLink?.(linkDoc as Doc)); }); @@ -629,7 +627,7 @@ export class ButtonDropdown extends ObservableReactComponent {this._props.button} { - // eslint-disable-next-line jsx-a11y/control-has-associated-label @@ -697,12 +694,12 @@ export class ButtonDropdown extends ObservableReactComponent { // eslint-disable-next-line react/no-unused-class-component-methods - update(view: EditorView, lastState: EditorState | undefined) { - RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps, (view as any).TextView?.layoutDoc); + update(view: EditorView & {TextView ?: FormattedTextBox}, lastState: EditorState | undefined) { + RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps, view.TextView?.layoutDoc); } render() { return null; diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index 2f6824466..03585a8b7 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -25,7 +25,7 @@ export class AnchorMenu extends AntimodeMenu { private _commentRef = React.createRef(); private _cropRef = React.createRef(); - constructor(props: any) { + constructor(props: AntimodeMenuProps) { super(props); makeObservable(this); AnchorMenu.Instance = this; @@ -50,7 +50,7 @@ export class AnchorMenu extends AntimodeMenu { public OnAudio: (e: PointerEvent) => void = unimplementedFunction; public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction; public StartCropDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction; - public Highlight: (color: string) => Opt = (/* color: string */) => undefined; + public Highlight: (color: string) => void = emptyFunction; public GetAnchor: (savedAnnotations: Opt>, addAsAnnotation: boolean) => Opt = emptyFunction; public Delete: () => void = unimplementedFunction; public PinToPres: () => void = unimplementedFunction; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index fa5e5cedb..1279563ef 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as Pdfjs from 'pdfjs-dist'; @@ -64,13 +62,13 @@ export class PDFViewer extends ObservableReactComponent { } @observable _pageSizes: { width: number; height: number }[] = []; - @observable _savedAnnotations = new ObservableMap(); + @observable _savedAnnotations = new ObservableMap(); @observable _textSelecting = true; @observable _showWaiting = true; @observable Index: number = -1; - private _pdfViewer: any; - private _styleRule: any; // stylesheet rule for making hyperlinks clickable + private _pdfViewer!: PDFJSViewer.PDFViewer; + private _styleRule: number | undefined; // stylesheet rule for making hyperlinks clickable private _retries = 0; // number of times tried to create the PDF viewer private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void); private _marqueeref = React.createRef(); @@ -107,7 +105,7 @@ export class PDFViewer extends ObservableReactComponent { }); this.setupPdfJsViewer(); this._mainCont.current?.addEventListener('scroll', e => { - (e.target as any).scrollLeft = 0; + (e.target as HTMLElement).scrollLeft = 0; }); this._disposers.layout_autoHeight = reaction( @@ -211,18 +209,12 @@ export class PDFViewer extends ObservableReactComponent { }; pagesinit = () => { - if (this._pdfViewer._setDocumentViewerElement?.offsetParent) { - runInAction(() => { - this._pdfViewer.currentScaleValue = this._props.layoutDoc._freeform_scale = 1; - }); - this.gotoPage(NumCast(this._props.Document._layout_curPage, 1)); - } document.removeEventListener('pagesinit', this.pagesinit); let quickScroll: { loc?: string; easeFunc?: 'ease' | 'linear' } | undefined = { loc: this._initialScroll ? this._initialScroll.loc?.toString() : '', easeFunc: this._initialScroll ? this._initialScroll.easeFunc : undefined }; this._disposers.scale = reaction( () => NumCast(this._props.layoutDoc._freeform_scale, 1), scale => { - this._pdfViewer.currentScaleValue = scale; + this._pdfViewer.currentScaleValue = scale+""; }, { fireImmediately: true } ); @@ -321,7 +313,7 @@ export class PDFViewer extends ObservableReactComponent { } }; - @observable private _scrollTimer: any = undefined; + @observable private _scrollTimer: NodeJS.Timeout | undefined = undefined; onScroll = () => { if (this._mainCont.current && !this._forcedScroll) { @@ -330,7 +322,7 @@ export class PDFViewer extends ObservableReactComponent { this._props.layoutDoc._layout_scrollTop = this._mainCont.current.scrollTop; } this._ignoreScroll = false; - if (this._scrollTimer) clearTimeout(this._scrollTimer); // wait until a scrolling pause, then create an anchor to audio + this._scrollTimer && clearTimeout(this._scrollTimer); // wait until a scrolling pause, then create an anchor to audio this._scrollTimer = setTimeout(() => { CreateLinkToActiveAudio(() => this._props.pdfBox.getAnchor(true)!, false); this._scrollTimer = undefined; @@ -390,8 +382,8 @@ export class PDFViewer extends ObservableReactComponent { this._props.select(false); MarqueeAnnotator.clearAnnotations(this._savedAnnotations); this.isAnnotating = true; - const target = e.target as any; - if (e.target && (target.className.includes('endOfContent') || (target.parentElement.className !== 'textLayer' && target.parentElement.parentElement?.className !== 'textLayer'))) { + const target = e.target as HTMLElement; + if (e.target && (target.className.includes('endOfContent') || (target.parentElement?.className !== 'textLayer' && target.parentElement?.parentElement?.className !== 'textLayer'))) { this._textSelecting = false; } else { // if textLayer is hit, then we select text instead of using a marquee so clear out the marquee. @@ -491,7 +483,7 @@ export class PDFViewer extends ObservableReactComponent { e.stopPropagation(); if (e.ctrlKey) { const curScale = Number(this._pdfViewer.currentScaleValue); - this._pdfViewer.currentScaleValue = Math.max(1, Math.min(10, curScale - (curScale * e.deltaY) / 1000)); + this._pdfViewer.currentScaleValue = Math.max(1, Math.min(10, curScale - (curScale * e.deltaY) / 1000)) + ""; this._props.layoutDoc._freeform_scale = Number(this._pdfViewer.currentScaleValue); } } @@ -520,7 +512,7 @@ export class PDFViewer extends ObservableReactComponent { panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); transparentFilter = () => [...this._props.childFilters(), ClientUtils.TransparentBackgroundFilter]; opaqueFilter = () => [...this._props.childFilters(), ClientUtils.noDragDocsFilter, ...(SnappingManager.CanEmbed && this._props.isContentActive() ? [] : [ClientUtils.OpaqueBackgroundFilter])]; - childStyleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { + childStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (doc instanceof Doc && property === StyleProp.PointerEvents) { if (this.inlineTextAnnotations.includes(doc) || this._props.isContentActive() === false) return 'none'; const isInk = doc.layout_isSvg && !props?.LayoutTemplateString; @@ -531,11 +523,11 @@ export class PDFViewer extends ObservableReactComponent { }; childPointerEvents = () => (this._props.isContentActive() !== false ? 'all' : 'none'); - renderAnnotations = (childFilters: () => string[], mixBlendMode?: any, display?: string) => ( + renderAnnotations = (childFilters: () => string[], mixBlendMode?: 'hard-light' | 'multiply', display?: string) => (
-- cgit v1.2.3-70-g09d2 From 6cf715a76dfb3f6a80fbf7c33e643681ea1a584c Mon Sep 17 00:00:00 2001 From: IEatChili Date: Tue, 30 Jul 2024 14:30:08 -0400 Subject: feat: adjusted ui: --- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/KeywordBox.tsx | 263 +++++++++++++++++++------------ src/client/views/StyleProvider.scss | 26 ++- 3 files changed, 189 insertions(+), 102 deletions(-) diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index dc40562e8..bd6952620 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -832,7 +832,7 @@ export class DocumentDecorations extends ObservableReactComponent DocumentView.Selected()} /> diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx index 321362299..68584a7fa 100644 --- a/src/client/views/KeywordBox.tsx +++ b/src/client/views/KeywordBox.tsx @@ -1,4 +1,4 @@ -import { Colors, IconButton } from 'browndash-components'; +import { Button, Colors, IconButton } from 'browndash-components'; import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; @@ -6,14 +6,11 @@ import { returnFalse, setupMoveUpEvents } from '../../ClientUtils'; import { Doc, DocListCast } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; -import { DocCast, NumCast } from '../../fields/Types'; +import { NumCast, StrCast } from '../../fields/Types'; import { emptyFunction } from '../../Utils'; -import { Docs } from '../documents/Documents'; -import { DocUtils } from '../documents/DocUtils'; -import { DragManager, SetupDrag } from '../util/DragManager'; +import { DocumentType } from '../documents/DocumentTypes'; +import { DragManager } from '../util/DragManager'; import { SnappingManager } from '../util/SnappingManager'; -import { CollectionFreeFormView } from './collections/collectionFreeForm'; -import { MainView } from './MainView'; import { DocumentView } from './nodes/DocumentView'; import { ObservableReactComponent } from './ObservableReactComponent'; @@ -21,11 +18,13 @@ interface KeywordItemProps { doc: Doc; keyword: string; keywordDoc: Doc; - keywordCollection: Doc[]; setToEditing: () => void; isEditing: boolean; } +/** + * A component that handles individual keywords. + */ @observer export class KeywordItem extends ObservableReactComponent { constructor(props: any) { @@ -36,8 +35,12 @@ export class KeywordItem extends ObservableReactComponent { private ref: React.RefObject; + /** + * Gets the documents that a keyword is associated with. + * @returns An array of documents that contain the keyword. + */ getKeywordCollectionDocs = () => { - for (const doc of DocListCast(Doc.UserDoc().myKeywordCollections)) { + for (const doc of DocListCast(Doc.ActiveDashboard?.myKeywordCollections)) { if (doc.title === this._props.keyword) { return doc[DocData].docs; } @@ -45,9 +48,16 @@ export class KeywordItem extends ObservableReactComponent { return null; }; + /** + * Creates a smart collection. + * @returns + */ createCollection = () => { + // Get the documents that contain the keyword. const selected = DocListCast(this.getKeywordCollectionDocs()!); const newEmbeddings = selected.map(doc => Doc.MakeEmbedding(doc)); + + // Create a new collection and set up configurations. const newCollection = ((doc: Doc) => { const docData = doc[DocData]; docData.data = new List(newEmbeddings); @@ -59,9 +69,12 @@ export class KeywordItem extends ObservableReactComponent { newCollection._width = 900; newCollection._height = 900; newCollection.layout_fitWidth = true; - //newCollection[DocData].smartCollection = this._props.keywordDoc; + // Add the collection to the keyword document's list of associated smart collections. this._props.keywordDoc.collections = new List([...DocListCast(this._props.keywordDoc.collections), newCollection]); + newCollection[DocData].data_labels = new List([this._props.keyword]); + newCollection[DocData][`${this._props.keyword}`] = true; + newCollection[DocData].showLabels = true; return newCollection; }; @@ -89,16 +102,24 @@ export class KeywordItem extends ObservableReactComponent { @action removeLabel = () => { if (this._props.doc[DocData].data_labels) { - const filtered_docs = new List(DocListCast(this.getKeywordCollectionDocs()!).filter(doc => doc !== this._props.doc)); - this._props.keywordDoc[DocData].docs = filtered_docs; + if (this._props.doc.type === DocumentType.COL) { + const filtered_collections = new List(DocListCast(this._props.keywordDoc.collections).filter(doc => doc !== this._props.doc)); + this._props.keywordDoc.collections = filtered_collections; - this._props.doc[DocData].data_labels = (this._props.doc[DocData].data_labels as List).filter(label => label !== this._props.keyword) as List; - this._props.doc![DocData][`${this._props.keyword}`] = false; + for (const cur_doc of DocListCast(this.getKeywordCollectionDocs()!, [])) { + this._props.doc[DocData].data = new List(DocListCast(this._props.doc[DocData].data).filter(doc => !Doc.AreProtosEqual(cur_doc, doc))); + } + } else { + const filtered_docs = new List(DocListCast(this.getKeywordCollectionDocs()!).filter(doc => doc !== this._props.doc)); + this._props.keywordDoc[DocData].docs = filtered_docs; - for (const collection of DocListCast(this._props.keywordDoc.collections)) { - collection[DocData].data = new List(DocListCast(collection[DocData].data).filter(doc => !Doc.AreProtosEqual(this._props.doc, doc))); + for (const collection of DocListCast(this._props.keywordDoc.collections)) { + collection[DocData].data = new List(DocListCast(collection[DocData].data).filter(doc => !Doc.AreProtosEqual(this._props.doc, doc))); + } } } + this._props.doc[DocData].data_labels = (this._props.doc[DocData].data_labels as List).filter(label => label !== this._props.keyword) as List; + this._props.doc![DocData][`${this._props.keyword}`] = false; }; render() { @@ -116,6 +137,9 @@ interface KeywordBoxProps { isEditing: boolean; } +/** + * A component that handles the keyword display for documents. + */ @observer export class KeywordBox extends ObservableReactComponent { @observable _currentInput: string = ''; @@ -127,30 +151,32 @@ export class KeywordBox extends ObservableReactComponent { return NumCast((this._props.doc.embedContainer as Doc)?._freeform_scale, 1); } + @computed + get cur_height() { + return this.ref.current?.offsetHeight ? this.ref.current?.offsetHeight : 0; + } + constructor(props: any) { super(props); makeObservable(this); this.ref = React.createRef(); - } - - componentDidMount(): void { - this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; - this._props.doc._keywordHeight = this.height; reaction( - () => this.currentScale, + () => this.cur_height, () => { - if (this.currentScale < 1) { - this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; - this._props.doc._keywordHeight = this.height; - } + this._props.doc[DocData].keywordHeight = this.height; } ); } + componentDidMount(): void { + this.height = this.ref.current?.offsetHeight ? this.ref.current?.offsetHeight : 0; + this._props.doc[DocData].keywordHeight = this.height; + } + componentDidUpdate(prevProps: Readonly): void { - this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; - this._props.doc._keywordHeight = this.height; + this.height = this.ref.current?.offsetHeight ? this.ref.current?.offsetHeight : 0; + this._props.doc[DocData].keywordHeight = this.height; } @action @@ -163,30 +189,44 @@ export class KeywordBox extends ObservableReactComponent { this._props.isEditing = false; }; + /** + * Gets the document associated with a keyword. + * @param keyword The keyword being searched for + * @returns A Doc containing keyword information + */ getKeywordCollection = (keyword: string) => { - for (const doc of DocListCast(Doc.UserDoc().myKeywordCollections)) { + // Look for the keyword document. + for (const doc of DocListCast(Doc.ActiveDashboard!.myKeywordCollections)) { if (doc.title === keyword) { return doc; } } + // If not contained, create a new document and add it to the active Dashboard's keyword list. const keywordCollection = new Doc(); keywordCollection.title = keyword; keywordCollection[DocData].docs = new List(); keywordCollection.collections = new List(); - Doc.UserDoc().myKeywordCollections = new List([...DocListCast(Doc.UserDoc().myKeywordCollections), keywordCollection]); + if (Doc.ActiveDashboard) { + Doc.ActiveDashboard.myKeywordCollections = new List([...DocListCast(Doc.ActiveDashboard.myKeywordCollections), keywordCollection]); + } return keywordCollection; }; - submitLabel = () => { - if (!Doc.UserDoc().myKeywordCollections) { - Doc.UserDoc().myKeywordCollections = new List(); + /** + * Adds the keyword to the document. + * @param keyword + */ + submitLabel = (keyword: string) => { + // If the active Dashboard does not have a keyword collection, create it. + if (Doc.ActiveDashboard && !Doc.ActiveDashboard.myKeywordCollections) { + Doc.ActiveDashboard.myKeywordCollections = new List(); } - const submittedLabel = this._currentInput.trim(); - if (submittedLabel) { - // If the keyword collection is not in the user doc, add it as a new doc, with the keyword as its title. + const submittedLabel = keyword.trim(); + if (submittedLabel && !this._props.doc![DocData][`${submittedLabel}`]) { + // If the keyword collection is not in active Dashboard, add it as a new doc, with the keyword as its title. const keywordCollection = this.getKeywordCollection(submittedLabel); // If the document has no keywords field, create the field. @@ -194,20 +234,31 @@ export class KeywordBox extends ObservableReactComponent { this._props.doc[DocData].data_labels = new List(); } - // Add this document to the keyword's collection of associated documents. - keywordCollection[DocData].docs = new List([...DocListCast(keywordCollection[DocData].docs), this._props.doc]); - - // Push the keyword to the document's keyword list field. - (this._props.doc![DocData].data_labels! as List).push(submittedLabel); - this._props.doc![DocData][`${this._currentInput}`] = true; + // If the document is of type COLLECTION, make it a smart collection, otherwise, add the keyword to the document. + if (this._props.doc.type === DocumentType.COL) { + keywordCollection.collections = new List([...DocListCast(keywordCollection.collections), this._props.doc]); - // Iterate through the keyword document's collections and add a copy of the document to each collection - for (const collection of DocListCast(keywordCollection.collections)) { - const newEmbedding = Doc.MakeEmbedding(this._props.doc); - collection[DocData].data = new List([...DocListCast(collection.data), newEmbedding]); - newEmbedding.embedContainer = collection; + // Iterate through the keyword document's collections and add a copy of the document to each collection + for (const doc of DocListCast(keywordCollection[DocData].docs)) { + const newEmbedding = Doc.MakeEmbedding(doc); + this._props.doc[DocData].data = new List([...DocListCast(this._props.doc[DocData].data), newEmbedding]); + newEmbedding.embedContainer = this._props.doc; + } + } else { + // Add this document to the keyword's collection of associated documents. + keywordCollection[DocData].docs = new List([...DocListCast(keywordCollection[DocData].docs), this._props.doc]); + + // Iterate through the keyword document's collections and add a copy of the document to each collection + for (const collection of DocListCast(keywordCollection.collections)) { + const newEmbedding = Doc.MakeEmbedding(this._props.doc); + collection[DocData].data = new List([...DocListCast(collection.data), newEmbedding]); + newEmbedding.embedContainer = collection; + } } + // Push the keyword to the document's keyword list field. + (this._props.doc![DocData].data_labels! as List).push(submittedLabel); + this._props.doc![DocData][`${submittedLabel}`] = true; this._currentInput = ''; // Clear the input box } }; @@ -223,9 +274,9 @@ export class KeywordBox extends ObservableReactComponent { if (SnappingManager.IsDragging || !(seldoc === this._props.doc) || !this._props.isEditing) { setTimeout( action(() => { - // if ((keywordsList as List).length === 0) { - // this._props.doc[DocData].showLabels = false; - // } + if ((keywordsList as List).length === 0) { + this._props.doc[DocData].showLabels = false; + } this.setToView(); }) ); @@ -237,59 +288,75 @@ export class KeywordBox extends ObservableReactComponent { ref={this.ref} style={{ transformOrigin: 'top left', + overflow: 'hidden', transform: `scale(${1 / this.currentScale})`, backgroundColor: this._props.isEditing ? Colors.LIGHT_GRAY : Colors.TRANSPARENT, borderColor: this._props.isEditing ? Colors.BLACK : Colors.TRANSPARENT, + maxWidth: `400px`, }}> -
- {(keywordsList as List).map(keyword => { - return ( - - ); - })} -
- {this._props.isEditing ? ( -
-
- { - e.key === 'Enter' ? this.submitLabel() : null; - e.stopPropagation(); - }} - type="text" - placeholder="Input keywords for document..." - aria-label="keyword-input" - className="keyword-input" - style={{ width: '100%', borderRadius: '5px' }} - /> -
-
- { - if ((keywordsList as List).length === 0) { - this._props.doc[DocData].showLabels = false; - } else { - this.setToView(); - } - }} - icon={'x'} - style={{ width: '4px' }} - /> -
+
+
+ {(keywordsList as List).map(keyword => { + return ; + })}
- ) : ( -
- )} + {this._props.isEditing ? ( +
+
+ { + e.key === 'Enter' ? this.submitLabel(this._currentInput) : null; + e.stopPropagation(); + }} + type="text" + placeholder="Input keywords for document..." + aria-label="keyword-input" + className="keyword-input" + style={{ width: '100%', borderRadius: '5px' }} + /> +
+ {Doc.ActiveDashboard?.myKeywordCollections ? ( +
+ {DocListCast(Doc.ActiveDashboard?.myKeywordCollections).map(doc => { + const keyword = StrCast(doc.title); + return ( +
+ ) : ( +
+ )} +
+ { + if ((keywordsList as List).length === 0) { + this._props.doc[DocData].showLabels = false; + } else { + this.setToView(); + } + }} + icon={'x'} + style={{ width: '4px' }} + /> +
+
+ ) : ( +
+ )} +
); } diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss index 4267762aa..1d41697f5 100644 --- a/src/client/views/StyleProvider.scss +++ b/src/client/views/StyleProvider.scss @@ -77,14 +77,34 @@ align-items: center; } +.keyword-suggestions-box { + display: flex; + flex-wrap: wrap; + margin: auto; + align-self: center; + width: 90%; + border: 1px solid black; + border-radius: 2px; + margin-top: 8px; +} + +.keyword-suggestion { + cursor: pointer; + padding: 1px 1px; + margin: 2px 2px; + background-color: lightblue; + border: 1px solid black; + border-radius: 5px; + white-space: nowrap; + display: flex; + align-items: center; +} + .keyword-editing-box { margin-top: 8px; } .keyword-input-box { - // display: flex; - // align-items: center; - // align-content: center; margin: auto; align-self: center; width: 90%; -- cgit v1.2.3-70-g09d2 From 426411ca07db203857617f385b14697c4db2f163 Mon Sep 17 00:00:00 2001 From: IEatChili Date: Thu, 1 Aug 2024 14:29:21 -0400 Subject: feat: added groundwork for face recognition --- package-lock.json | 64 ++++++++++ package.json | 1 + src/client/views/Main.tsx | 2 + src/client/views/search/FaceRecognitionHandler.tsx | 86 +++++++++++++ src/server/public/models/age_gender_model-shard1 | Bin 0 -> 429708 bytes .../models/age_gender_model-weights_manifest.json | 1 + .../public/models/face_expression_model-shard1 | Bin 0 -> 329468 bytes .../face_expression_model-weights_manifest.json | 1 + .../public/models/face_landmark_68_model-shard1 | Bin 0 -> 356840 bytes .../face_landmark_68_model-weights_manifest.json | 1 + .../models/face_landmark_68_tiny_model-shard1 | Bin 0 -> 77224 bytes ...ce_landmark_68_tiny_model-weights_manifest.json | 1 + .../public/models/face_recognition_model-shard1 | Bin 0 -> 4194304 bytes .../public/models/face_recognition_model-shard2 | 6 + .../face_recognition_model-weights_manifest.json | 1 + src/server/public/models/mtcnn_model-shard1 | Bin 0 -> 1983400 bytes .../models/mtcnn_model-weights_manifest.json | 1 + .../public/models/ssd_mobilenetv1_model-shard1 | Bin 0 -> 4194304 bytes .../public/models/ssd_mobilenetv1_model-shard2 | 137 +++++++++++++++++++++ .../ssd_mobilenetv1_model-weights_manifest.json | 1 + .../public/models/tiny_face_detector_model-shard1 | Bin 0 -> 193321 bytes .../tiny_face_detector_model-weights_manifest.json | 1 + 22 files changed, 304 insertions(+) create mode 100644 src/client/views/search/FaceRecognitionHandler.tsx create mode 100644 src/server/public/models/age_gender_model-shard1 create mode 100644 src/server/public/models/age_gender_model-weights_manifest.json create mode 100644 src/server/public/models/face_expression_model-shard1 create mode 100644 src/server/public/models/face_expression_model-weights_manifest.json create mode 100644 src/server/public/models/face_landmark_68_model-shard1 create mode 100644 src/server/public/models/face_landmark_68_model-weights_manifest.json create mode 100644 src/server/public/models/face_landmark_68_tiny_model-shard1 create mode 100644 src/server/public/models/face_landmark_68_tiny_model-weights_manifest.json create mode 100644 src/server/public/models/face_recognition_model-shard1 create mode 100644 src/server/public/models/face_recognition_model-shard2 create mode 100644 src/server/public/models/face_recognition_model-weights_manifest.json create mode 100644 src/server/public/models/mtcnn_model-shard1 create mode 100644 src/server/public/models/mtcnn_model-weights_manifest.json create mode 100644 src/server/public/models/ssd_mobilenetv1_model-shard1 create mode 100644 src/server/public/models/ssd_mobilenetv1_model-shard2 create mode 100644 src/server/public/models/ssd_mobilenetv1_model-weights_manifest.json create mode 100644 src/server/public/models/tiny_face_detector_model-shard1 create mode 100644 src/server/public/models/tiny_face_detector_model-weights_manifest.json diff --git a/package-lock.json b/package-lock.json index 6cd2ab605..35b4b6238 100644 --- a/package-lock.json +++ b/package-lock.json @@ -101,6 +101,7 @@ "express-session": "^1.17.3", "express-validator": "^7.0.1", "extract-colors": "^4.0.2", + "face-api.js": "^0.22.2", "ffmpeg": "0.0.4", "file-loader": "^6.2.0", "file-saver": "^2.0.5", @@ -7084,6 +7085,30 @@ "node": ">=14.16" } }, + "node_modules/@tensorflow/tfjs-core": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-1.7.0.tgz", + "integrity": "sha512-uwQdiklNjqBnHPeseOdG0sGxrI3+d6lybaKu2+ou3ajVeKdPEwpWbgqA6iHjq1iylnOGkgkbbnQ6r2lwkiIIHw==", + "dependencies": { + "@types/offscreencanvas": "~2019.3.0", + "@types/seedrandom": "2.4.27", + "@types/webgl-ext": "0.0.30", + "@types/webgl2": "0.0.4", + "node-fetch": "~2.1.2", + "seedrandom": "2.4.3" + }, + "engines": { + "yarn": ">= 1.3.2" + } + }, + "node_modules/@tensorflow/tfjs-core/node_modules/node-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "integrity": "sha512-IHLHYskTc2arMYsHZH82PVX8CSKT5lzb7AXeyO06QnjGDKtkv+pv3mEki6S7reB/x1QPo+YPxQRNEVgR5V/w3Q==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, "node_modules/@tokenizer/token": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", @@ -9424,6 +9449,11 @@ "@types/node": "*" } }, + "node_modules/@types/offscreencanvas": { + "version": "2019.3.0", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz", + "integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==" + }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", @@ -9671,6 +9701,11 @@ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", "optional": true }, + "node_modules/@types/seedrandom": { + "version": "2.4.27", + "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz", + "integrity": "sha512-YvMLqFak/7rt//lPBtEHv3M4sRNA+HGxrhFZ+DQs9K2IkYJbNwVIb8avtJfhDiuaUBX/AW0jnjv48FV8h3u9bQ==" + }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -9786,6 +9821,16 @@ "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.147.tgz", "integrity": "sha512-HubXF+XiMsQBdwhMC9w1aZuSOZ6CvcBR01MA4UdQCbWABkcrSBbMGQ0VnqTJlEU1b78WCx8quv8pznnDXSiUtQ==" }, + "node_modules/@types/webgl-ext": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/webgl-ext/-/webgl-ext-0.0.30.tgz", + "integrity": "sha512-LKVgNmBxN0BbljJrVUwkxwRYqzsAEPcZOe6S2T6ZaBDIrFp0qu4FNlpc5sM1tGbXUYFgdVQIoeLk1Y1UoblyEg==" + }, + "node_modules/@types/webgl2": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/webgl2/-/webgl2-0.0.4.tgz", + "integrity": "sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw==" + }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", @@ -19377,6 +19422,20 @@ "node >=0.6.0" ] }, + "node_modules/face-api.js": { + "version": "0.22.2", + "resolved": "https://registry.npmjs.org/face-api.js/-/face-api.js-0.22.2.tgz", + "integrity": "sha512-9Bbv/yaBRTKCXjiDqzryeKhYxmgSjJ7ukvOvEBy6krA0Ah/vNBlsf7iBNfJljWiPA8Tys1/MnB3lyP2Hfmsuyw==", + "dependencies": { + "@tensorflow/tfjs-core": "1.7.0", + "tslib": "^1.11.1" + } + }, + "node_modules/face-api.js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -37613,6 +37672,11 @@ "resolved": "https://registry.npmjs.org/section-iterator/-/section-iterator-2.0.0.tgz", "integrity": "sha512-xvTNwcbeDayXotnV32zLb3duQsP+4XosHpb/F+tu6VzEZFmIjzPdNk6/O+QOOx5XTh08KL2ufdXeCO33p380pQ==" }, + "node_modules/seedrandom": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz", + "integrity": "sha512-2CkZ9Wn2dS4mMUWQaXLsOAfGD+irMlLEeSP3cMxpGbgyOOzJGFa+MWCOMTOCMyZinHRPxyOj/S/C57li/1to6Q==" + }, "node_modules/selderee": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", diff --git a/package.json b/package.json index bbd2a4c46..019a1e308 100644 --- a/package.json +++ b/package.json @@ -186,6 +186,7 @@ "express-session": "^1.17.3", "express-validator": "^7.0.1", "extract-colors": "^4.0.2", + "face-api.js": "^0.22.2", "ffmpeg": "0.0.4", "file-loader": "^6.2.0", "file-saver": "^2.0.5", diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 8242e7c27..ada934aea 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -61,6 +61,7 @@ import { ImportElementBox } from './nodes/importBox/ImportElementBox'; import { PresBox, PresElementBox } from './nodes/trails'; import { SearchBox } from './search/SearchBox'; import { ImageLabelBox } from './collections/collectionFreeForm/ImageLabelBox'; +import { FaceRecognitionHandler } from './search/FaceRecognitionHandler'; dotenv.config(); @@ -96,6 +97,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; new BranchingTrailManager({}); new PingManager(); new KeyManager(); + new FaceRecognitionHandler(); // initialize plugins and classes that require plugins CollectionDockingView.Init(TabDocView); diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx new file mode 100644 index 000000000..86619b2d1 --- /dev/null +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -0,0 +1,86 @@ +import * as faceapi from 'face-api.js'; +import { FaceMatcher, TinyFaceDetectorOptions } from 'face-api.js'; +import { Doc, DocListCast, NumListCast } from '../../../fields/Doc'; +import { DocData } from '../../../fields/DocSymbols'; +import { List } from '../../../fields/List'; +import { ObjectField } from '../../../fields/ObjectField'; +import { StrCast } from '../../../fields/Types'; + +export class FaceRecognitionHandler { + static _instance: FaceRecognitionHandler; + + constructor() { + FaceRecognitionHandler._instance = this; + this.loadModels(); + if (!Doc.ActiveDashboard![DocData].faceDocuments) { + Doc.ActiveDashboard![DocData].faceDocuments = new List(); + } + } + + async loadModels() { + const MODEL_URL = `/models`; + await faceapi.loadTinyFaceDetectorModel(MODEL_URL); + await faceapi.loadFaceLandmarkTinyModel(MODEL_URL); + await faceapi.loadFaceRecognitionModel(MODEL_URL); + } + + public static get Instance() { + return FaceRecognitionHandler._instance ?? new FaceRecognitionHandler(); + } + + public async findMatches(doc: Doc, imageURL: string) { + const img = await this.loadImage(imageURL); + + const fullFaceDescriptions = await faceapi.detectAllFaces(img, new TinyFaceDetectorOptions()).withFaceLandmarks(true).withFaceDescriptors(); + + fullFaceDescriptions.forEach(fd => { + const match = this.findMatch(fd.descriptor); + if (match) { + match[DocData].associatedDocs = new List([...DocListCast(match[DocData].associatedDocs), doc]); + match[DocData].faceDescriptors = new List>([...(match[DocData].faceDescriptors as List>), Array.from(fd.descriptor) as List]); + } else { + const newFaceDocument = new Doc(); + const converted_array = Array.from(fd.descriptor); + newFaceDocument[DocData].faceDescriptors = new List>(); + (newFaceDocument[DocData].faceDescriptors as List>).push(converted_array as List); + newFaceDocument[DocData].label = `Person ${DocListCast(Doc.ActiveDashboard![DocData].faceDocuments).length + 1}`; + newFaceDocument[DocData].associatedDocs = new List([doc]); + + Doc.ActiveDashboard![DocData].faceDocuments = new List([...DocListCast(Doc.ActiveDashboard![DocData].faceDocuments), newFaceDocument]); + } + }); + } + + private findMatch(cur_descriptor: Float32Array) { + if (DocListCast(Doc.ActiveDashboard![DocData].faceDocuments).length < 1) { + return null; + } + + const faceDescriptors: faceapi.LabeledFaceDescriptors[] = DocListCast(Doc.ActiveDashboard![DocData].faceDocuments).map(faceDocument => { + const float32Array = (faceDocument[DocData].faceDescriptors as List>).map(faceDescriptor => new Float32Array(Array.from(faceDescriptor))); + return new faceapi.LabeledFaceDescriptors(StrCast(faceDocument[DocData].label), float32Array); + }); + const faceMatcher = new FaceMatcher(faceDescriptors, 0.6); + const match = faceMatcher.findBestMatch(cur_descriptor); + + if (match.label == 'unknown') { + return null; + } else { + for (const doc of DocListCast(Doc.ActiveDashboard![DocData].faceDocuments)) { + if (doc[DocData].label === match.label) { + return doc; + } + } + } + } + + private loadImage = (src: string): Promise => { + return new Promise((resolve, reject) => { + const img = new Image(); + img.crossOrigin = 'anonymous'; + img.onload = () => resolve(img); + img.onerror = err => reject(err); + img.src = src; + }); + }; +} diff --git a/src/server/public/models/age_gender_model-shard1 b/src/server/public/models/age_gender_model-shard1 new file mode 100644 index 000000000..d942d6ad1 Binary files /dev/null and b/src/server/public/models/age_gender_model-shard1 differ diff --git a/src/server/public/models/age_gender_model-weights_manifest.json b/src/server/public/models/age_gender_model-weights_manifest.json new file mode 100644 index 000000000..ebc009ab8 --- /dev/null +++ b/src/server/public/models/age_gender_model-weights_manifest.json @@ -0,0 +1 @@ +[{"weights":[{"name":"entry_flow/conv_in/filters","shape":[3,3,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005431825039433498,"min":-0.7441600304023892}},{"name":"entry_flow/conv_in/bias","shape":[32],"dtype":"float32"},{"name":"entry_flow/reduction_block_0/separable_conv0/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005691980614381678,"min":-0.6090419257388395}},{"name":"entry_flow/reduction_block_0/separable_conv0/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009089225881239947,"min":-1.1179747833925135}},{"name":"entry_flow/reduction_block_0/separable_conv0/bias","shape":[64],"dtype":"float32"},{"name":"entry_flow/reduction_block_0/separable_conv1/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00683894624897078,"min":-0.8138346036275228}},{"name":"entry_flow/reduction_block_0/separable_conv1/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011632566358528886,"min":-1.3028474321552352}},{"name":"entry_flow/reduction_block_0/separable_conv1/bias","shape":[64],"dtype":"float32"},{"name":"entry_flow/reduction_block_0/expansion_conv/filters","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010254812240600587,"min":-0.9229331016540528}},{"name":"entry_flow/reduction_block_0/expansion_conv/bias","shape":[64],"dtype":"float32"},{"name":"entry_flow/reduction_block_1/separable_conv0/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0052509616403018725,"min":-0.6406173201168285}},{"name":"entry_flow/reduction_block_1/separable_conv0/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010788509424994973,"min":-1.4564487723743214}},{"name":"entry_flow/reduction_block_1/separable_conv0/bias","shape":[128],"dtype":"float32"},{"name":"entry_flow/reduction_block_1/separable_conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00553213918910307,"min":-0.7025816770160899}},{"name":"entry_flow/reduction_block_1/separable_conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.013602388606351965,"min":-1.6186842441558837}},{"name":"entry_flow/reduction_block_1/separable_conv1/bias","shape":[128],"dtype":"float32"},{"name":"entry_flow/reduction_block_1/expansion_conv/filters","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007571851038465313,"min":-1.158493208885193}},{"name":"entry_flow/reduction_block_1/expansion_conv/bias","shape":[128],"dtype":"float32"},{"name":"middle_flow/main_block_0/separable_conv0/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005766328409606335,"min":-0.6688940955143349}},{"name":"middle_flow/main_block_0/separable_conv0/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.012136116214826995,"min":-1.5776951079275094}},{"name":"middle_flow/main_block_0/separable_conv0/bias","shape":[128],"dtype":"float32"},{"name":"middle_flow/main_block_0/separable_conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004314773222979377,"min":-0.5652352922102984}},{"name":"middle_flow/main_block_0/separable_conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01107162026798024,"min":-1.2400214700137868}},{"name":"middle_flow/main_block_0/separable_conv1/bias","shape":[128],"dtype":"float32"},{"name":"middle_flow/main_block_0/separable_conv2/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0036451735917259667,"min":-0.4848080876995536}},{"name":"middle_flow/main_block_0/separable_conv2/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008791744942758598,"min":-1.134135097615859}},{"name":"middle_flow/main_block_0/separable_conv2/bias","shape":[128],"dtype":"float32"},{"name":"middle_flow/main_block_1/separable_conv0/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004915751896652521,"min":-0.6095532351849126}},{"name":"middle_flow/main_block_1/separable_conv0/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010868691463096469,"min":-1.3368490499608656}},{"name":"middle_flow/main_block_1/separable_conv0/bias","shape":[128],"dtype":"float32"},{"name":"middle_flow/main_block_1/separable_conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005010117269029804,"min":-0.6012140722835765}},{"name":"middle_flow/main_block_1/separable_conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010311148213405235,"min":-1.3816938605963016}},{"name":"middle_flow/main_block_1/separable_conv1/bias","shape":[128],"dtype":"float32"},{"name":"middle_flow/main_block_1/separable_conv2/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004911523706772748,"min":-0.7367285560159123}},{"name":"middle_flow/main_block_1/separable_conv2/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008976466047997568,"min":-1.2207993825276693}},{"name":"middle_flow/main_block_1/separable_conv2/bias","shape":[128],"dtype":"float32"},{"name":"exit_flow/reduction_block/separable_conv0/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005074804436926748,"min":-0.7104726211697447}},{"name":"exit_flow/reduction_block/separable_conv0/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011453078307357489,"min":-1.4545409450344011}},{"name":"exit_flow/reduction_block/separable_conv0/bias","shape":[256],"dtype":"float32"},{"name":"exit_flow/reduction_block/separable_conv1/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007741751390344957,"min":-1.1380374543807086}},{"name":"exit_flow/reduction_block/separable_conv1/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011347713189966538,"min":-1.497898141075583}},{"name":"exit_flow/reduction_block/separable_conv1/bias","shape":[256],"dtype":"float32"},{"name":"exit_flow/reduction_block/expansion_conv/filters","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006717281014311547,"min":-0.8329428457746318}},{"name":"exit_flow/reduction_block/expansion_conv/bias","shape":[256],"dtype":"float32"},{"name":"exit_flow/separable_conv/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0027201742518181892,"min":-0.3237007359663645}},{"name":"exit_flow/separable_conv/pointwise_filter","shape":[1,1,256,512],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010076364348916447,"min":-1.330080094056971}},{"name":"exit_flow/separable_conv/bias","shape":[512],"dtype":"float32"},{"name":"fc/age/weights","shape":[512,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008674054987290326,"min":-1.2664120281443876}},{"name":"fc/age/bias","shape":[1],"dtype":"float32"},{"name":"fc/gender/weights","shape":[512,2],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0029948226377075793,"min":-0.34140978069866407}},{"name":"fc/gender/bias","shape":[2],"dtype":"float32"}],"paths":["age_gender_model-shard1"]}] \ No newline at end of file diff --git a/src/server/public/models/face_expression_model-shard1 b/src/server/public/models/face_expression_model-shard1 new file mode 100644 index 000000000..619cdf6d4 Binary files /dev/null and b/src/server/public/models/face_expression_model-shard1 differ diff --git a/src/server/public/models/face_expression_model-weights_manifest.json b/src/server/public/models/face_expression_model-weights_manifest.json new file mode 100644 index 000000000..7b74b5ab4 --- /dev/null +++ b/src/server/public/models/face_expression_model-weights_manifest.json @@ -0,0 +1 @@ +[{"weights":[{"name":"dense0/conv0/filters","shape":[3,3,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0057930146946626555,"min":-0.7125408074435067}},{"name":"dense0/conv0/bias","shape":[32],"dtype":"float32"},{"name":"dense0/conv1/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006473719839956246,"min":-0.6408982641556684}},{"name":"dense0/conv1/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010509579321917366,"min":-1.408283629136927}},{"name":"dense0/conv1/bias","shape":[32],"dtype":"float32"},{"name":"dense0/conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005666389652326995,"min":-0.7252978754978554}},{"name":"dense0/conv2/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010316079270605948,"min":-1.1760330368490781}},{"name":"dense0/conv2/bias","shape":[32],"dtype":"float32"},{"name":"dense0/conv3/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0063220320963392074,"min":-0.853474333005793}},{"name":"dense0/conv3/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010322785377502442,"min":-1.4658355236053466}},{"name":"dense0/conv3/bias","shape":[32],"dtype":"float32"},{"name":"dense1/conv0/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0042531527724920535,"min":-0.5741756242864272}},{"name":"dense1/conv0/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010653339647779278,"min":-1.1825207009035}},{"name":"dense1/conv0/bias","shape":[64],"dtype":"float32"},{"name":"dense1/conv1/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005166931012097527,"min":-0.6355325144879957}},{"name":"dense1/conv1/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011478300188101974,"min":-1.3888743227603388}},{"name":"dense1/conv1/bias","shape":[64],"dtype":"float32"},{"name":"dense1/conv2/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006144821410085641,"min":-0.8479853545918185}},{"name":"dense1/conv2/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010541967317169788,"min":-1.3809977185492421}},{"name":"dense1/conv2/bias","shape":[64],"dtype":"float32"},{"name":"dense1/conv3/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005769844849904378,"min":-0.686611537138621}},{"name":"dense1/conv3/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010939095534530341,"min":-1.2689350820055196}},{"name":"dense1/conv3/bias","shape":[64],"dtype":"float32"},{"name":"dense2/conv0/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0037769308277204924,"min":-0.40790852939381317}},{"name":"dense2/conv0/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01188667194516051,"min":-1.4382873053644218}},{"name":"dense2/conv0/bias","shape":[128],"dtype":"float32"},{"name":"dense2/conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006497045825509464,"min":-0.8381189114907208}},{"name":"dense2/conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011632198913424622,"min":-1.3377028750438316}},{"name":"dense2/conv1/bias","shape":[128],"dtype":"float32"},{"name":"dense2/conv2/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005947182225246056,"min":-0.7969224181829715}},{"name":"dense2/conv2/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011436844339557722,"min":-1.4524792311238306}},{"name":"dense2/conv2/bias","shape":[128],"dtype":"float32"},{"name":"dense2/conv3/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006665432686899222,"min":-0.8998334127313949}},{"name":"dense2/conv3/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01283421422920975,"min":-1.642779421338848}},{"name":"dense2/conv3/bias","shape":[128],"dtype":"float32"},{"name":"dense3/conv0/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004711699953266218,"min":-0.6737730933170692}},{"name":"dense3/conv0/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010955964817720302,"min":-1.3914075318504784}},{"name":"dense3/conv0/bias","shape":[256],"dtype":"float32"},{"name":"dense3/conv1/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00554193468654857,"min":-0.7149095745647656}},{"name":"dense3/conv1/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.016790372250126858,"min":-2.484975093018775}},{"name":"dense3/conv1/bias","shape":[256],"dtype":"float32"},{"name":"dense3/conv2/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006361540626077091,"min":-0.8142772001378676}},{"name":"dense3/conv2/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01777329678628959,"min":-1.7062364914838006}},{"name":"dense3/conv2/bias","shape":[256],"dtype":"float32"},{"name":"dense3/conv3/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006900275922289082,"min":-0.8625344902861353}},{"name":"dense3/conv3/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015449936717164282,"min":-1.9003422162112067}},{"name":"dense3/conv3/bias","shape":[256],"dtype":"float32"},{"name":"fc/weights","shape":[256,7],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004834276554631252,"min":-0.7203072066400565}},{"name":"fc/bias","shape":[7],"dtype":"float32"}],"paths":["face_expression_model-shard1"]}] \ No newline at end of file diff --git a/src/server/public/models/face_landmark_68_model-shard1 b/src/server/public/models/face_landmark_68_model-shard1 new file mode 100644 index 000000000..fcaca474f Binary files /dev/null and b/src/server/public/models/face_landmark_68_model-shard1 differ diff --git a/src/server/public/models/face_landmark_68_model-weights_manifest.json b/src/server/public/models/face_landmark_68_model-weights_manifest.json new file mode 100644 index 000000000..0fe27075f --- /dev/null +++ b/src/server/public/models/face_landmark_68_model-weights_manifest.json @@ -0,0 +1 @@ +[{"weights":[{"name":"dense0/conv0/filters","shape":[3,3,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004853619781194949,"min":-0.5872879935245888}},{"name":"dense0/conv0/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004396426443960153,"min":-0.7298067896973853}},{"name":"dense0/conv1/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00635151559231328,"min":-0.5589333721235686}},{"name":"dense0/conv1/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009354315552057004,"min":-1.2628325995276957}},{"name":"dense0/conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0029380727048013726,"min":-0.5846764682554731}},{"name":"dense0/conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0049374802439820535,"min":-0.6171850304977566}},{"name":"dense0/conv2/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009941946758943446,"min":-1.3421628124573652}},{"name":"dense0/conv2/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030300481062309416,"min":-0.5272283704841838}},{"name":"dense0/conv3/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005672684837790097,"min":-0.7431217137505026}},{"name":"dense0/conv3/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010712201455060173,"min":-1.5639814124387852}},{"name":"dense0/conv3/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030966934035806097,"min":-0.3839899820439956}},{"name":"dense1/conv0/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0039155554537679636,"min":-0.48161332081345953}},{"name":"dense1/conv0/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01023082966898002,"min":-1.094698774580862}},{"name":"dense1/conv0/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0027264176630506327,"min":-0.3871513081531898}},{"name":"dense1/conv1/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004583378632863362,"min":-0.5454220573107401}},{"name":"dense1/conv1/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00915846403907327,"min":-1.117332612766939}},{"name":"dense1/conv1/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003091680419211294,"min":-0.5966943209077797}},{"name":"dense1/conv2/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005407439727409214,"min":-0.708374604290607}},{"name":"dense1/conv2/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00946493943532308,"min":-1.2399070660273235}},{"name":"dense1/conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004409168514550901,"min":-0.9788354102303}},{"name":"dense1/conv3/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004478132958505668,"min":-0.6493292789833219}},{"name":"dense1/conv3/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011063695888893277,"min":-1.2501976354449402}},{"name":"dense1/conv3/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003909627596537272,"min":-0.6646366914113363}},{"name":"dense2/conv0/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003213915404151468,"min":-0.3374611174359041}},{"name":"dense2/conv0/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010917326048308728,"min":-1.4520043644250609}},{"name":"dense2/conv0/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002800439152063108,"min":-0.38085972468058266}},{"name":"dense2/conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0050568851770139206,"min":-0.6927932692509071}},{"name":"dense2/conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01074961213504567,"min":-1.3222022926106174}},{"name":"dense2/conv1/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030654204242369708,"min":-0.5487102559384177}},{"name":"dense2/conv2/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00591809165244009,"min":-0.917304206128214}},{"name":"dense2/conv2/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01092823346455892,"min":-1.366029183069865}},{"name":"dense2/conv2/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002681120470458386,"min":-0.36463238398234055}},{"name":"dense2/conv3/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0048311497650894465,"min":-0.5797379718107336}},{"name":"dense2/conv3/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011227761062921263,"min":-1.4483811771168429}},{"name":"dense2/conv3/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0034643323982463162,"min":-0.3360402426298927}},{"name":"dense3/conv0/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003394978887894574,"min":-0.49227193874471326}},{"name":"dense3/conv0/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010051267287310432,"min":-1.2765109454884247}},{"name":"dense3/conv0/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003142924752889895,"min":-0.4588670139219247}},{"name":"dense3/conv1/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00448304671867221,"min":-0.5872791201460595}},{"name":"dense3/conv1/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.016063522357566685,"min":-2.3613377865623026}},{"name":"dense3/conv1/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00287135781026354,"min":-0.47664539650374765}},{"name":"dense3/conv2/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006002906724518421,"min":-0.7923836876364315}},{"name":"dense3/conv2/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.017087187019048954,"min":-1.6061955797906016}},{"name":"dense3/conv2/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003124481205846749,"min":-0.46242321846531886}},{"name":"dense3/conv3/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006576311588287353,"min":-1.0193282961845398}},{"name":"dense3/conv3/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015590153955945782,"min":-1.99553970636106}},{"name":"dense3/conv3/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004453541601405424,"min":-0.6546706154065973}},{"name":"fc/weights","shape":[256,136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010417488509533453,"min":-1.500118345372817}},{"name":"fc/bias","shape":[136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0025084222648658005,"min":0.07683877646923065}}],"paths":["face_landmark_68_model-shard1"]}] \ No newline at end of file diff --git a/src/server/public/models/face_landmark_68_tiny_model-shard1 b/src/server/public/models/face_landmark_68_tiny_model-shard1 new file mode 100644 index 000000000..f04a9d5ec Binary files /dev/null and b/src/server/public/models/face_landmark_68_tiny_model-shard1 differ diff --git a/src/server/public/models/face_landmark_68_tiny_model-weights_manifest.json b/src/server/public/models/face_landmark_68_tiny_model-weights_manifest.json new file mode 100644 index 000000000..5dc790e48 --- /dev/null +++ b/src/server/public/models/face_landmark_68_tiny_model-weights_manifest.json @@ -0,0 +1 @@ +[{"weights":[{"name":"dense0/conv0/filters","shape":[3,3,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008194216092427571,"min":-0.9423348506291708}},{"name":"dense0/conv0/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006839508168837603,"min":-0.8412595047670252}},{"name":"dense0/conv1/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009194007106855804,"min":-1.2779669878529567}},{"name":"dense0/conv1/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0036026100317637128,"min":-0.3170296827952067}},{"name":"dense0/conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.000740380117706224,"min":-0.06367269012273527}},{"name":"dense0/conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":1,"min":0}},{"name":"dense0/conv2/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":1,"min":0}},{"name":"dense0/conv2/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0037702228508743585,"min":-0.6220867703942692}},{"name":"dense1/conv0/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0033707996209462483,"min":-0.421349952618281}},{"name":"dense1/conv0/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014611541991140328,"min":-1.8556658328748217}},{"name":"dense1/conv0/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002832523046755323,"min":-0.30307996600281956}},{"name":"dense1/conv1/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006593170586754294,"min":-0.6329443763284123}},{"name":"dense1/conv1/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.012215249211180444,"min":-1.6001976466646382}},{"name":"dense1/conv1/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002384825547536214,"min":-0.3028728445370992}},{"name":"dense1/conv2/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005859645441466687,"min":-0.7617539073906693}},{"name":"dense1/conv2/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.013121426806730382,"min":-1.7845140457153321}},{"name":"dense1/conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0032247188044529336,"min":-0.46435950784122243}},{"name":"dense2/conv0/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002659512618008782,"min":-0.32977956463308894}},{"name":"dense2/conv0/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015499923743453681,"min":-1.9839902391620712}},{"name":"dense2/conv0/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0032450980999890497,"min":-0.522460794098237}},{"name":"dense2/conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005911862382701799,"min":-0.792189559282041}},{"name":"dense2/conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.021025861478319356,"min":-2.2077154552235325}},{"name":"dense2/conv1/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00349616945958605,"min":-0.46149436866535865}},{"name":"dense2/conv2/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008104994250278847,"min":-1.013124281284856}},{"name":"dense2/conv2/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.029337059282789044,"min":-3.5791212325002633}},{"name":"dense2/conv2/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0038808938334969913,"min":-0.4230174278511721}},{"name":"fc/weights","shape":[128,136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014016061670639936,"min":-1.8921683255363912}},{"name":"fc/bias","shape":[136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0029505149698724935,"min":0.088760145008564}}],"paths":["face_landmark_68_tiny_model-shard1"]}] \ No newline at end of file diff --git a/src/server/public/models/face_recognition_model-shard1 b/src/server/public/models/face_recognition_model-shard1 new file mode 100644 index 000000000..3d4b3017a Binary files /dev/null and b/src/server/public/models/face_recognition_model-shard1 differ diff --git a/src/server/public/models/face_recognition_model-shard2 b/src/server/public/models/face_recognition_model-shard2 new file mode 100644 index 000000000..8a4b5fbe2 --- /dev/null +++ b/src/server/public/models/face_recognition_model-shard2 @@ -0,0 +1,6 @@ +r^~~}pz|~v}yy||{r_{}~~|pxr؛uy|y~~}z|}v{jŖx{v~uq{sM|~Sh~oh~su~}g}~}sqxwz|w|yymzn}~~~z}~~lu~w|u~zdx~~}~uo}vr}|~{r~}}{}xy{{s~}~}znwy}}y}|v}y’p~}~ux}v~~qpzTut~۔~iq}v}vz|t{|}|ix~||}~}~v}|}wx|z~|y}y|{x|}}|{vx}w{zœ}uy|{z|zy{~z{||u~q~|u~~|{~||y~~|}}w}}}{sz~|hxד֛v|z{~~~~zqyxffecx|wsv|s}}yf{}qwvtox|}~{}z}{~rza|u{~w~}wwt{Ȍ~b~oyzywyz{{tfjuy~z~yUs~z|ݎxr~u|{r}wr~w|su{{h{x{~~ue}yz~v~{kzqt{{v}s~xz拗|ys}p|s{Pxvԉolowzc~{y~|ytz|~~}~{}vz|rv{|~jt[u{~ϧy}v~qu~{|~~|qy|w}|y}|mwxpzvtx|lxl|~~{ŏyxt{ov}|}}}}uov~szz~s~y~}~ɡz|z~}y}܍{}~v{vwytx|}rw~vy}~~zzu{|~~y|y}}}u}Γ‰~wj~rmya{||~r}}v~m~guqznz~v||w}v}}Ďpyc^|w}uxw}|ٜ{xx}coƖ2}t~_x|yxy~|v|wxryv~w{~|y~ʞx~trf}w}}v}|{y|wuzuy|{~wrzxi|zv}|zuuw|zr}z||}~{|z~|ut]|ck}}{w}wy}xz}~y{wxp}z~{x{}}u~~q~|~~}x~z}~|zwz~}}z}nwsj~~yt{}uv~}Yz{~{q{}~~~~|zz~~r~yzzzgsz}}~x~tkgp}{~}v|vt|{z{{{{u}}zu~~}e|vnwCC~];u~wtu}a~r|~{y|Ǔzy}ďw{z}~~{|z{ruzt|{{}}wruy}y{~u|zz}|}z|~~v{w~}u~{||‘}quy}||ydp}}}w}v{l~|d~{||z~t|~}Í}yu~xy~t|t{|~}yr{w}v{wxyȤy|vw}s|}{~sĕ}×|||Ó}^yuz}{s|c{r}ixzd~|zzizpv{}tz}Ȗ|{|}su~~u~~euu}yj|~}vwywy~|~}}}vt{zv}z}}wu}jbvkJusg:}z`ZnGcXFYb1x{y% +Ss@X6kzTpYuqDlUq2s]crv/N>bvb\#D9)BSZaOf@WiaUZ8[_`qwsyrkp|mvFZum^a=FpJdF$H_7Z]Bgy2bUf_c_ixs:VjBTJ9!"+O`f5)36Xfnp2h(  97ML>9V%R +lfE5')<7WSq:ci};NVQ*siMrHB;5W%]1Sd; VNGi4l+#c:`*jZAw0asD6a4^j!7c aq0=A#)[NZDX:N''HVM!=PF$3^:?0/T]\\ 1$%#z=6OM0N=8I9bQ",#OlnLV@CJ3A%: "|AQc&VjA1"%Qq8HM.<$AcA=[:%S~JftOj~*te?M(FK3|*@.@Q7w8+ *[>[4g~q_v`z/B2'~^9284lz*4P=?@nj {c}{~{{}||wzwtwx|}c~z{y~xu}|{~s~ysdxx}q{|s|rsqxzryx~vzx{~w|~ymty}z~zoyyr}z|~~osxuyhxu}~~m~njx|{~{nul}r~wzo~`niniowk|x}twstz|jtyap|q~z`ws]yy|sjv}z~y{|{zx{~txyxy|x~yv}|y}~zn|ry}~s~y|my~~}}xtuu|z}qnzy}}~wqx|u}~z||~xy|v~z~|~~vy{z{zvt{}q||y}~vw{x~pw{mn{xrouyu{vuj~v~yst||z}r}u{}|wm}h~{{}|{ukz|v{zzty}u~|~j~vs~r{s|zt}x~zywux{wv}{~zvyy~|zw}~uz{{~tx{}{lg~}~{{}trzoz~~uy{x{u||z~{}v{}~~gsxwt}|t|m}xyzwq~t}qszc|o|}vwvy~x}{~{zuozd}zno~cu~x~fk~|g|k{}zhwxsz{r|yymw|yw}j~ztp|{yt}~sy~~ux~m{o}||{|}oxz~uxop|~|~x|}xtx|w~sx{vxq}oz|}}}z{y}w|zzwx~mz~~{v|}tr~g|m~{vys}{z|}xpuwv~s}{}z~}x~rr|~|x~}|~}~uz~}~tx~~}}mq{hqrvvyokzhr}t{v{k|~~otU~}Yj}m{|ozosln}t{|sUdz{ayPqs_z|x}|xxlq{q~}~prs}}~|{wwvyx|}no}{v{pvt~~{qm|}y||{ltvvx}wy{y}~~t{x|z}w}v|v|}z|~xz~zyy{~|zmzqyxrxyppx~}z~wj~mux~{ry}yuwx|xho}t{||tyzwv||wy|{np}|v|~}}|{{ov}xn~}u||toy~v~z|r|tur}~w}un~{|szxx{y}mt}tvtu~s~|x~~{~vy|vu~{~}|lqy~}}|~|}}xs~}|ux~y{{s||}oqu~}}}|}v{rxv|~o}q~z{vw~|z~~~~ox|zt}ux{{qo{f}}w{|zn|}{hry{|}|tqqly|~txzryzyun~tuv~[szsx}{w}Zpzv~tr{|w}xyo~xxm{r~uw{xx~zw~{xyzzwwy|tuw~s|t{w~ztyz}w}|}y{{t}|~~|u~x}s~~}|~~|}{}vt{x}~w|~{w|zvt~sxm|zyxpw~yrxzv{|{z~x~|||s{}~}w}|zrwt}~zwysxtp}zz}|x}{w{{to~izvtorkmu~klTz}}|~]uqps}~x^|w~|~~syy|ux{}uvy~}}yioxs~{{|yvxnyu{tx}~to{z~x}|~{y~{zxst|y{~y~w}zzqz}pw|}tx}vywy~|}xy}~sqwy~y}~|wz{}xy}~{zrp~s}~w}}m}~|{us~|z~hku{y|w{z~zx~ti}{wz{wn{ym{p{~}y}zxx|}}z}w{yut}w~}xwx~{klvztuz{~y}|pxzw}|ru{||z}|s}swx||n~y~z{}|}pwus{|nk|~z}qt~wl}s~wzuss}je{~sj\zkfht~gnsteoysz{|zwm}\q}s~}zwx~zzu}||q{|t}v|~xwts~vx{s}{||t}||{}|{jzuxzzr}u~r}suv~l~q~|}}z}~noxyxwiw~~w~}ty}{}{vswx}}~rp~ysvx|{|ux|~{y}~ws~~}v|zyswl{~w~{v}wxw~r|}}xxpq~~}}y|x{s}ss|z~vxsozus~}tvylx{ou{r~}z|xww|pi}y|{y{wwvts|~|jy|ywvv}v{x~|}{}vzs~}w}w~u{{~wz~zy~}swx{}{y~tz{~~wt{{zwx~qq{vy}zw|~v}~vzy~vx}{~mozvyvt}j}zyuuv}z}gky}~~u{}}}tzq{zy~uw||iqxm|s|n|{}wvsf|o{{yt~v~~xzy|ym}~v~uy~xu~z|z~s|~vz~~~zs~||v~m}xgYzuh~dyzl|vg}rPo|ebkwxpz}~y{}|}}|uvys|sx}xz_iz{~zvwww|~wvxv{{||zr~sqzrx{nsru}xqj~{{}tw|x~qvslv~~sxu}||~x|~{|}kvnk}}}{}~uwvv|oyo|}}}vnvo|~xt}~{~mq{}~}}px~z}vy~}~|sx}n~}yx}~}zuvz~}~~vzx~}v{kp|wwq|{wtzzswyr}Yp|{}wpo~|w~qe|vzwyzr}toymt~{{uz{|xxwo}yhou}{r{xpw{}xwxxz}~}{|z|y~mxyvx}u}zy{uyyxz}uyvrz}~{{r{zuv{~tw}}~}pp~zxw{|x{}z{yu|t}}}xyn~x}|}y}v|g|q|zvys}~y{y~xyzp|w{y}~zzp}~xmv}n|xwmjjyt~{{~z|rn~{vnsw~xdg]vzbiryurylrZ~w{zq}oe|qu|y{yhkp~^{tut~vsvize[z}o|}|vlvfe~qtuwiwv}}~je~|k}wy~}qgx|u|p}r{|v}}u|y~rw~zxk~vv{|s}||{{}|~{|vxur|||x}~zywmwww}ty|oyqyz{uw}~|pumrg|}}zuvw|oyz}~}}~{zl|z}r{w}~~wz~zu~u}}p~}v{u{kzy~~umw{|~}|~}z}}}{~z~|oz{{~{{qypw{|}sy}|yr|w}xl}lozqj~v}{}}}|z~v~wyz~~~~}yw}|v|wy}yz{x|vwzUx~~|}}~wzv~zwuzuy~rq}|}zz~~nrtx|vu~{}~}q}|zpzzv~y}v|m{r{}{yyqvt|y{~~xUs}uxzyt|y|ut~~}y}o~vuxz~~}y}z{}z{p}x}~|~w~~w}|}~z~xy}}m{w|x~}h~}z|{|{{}{{zvvrv||x|||g}}o}y|}sz}ql~zx~qt}~usz}z|zp{y~xs}}}xz}vy}{y|~o|znr}||z{}yr|x~w}{sy~~us}}|p~i~~vt{|{|qwzyy~}}wru~y|t}zlhu|r~}ziw~}~~ywzvz}zuwxvpot~|~y|z~}nyvytzyv||v~{~|pi|z{vzss~l}{}u}u|{s~z~~y{q~~~~vukj{|{|wzs{vY}syyxys|}o|~qp|turyyu~|~|y~w}|w~wsq}}wy{vvrp{x{s|}zts|x{}o}|}~qz|w{}zu}zy{~~wy~{zt}p~p~~u{}i{u~|v}qz|}~n|o|n{yzxzx}z|z{r|ty}{||{pt~|v~{vyy~ulxy|}~y~xyrvtrkx~y}s{rtvjtcxixzut~yx{e||zpZo~{hor~Ʉn{izxx|nr|qzlhLj~zz}qpdu~~z~i{{}~uuxux}}~po~~}}~}z~~wv}y|~tw|ylpz|{yyu~{yx}w{yz|}w{w}}jw}w}{|wy~~xxvlyqz{{zosuu}q~{vx}sw|x{|x||~yr~{|wlzvz}{vzz{~f~||x{x~zhw~{z{{}kwk{}sw{yx~pzwt|}~~u}yyrvwx|}{vx|wz~qt}}{}q}w}tysx}~x||ux{rux~~qo}x}wvy}jy|ltp|{}|~xr|mw{gz{s{y|rgvqqw~mmuuR|z{y\y|oncrltreulmys{vwi|ss}pu\r{}x|}p}}yw}rxxyx{wuw}nx~{yr}{ytw~}||v}zt}}z}ui||{}{zx~~uww|qvzwv}vr}{{u}mpt}z}vv|}}x~}t|y~{z}yz}{z}}xz~yu~wtp}a|j}rtwusyz|b{sy{bć]tmy}z|v}x[}svxjs}Nvzpy}v~zjHWzuz`w`~rzvt|oxwyt|}X~rmvsr}tvowpɟ~y~rz~~s}i~}}}~huj}|k}|}{uv~~|nv}{s||{{vw|x~yroy{xr~~~}~y{~{vtwvy}|r~o||}~|w{x_v|~}zx{{ztzz~}~l|~{xky{}tx{r|}r|wyy}uwyttxy{~mpz{~y|uz}u|{w}t|cvv{xx}~~||yyozzxu||}{~xv}xwsp|~s~|y~y~vxr}~t|wzm}~}~~~ni~|~w}}~n~{rypz}pwoy~~{wzvx~{qxxtuw{~}vp~vzy~|}mnyy{~{|}{{x{quy{}rw}}js{w~x~~u{u{xz}u~ru{|tv|{|}|y{{|p~uzzz~qxvwxnp}|v}{mw}v~t}l~|||pwuw{jz|}~zzr|z~qw}u|tx{|p|p~|}~sz}{wxvq}pzww~}~rw|~yztwxxv|{}|mo}w~yvz}}v~~~}|}z|v}yu}yv|{t~~z|zp|w|{}v|ssr~~zvw{|zmzvw~|}z~r}ts~wrz~}~|rxv|xzl}~tyxw~i|{~w~{~ypuxt{}y{~x}zyvxx{~wx|}}}}|~zq~~p{~~shz}}w}}g{yxu}tq}~wn{izur}}{|g~v|v{y||}rtyrqi\vxt~wzix~qn{~{ypzv~rvv{}x}{~p{i|~}u{{|~}{pw}}~}q|qu}~xpvuq~~|{~rx~{zw}x}qypxuw|tz{r}{xp}rmto|j}{r|zx|wwt{s{{y}{nxzz|w}|z|qm}}|i~q{uvszz}yxyt}z|w{`}v|x}~x{~x|mv~vxxxvpo}y~lsZz~~~|qzy|y|j}zs}~wzv}{rys}n{c{vym{}~}np}|{nwz|ydd{xy|w{~x}rytx~op}|~}~{}|lez]}WVov}j}x{z~wsxsymy]bzqv|vr}~y|_\zkr}`cuitt}j||spsr}}}yz|~tx}}|}pvx}x}l|yyr|mw{|zvwo~}}|}{}~vx|}xz|wo|~ol~lx|}wz|}wysx~}}{}{|xwz|zrx|w}ntow|botxqy~s{zs`}~zuxs}|rkvlyz}twxcmugm~{u|uuw{{yz|||u|wssnz|~y}ywzxzy~}kt~}~x}qxm{np{ezmxx{s{xw}}zvuzunyv~wu{~oz|xrs~}ys|zz{y|u|vw|{wx{{}}~|mzos~g}~|x|wwtpj~~tq}z}{jnmzr|}qyf~||txqz|mxz~qiywwx}y~}vuzs{}{qwrx{v}}sur{vzy}|syu{ty~|zylw{{tzx{|}~w~{}xv}uv~x}~uzo|||sxy|~mz~|yy|~}vzu~~zuu~}}|z~yvzvz~ux{~}wx|pm|||q|zxwz|~ux{~}~p~~o}p}{z}pw~zwxz|sp}}u}yv|z}o~v{}v{vs|qloym{iuls}yzvltgzos_s|p`m|ym~yu{{q}y{{dt~vygy}v~yw|~~}}~}~{~~~|~~~s}}}|}|~uww}lyzxqyyv{~}x~|~z|yz}yu|v}~zwr|{{xyz}}x|t~{{r~{w}y{y{}x~}y}o||z{|xx{~}|~}|{~|~lv~z{~}z|}yx|w}o|~s{yy~uu{st{~}}xyvw|wz~vw}u{{|}m~{{w{kt~{yv~|~w{u{w~{{}m}s{{w|zz~}q~m{|w|wqw~{{|tu|~}{~~v|x{}zzx}xw{y~w~|u}y~p|s}|{zz{}}{|p{}{r}uw||zw~{~u}t|{~v{~~}~|x}~y~{ov~}~~~c~~u|vq~|wzw{~`yr|yhf}qmxz~t{}yy{tutrk~}uzq{wkxrwotjnmztaw~rvkaolqzLvr~ww}uo|k}yw|^fqqzrw~~{r~lrwv|{ezqz{vy||rw|{{vx{~{xyxy~|y|xz|}qw|{yxx~qp{~~zx~xxyxvy}|{qqy}|xx~~sz~zxtyz}~|pqw}u||}z|uw{|x}~ty}~}}}tp~{lwx}}wzm}u|{uztv|w{}v}zsuzvvpkdw|o[u|r{~{bruv|{v}zyjyxdy}~}|wvy|~yy|r|}zuy|w{wvz}ytye|r~~|}{v~uv~|~~x}}|xsz}lvs{|}{y{uywy||uyz}w{z}z}}{~y|v~~xzx}~vww{q~~|}Njwzv}{qxt}w|yxz{z}~vi|y~{|}zsw{yx{~x~x{~ty|yv}~yvz|~~}~}{}w~r~}~|x}|{zr|iutvtkzyujosvwmt~y~~|}|{mV|gvupjymv}p|yxupky|xyozmts~rpft}}v|{}w{y}y{zz{|upyvt{w~ycw}{zuzv~~v|wvz}z}p||ox~~t~zyx}t{z~v|v|~wxtrz}}yz}uzsxw|ux|}y}y||}~wyzxxx~~u}z~yze|w{y~z{rv|{tzw~{||z|{yvww~u{||||x~}pz~yz|}}~|nt}x{}w~}~{|x~{u{|rv}t~|n~}zyjttw}{w{~wk~zv}}}z}}~rm~ui~p|~}y{z|vz{~yu{y}~p}{{}y{z}~ohr}u~y{~wpz{||s}t|vt|~}ovuzxyrw~}|~u{~z~~|~v|w|r}}}~|~yx{}zn{{}~zuw}w{wi{xx|}u}zzzzzzw|}im|~~|||t}qvq|~|tw{z~~~yv~w|wxm}rzi|w|hnygzgtrywxtvsyyunzjpzcyg}t~Eyv6zyxvpnxss{qt}n{z{u}{vu~wu{t~|~|zw~}zyxt~z}x~lt~{~y~i{}~{|~}}z}~{|w|yw}y~z{xzvxztw}}zzp||}x}}||qo|~}z}~~}}~~ty|{{{~~{v|yux~~zuky{k|}{}vtx{w{z|z|~z~}{~~~uwt~}~|tv{sss|w|}r}}q}}~~zyyz{{vzw{yvqn{~z}zxy|}y{x~yw{~z}~z{v}~{|}}zpqwx~~}{{v~}w~yy|~}x~~zzy~|{y~vr}h{{z|gtslpsqeDbt@YqolUaxwl‰trD~nyyuvytW|{|qxrwyLsvuG~mgfqhgljdugayy|~sd}yn}}vxyev{x~~~~~}|{w}}{utwzu}z~{{vz|{|}{{wqvyrz{}|{{y|{nzvyc}}~}~u{{r|}~}}v}~|xpv|z}zq}~~~tz~~~|s~~~r~~z{v}~~|y~rz{|oxzt|x|mxxzxwr}~}|u~yytz~|qz~|wv|tr{x{u~jq{~}~w{|}uu|x~y}z}|}||x~ww~x{~wsulz{u}}kus|}wv||~wx~{|vv~|}x~zxtuwnxzwz~~|}}{v|~x{~}~}wzz|vs}p{~vzz|yi~tyu{~|iq||z}z}~|ntk~t~by}|~y|{v|{}w~wz|o~{{|zm~jy}rt~x|y{s~yw~xwzztyvvw{}}z}}nsy|q}|z}wv~{tz}}{|vwu~y||u}yy~z~{~u~u}pxp}z{}}x||o|w|{|~{{~{~y{x~{z|~}{{~ty~}~|}{r~p}w}z~u~}~~{v~y{uty~{vwssTze|vN~q|q}mvbkp}dgnoya~pvbx}wqnlzwu{|{w}|}x~}yu|q|x{v{|~}y~{yrv}~}xuo||xzvw{tux|q{sxptqvzz~www}yv~z|z}~znt}w~z}w||{{t{}upy~~}|y}~yyx{s{zop||w}yx}vy~|w{s}w}s|z|}~x}}}|x{{{ww}y{d|n|mxvx~}w~twd}u}x}{v|~~|{xv~~ve|xy}w|wunvxqv|}{i}kҋ~r{}sy~}o|~{t{xpxy|x|}i|}w|y|qw||y|~}x~|w|~xw~tz}}}~p{yozyz|~|~~~x{}x|~~xv|{~|~|zz}{{~ztwp{~}xzzz~x{yx{z{|}vytt}{sxzs|{|}|hq~~}}|ug{wy{wr|s}u~}~{y}vuq{|~~yx|y|}xuxv~|||~}r~~~pswrz|zyzz}t~}tu|~~}zzx}|}tqtzywu~m{w{~}~xs|y~y}~~~qpw~x~x||tz~~}x}r}wrwwz~{~yz~|~|s~{~yt{u~{~}~~~~vt~|v~j~~~y~xy|yy}vux}|z~}z}wv~{~}|~~|r~qz}}|y~twu{y{}v|}vy}u}}vn}wwuz}|x~zx~y}y}tv|{~~|uuz{}}u|uy|{w~vuz~|~{~}{w~Lv~}dr~txqytkprw~~mop~~y{~|qryuj_vukmz{xyrxv}y~w~ux~}{y~}y{}}~{yi{rxpwz}x|o}z}yzty|{y|{|vt{r|xwu~}{z}w|y|nz||y{|{z~o{}{~~|~~x|}|}w}u|z~zyt|v|{~{}uzuts~}zq|z|q{}a~^q~p~ozzqs|}wpui{vyq~}ms~|]~yt{xp|hynj|~~q`|~u~}z{~w{ju}v|x{}~}x~~~{q}~z~x~x~ny|~~u}}zywu|p}{yzxz~z{~v|||~u{zvx~|{v{}p|v{}|{sx}wv{|{x|y{y{~|}z~~{w~}wz}|}u~zx}}}~|}~~|{z~zvy}}ws}{suv}ty~x|}~yr~{zyvrpu}}|~~~{yy{~{}~{|q{}|zz}vsz~wwyrpv~v~}{~o|~}{||x~fuuj}~{~{~s~xw}lqzrwgu}fz{s~wv}y}wsx}ryux{u~|nzwzy}{w|wty}~vz~p|u{~zsvs}~w}{x~{}|~~||}|wt{~zr~~~y}x~|wz}{~}rqx{{|w{~v|z~z~z~}{~x}|~xsqw|}y|w{uu~yos~xv}||ylymuy|~{s~g~e~o}g{r^r}yenny|}~|r|t}qurn{zw}|ws}y~~u{~}xzu{xy{}x~m{{|~rz~x}xzz[{~{b|~q}{zw]yHwroz|qat~|]{~|wrwx~~qw~smtzyz~}|}|xx{yt~p|uzx}vupus}y{s~q|zqp~uyxpvq|xzvy|z~wu{{x}}{~{Sx}m}s~{y{quzvvzbyfszx|}yzruls|~~|~{{~}z{~vw~v|l~x~|xx`~{zxn|lu~|v{w~eys|~t{zuvn|pu}u}~w}~w{~xn~|{~~~w}~{t{|xt|uw}||s{{~{{|r{ty~}p{}glx_wy|u`ns}|}{vy}uq|}~vyv~~~w{}uys}}wxzsx}{qolypz{yi{~kyz{wvs|~m{|rzmuzu|zw~{x{r}~xqwzr|u}w{~xyuw}|uyv~rz}~~{x|xxzx~t~{~|{~u{z}}{~xwxxzs~{{{sw~~w~y{}x}{u~|~qx}~uzzr{vvzzyz~~~||{roxr}xw~{{tq~zsw}|~t}u~}xw|y{x{~|y|wt|y{}gq~}y}}~~zw}w|~|}z{}zy|||q{~z~tupjw~uxjynnY_~x~rbXhtzkqhqsbzdcyn}|i{qb{l}}{z{ij{sjurhi]kys}gxgvtnp}k~vh~usr~[x|}~{~~}~zyz~}~vuwzz{u}~ux}}vx{t~|~q~|o|~z~wxxt|q}r|z|wov{w{|qx{yoz|~wxpu{mzzz~~~|wq~}~~m}x}}osxxy}}|x{z{~wz||uzxqxx~t~~ywy~rt|~~y~~z|}~|zxy}t{k{x~{y|~z~x}}|{zy{~z~zw~v{z~~yv~y~u{ww~uwvsvx~|c}z{|io|z{yy||v}|}z{v~x{|~~wyt~x}~}~|}lwy}~~o}w~t~qzzpu|wp{~h~ywz{{wx{~z{~|}|ktuyp|{|yq|}wwotxwr~}zw}wy||{k{{w}qh|r|{vk|xzvpqzv}~y~v{svxz{{wqpfzxw{y}|}qyswv~~w~vy}{|w}~vw~{vrv{ym~|~~n~xz~r{x{~|}}~}~vwvysu~~~u}svyw~{v}}{tuq}mxst|ux}t~s~{sso}|wzuy~|sz{}xpyz}v~}zny}~tt|||{z~{yuqxz{~tmzw{yq||yzzsjo{onxxx}x~p~~~zx|}}w~}|y{g{kv|trn|y}zzy~s}|vewwosv}||}wt}}zbz|yx}}}z~{yq{vs~w|s{lx~xUnqvddq~k{|ʕ|_}upulw~vwsyksp}{{{uv~|||}w|vxvtt|~wlx|x|~|sl|Ynw{v~{u|~so|}p}yr}nztu{{wszyq|xg}wi{u|rk~{vesq~s~v|q~~}u~zxyw}yxwz}~}{{quy}usz~w~}vz}x||zzd~ty}|y{~w~w{~{~|}~~y{p~yzu}~susyv}~xv|xt{w}nq|~|vxx~|w~~juz||w}~{}vxqqy~ji{x{Wyx~x~~zlnt}Qwutiszt|~}xs|{x{zw|~xr{o{trmy|Z|xi}uzwtrsnussTxr}~}{s~[jh~~vvosv\syӋ}~ttzxmnw~lwuxq|qz~xw}yzs|}y}|||wwy~{~}{vw}~zylv{yrou~q||~}q||~wy~o}}~zzzxzxs|~v|||y{v}m}ou}s~x~v|xr~w|v~~zvx{yxy}{{}pmv~hyuy{}xzzx}|zy{w{z{}yzw}~|{otxx}}n~||~~}V{{hzwzpq}~{}tx|~t{}|}y|}{}{|s{zzs}srpwrzs|t{|p}|wyzxx{uyvwyujxxxx~gwz}vx~~~}br}qgwk{r{z|tp}|vytv}iyrx{~zv}y}z|}m{fzw~}y}~s}rs|zx}~||~mwz|~wxvstn|urxywvv~t~ls}usyy}|zr}xv{|w}u}xhy}zx{~{~|ntq|nw~}~}|z}~}y}~}vrwuql~uos}~psq{zno}u|qxi}ywusxsw{|~vqcxx[vdyz||Tzz|~qzy{~t~~wy}}}g~}~}}~ss}t}x|}{}tv~}z|uuvx~yy}u|w}z|{~||~{ty||rzyt||zr}owrz~z}}wss|~~~wvys{}{}q||}z~m~xy{|y}wtrz}{}|vry\|ky|{j~z~~{zu||ywy~ofxw{pw~||hx}yxw}x}}lxod~mx}{vjes~qx~}zk~~u~|rNJmwy~sqi~|Nqwmwsv>~uo~aytygzfpqa{yk\lpvul]~wl}f|z|fpk}}fgw~z~{|s}xy}zp~|r~q|y|}}}}~xoz|~u}sx|ox|euzy|xw{~xr|{~zyu}s~}py|w~sttv|uz~wv~{}x~}y~s|y}{}z}}~u{t}|}|~y}qtxz}u}zsr{||~~||~qw||z|{~w}||tu{w~}~ztxw}|}||zx~{{w}{w}y{~yrx||y}~{~zz{zx~xqypynxw|~t}|v{~zwrsv{~|v}~yz}y~}~~{wy|z~|p~}~{{~snt{xzr~wzx{wu~s|zuw~{sy~u{x|jzw~vlr}~}v}zrv~Z}|}tl|tywrvzs{}~v|y}{|uzry|z|}zztxw|vowup|z{vuxywzw|tl}l|~ty|zyxxt}o~||vx~sx}z|~x|r||z|v~~t|tmw{qz~vx~x}{r}}z{{vz|y||}ptqz~}}z}|z{x~xuqwszvUz|y}~|~yny}yv}z}~x{x~{m}wy}u{{|z{~w}{tvy~~x{~~}}rz}}z|~ztq{tw~~t~z||zxx~}vtwxx{z|z~wsz}x~}xv|}z}|vy|wlug{|qwx~v~v|}yy{{}~x~|w~~~slw|~}}zxw|~zx|~}{}~{}z~r}r~qyxxsx}~|u}~r~wv~pw~|q~u{t}ttjry|}vv~xv}}|u|{pz|}z{r|yzx~rvtznv~wx|y~~}v}}{}}o{u}~~w{}|p~}{}{w~y~~}~~zz}{~|}}~|~kx|{~jxz}tpw{rv|~|{w}|z|x~}r~wj}ywzx}wyy}{}{zx}|txz{zs}}~w{|~x~~y~}w~xt|prrvzrqvwo|}xnx}xuzvu~ntyw}y{ushvru|}xeb|vz~wn}z~}ez}uwwivy~~~k{v~}{}yr|ss~zyr{||||{j~x|}}z~{zv{~szy|~oyty~n||~y}}xt~zt~yvn{wx}y|}~~v|{|~{||}w}uyuwyny|gyw~so~}y~w}x|rluyt|t}u}tz~x|vuttwyr~yz~vyrp}zm{m~yoro{vt}q|~|~z}ymq|mqh|}vvr}rzx~r~z{{~}{xzZ{zv{{~wwtyy~s~~}xu}~}|utztwvvwot~v~wt|~qsxy~{zv{~zt~u}~vs|wztv~tw~znto}wnz|~z|w}uo{p{yt}qsu~yvjt|q{|{utyr|u||x~~|x}|}z|y~}vroxzny{zwzit{||wvuuyz}|p|}qpyx}{}~zu~xx}y|}{n|{|}yv|yz}~~zx~|{~z|{ryvy}r|~{}p}{i|~lw{zpuw|ozwz{ru|z~zwzz{xz~r}nzxzw}yposx{upv~|z}v~~~}}~{||~s~~xk{~~r}{v}u|{yy}|~o}rau{~wvl~pyh}y~uzx~xslv}}vs~~}yyvyyxy|Vl}|qnkb{f~yptv{ou|hw~v~zy{zx}nt|nr{{~vvuyz|w}yx~|vzv{}}|wwu~~{zu}}p{~yxvu~womww|}w{sxxvootvy~|suxuqh{z}|~|dzxzw{}{v}ryyzzyy|wyw~w}|zy{}x|v{~|yx}vvmvvzq|kuxvuxxt~zztwjyzwzt~v{ozuzvy~tv{x|}v{y~}rmt{zuy}w{}~wr~z}}yz{|xyv~|iz}z|}}{w|~xz|v~ov~|vu}z|}}{~y~z}w~yknzmyw{w}}s|vtvx}xx~wspy}}rx|s}mttw|x|xszuxw{|}}}yn{y|{rzz}~|xjjyxo|}}v}||~{{{~}}~vw|zt{{~{y~{w~}}{~~}}~zpw~}wz{vozv|y~wwwxyw~|ty|t~{wyu{y}{q~x|z~pmvz{{~}{||}|{suzss~~~tsq|}}}}|{~www~~|nrozzwy|}zvfzq}wquzmvvy||kpju~kzyus}y|{xqx{~yp}z{sq|}z}~pyyz|vtz}}{txvy|x}ya{ut{y~xyvyx~~|}~s~|}zrrynz~~~u|~}}ss{{~}zztwzzwzwt|sz}zv{}wryyxz~zzz{{vt|nv}x~||||q{vzpx{{x{~uo{nyz~~oyyx~zt~z~w}lzz~}}~}{mt{woywv~ly|~ttz}~}~{|vyt||}}py{{~vs{~~|~{{{|t}{z~yv}y|{xzr|qw{y~}{|xzuzyx|z{w}~}z{z~|||{trn{{}|x{~|mswvxz}~yu{z{~pxrt}~zz{p{{|v~s~}wuzx}}z|v}}q~x{|q]|{wjo{stlxy}y}|v~~v~{wx{}vz}zryzks|zu{~{z{{w|lyatwz}vzvizy|z~||z|y~~|{s{~|}}}||vty~|~zxu~|z{ou||||}zz}}~~yv~}{|w~|v~s{|y{~|y||zyw~pvy||y|{z~zz}~|{zzov~}}w~c~~~u|uq}|wzw{~^yr}zhf}q~mwz~t~}{|ug~~}W~xoz{|{rz{nxxjqc||sysyzwil{s~xuy||ptxmzW]l~y|n}}q|nz~r}wSnzr}{tlhyudVz|z|dw~xv|vz{xqvu|xy|w}wyyy|z~wyyy{}xyt~yyy~}zvmpu}y~|yxx|xy{wy~~|qqwx~sw~}~wwy}~~wyz|~upyrxstsxv{~~~~{}vwz~{}x~~uqwu}w{{rruu|rht{w}zh{yryluuy~vny~r}v|nzxml~y|~||~~tz~y}u{~rwz}t{x~r~~u~wqsutyy}wzx|vpw~y~}~flwzr|~p||ys|}xzu}~{jszz}||x{~y}q||ox}{~q{y|}~~wz|~vyx}|y}~k{vv~y}~k~ztz}}y~}zux|}}y~q}wy~uyyr~{{x{q}}||w{}zt}}}|xypw}~rvz}xw~~|p{zy~|y|txt|vpuv{o~~t}r}}||zx{py}tyx|{}ovy~}~}}v}~}}yz~~~p}}{{y~{||szГ|zk|z~}zuk{z_tjxu~}~x}z~zb}gpwv\qx{p~~`z~oyw~{_myjj||}z|}~}}w|xw|sv~}s~{~|{yt~~nx|}z~vw~w~uz|z}|v}xyfv|oyu|}~~zx|~z~~ww}~{|}}~}{z{v}t|}}yzxyxy{vzt{rv}{w|z{z~x~|txu|~y}|yzx}|wm}|}jwz}{~vynszguzt{vwx{qry}xy{r{|s}uyys~vxxx~wy~{}y~|~ypq~su|z|{w{y}|}zvyspzt~s|p}}{}~~yzzr|}~zv|y{wq{ztnz|}{xr~|rz{z}j~p|ty{}~q~}vsy{lyruy}x{suv~x}{~{v|uv||to|~zw~}~y{}tq{~y~}wv~~|xuzmz}sx}u|}{}y~nt{vo{m{}q~}w}wsu}{{}yz~}s|{y}}xsw|}y}|{~}|}z~w}x}wzu{opxy{~||~{~y~w~y}}~|vu~~}|syx}uvu~v~}x}zy~|{}s}y~}~~||~~~~zz}x~}|xw{n}w}xy|{}zz}}py{zwyy~}~rw}ltxzqxs|~x{|t}u||o~~upuz|}{w~vy}~z|~y~{v~{x~{yz}xz}|}u{}uxyu{r~ywmz}~xys|~{tuzy~{{}}y~{~}|}}~}|x}||w}~w~~~~~{~~|}yz}}}~~zw}{}~zz{v{|~y}~zv~}r~~}փ~}~}x|~z}r~z~lu|{k}vw{w}~yxq~v|}w}s}s~vws}~}x{|m{vuv~|}yzpzvruz~t}}n}ps|x{u~sg~~~}x}yzz~|t|}|l~{z{u~uz|qwuyyzq{{z|t|{{y}~|y|~}w|}v~|xz}yvx|}}w}~w}uyz~zz}~z|}zy}w~{vlwuypYs|yv~rq{y{xy{}{{{{}n}yv}kwr[{yy~~xyz~~}nyxz}it{tu|kw~tzxo{fpfsrux|}|~y{qxvtyT{|~lnwxzlrymw{~}|y{yyz{y|~~{|}}w}pq}|{~}q}z~|x~f}xwwq}}ux}t|ww{yy|z|yz}~wzwxvyxxxl|y|}y~|~~}u~uw{~yy~{o~urx|tuxtw|wz}~~p}xz~}z~~|yp~stt|w~~z{x~z}}z|}}~~zw}zz}yw}~~wrx~}{|x{~y|~{||}z{|uy}|wyzrr{}v~z||z{~~wrz~|{|}{{{~}x{uyzw}}}~}}~jv~|uzsqvo}|~zzws|twil}z}myuq}w{t~}s}yx}~}u|~|p|zx}z{~yyvs}s}|tux|y{_z{}yucj~zv}f}v|~x||zo{}zu~mq}|tc|~|bp{qyz~x~mror{z{z|yq}w}y}xu~}~~y~~w{~~}wx{|xrr~}}szwzxz||ywx{}zyx{}|}|wx~||v{xs}}~y|{ykw}{j|}wq{~krz{wk}v|uw~|dy}ix|x|u^j~vy|zzttz|w|v|}otz||}}z{}|ymy|yzm{v}|y}q|~xvwxyz|nr~|y}wx{y|x{||x{uv}}|w~w~}}~|~}|u~{uz{~{{|q}~y|}w~{~zw{~}x}}~}|{z{{tzrtrkr~{ro|}t}˅|~}irqvw|yl{tt~~{oysp||Yl~svluu{qvv|suwrui}}~~}whuvt{z~~}w}~||{}{s{w~z{|wwz{~~|zgx}|}t[xz}zz}vq~{~}w|{u||y|r}}}}t|{t~~rzuu{}{|y~vq~}v}}z~x~yp{~yz||n}m{{xurz}{x}|w|wqzw{xy{||}|vzs|o|{|ytyvz}~~y~}r|{s~x}}~x|}z~~v}}|v}~t{y~|{o~tw]S~~|tw}|Ys|{|u}~}oqVvzxt~x{}r_}n}t{~wy~}v]{V~nt}i}x:w|wz|t|ws}~yu|y}~w}ov}|h|wu}{~~|zvjlvqw~{z}|{z|{|wtw~t}{w~|sx~pxr|{q{}x||zz}|x|~z~|{}w|z}|~yz~|~~||v|t~{~|zz{~r~|~yzyz|||{tooxv~l~wczvtyv}|||lew|z~|~ywy~yynny~yxttz{xyut}{{x}|z~t|xtwjywx{x{spvs|~{w~~}}s}{zw}}zywu}~|}zr{~xyz~y{|~szuxxy}zxzt~~}|y{z}}z~||uyz}}~z{x~{{}zx~|wywz{}p}}rsy{u~d|}}zvz{zyzt{r}y}zkx{~x|p}z|sy}|y}z}wu~{}~|~~tyquw}|{y}wxvu~~}w|wxzz{yh{p~ou~}ywzx}~v|{u}{zw}u|{|~p}y~|xy}y{yu{~y|}||||z{~|}|z}xt~{z}t{~~}}w}huiuTxvvvf{zx~ujqtu{kovp\oskr}yjx}`vytlqvzi{eyxwY^~t~e_uuuyz}zsvwrx{~zz~u~~x|z~{y}e~mqv}w~p~{}S{~s{|vm{~z|}~stl}ps}sy}g}s{~|~y{}|}~z{}zx}}u}^{}}|su}~wzznws|z|t~~w}}~|wy{x|wwwup~|y|{}~~{i}~xwt}xo}x|mytrr|vxyy~m{wx}{|u|{{}}z{{|yr^w~u{}}y|t{{w}|zo}|m}~x}}}r~zyx{}xtwz|}mu|c|v{r|~v}o~y|y{u|~ot}uwt}|ut}{u{~y|prs~}x||~{|x~tx}}vs}l|u~|wwuxz|}{xwy~}~u}w~{~v||y~|}~}~{ystz|yp}zt~}{{|n|}~k|v}i}{y|vr}|~|vz~lx}psw{~uz|xmx{~}~~~~|}{|}z{zs}||~yw~s}}|{~{}uz~}t~{~zxqswxz}y}mz}{~|nyz}{|z}t{~~y~|||}~~z~tv|~~}z}||}~|sxw~v~{w~~}}|~s|vpXr}w~u{}w}j~|syzQ~{~z}}}~z}yrpwz{~|}vw|yy}}q~zmz||tw{|x{yz||x}r|x|yssyyvs}u}||yzr|}}zxv}zz~~y{xx}~x}}{xv~|xyyz}v}z}zy}~xwzu}x}v}}uz~wus}y}z}s~}{~~wvvy}{yu~x|}wuvxv|~x~vywvlk{mwyv{}}ryse|oz{|t~~izzeuic}x~tjsu|n|pr}a{}~nzytm}ty{yx~w~~xu|p}z|y{x}v|x~xxo{t{v~}uyt~zx}y}{z{oy||y|xzx~}~xx~u}{~x{sywx}}rn|xw|q}dp{ws}{~n|xou~}wv~~xzzvzxityo|z~jyuq{l}_}y~z|~{vw{tt{j~dz~|xtr~~qwxl|}}zvmk{zyw|w{|{n|yxxsu{vzqyzz}y~x{w{wvxdnrno|{jmasx|s{}r{oxzyo||xy}|szyz|}|y{z}huvqzo~{~z~{y|qz~v}{q~}xtw{}w~zkyyo~|~t|}|x{u}~sj}u{{y{vl|s}~{{zx}}x~x}xyw|}rlws{|}u~|y~y|}~~xs|~xs~{v}x~|vz}{}zt{z~wy~}z~nrxwyuxs{|~|qu}zv}t{op~tqnxnzs~z}xzs}{ll}rszvl~y|~y~x|Zz{uysz{{y|{}xt|t|wqvn|}}}{q~yxxw~yj}u^{qywz{y~zgw}kx|x{||z{|}{z~p}x|x}|~{w}vxv|}tzyw}~u|~x~}~|t~{}zrz~x~|}{}}z}z~}~xt~}|}z~x}}sxsy}~~q|~t}|s||{{yw|}xz|xt|z{}}~wxk{{~~z}w}~jw}zx{vzwtw{j~r}|~xyt~t|{u}~}u~z|{v~|{q~y~|}wz{~}|}}|~~|zpz~z~}uuwxzztuzww|ytvy|~n}yu~}ztv{wn~t|ztxfmvu{yvuzyywxqv|}v~dkynvy~}~}x~v|{~|~}|}}yz{v||z}{|~}~y~yx~~|}}w~yh}x{t{{||xn}zvz~xl{z{uoxyzz~|t|}|qrw|u|}{hz~zqq|zux~z~pvzu{~~pstvwzxp}x~s{{|sw||{}y{~{s~~pq{xxzx{wsz{ns|xq|~p~|}~xsw}}yzp|~m~{{vnk~||~y}|~~{z}~wzwxvxzywxorz}}}~x{zy{|~y{y|z}zzuxuxsxtu|w{~ssy}vzzt~ooy|jt}uru~y}|clour|u|mo||y}}wq}~ixox{}{z{xy|~zry}z{~i|ne}~~~v{ywr~txsq{}ww`|lyi|}~t{r|rsy|~|~xvk|t}~w}uxwwt}}pozxq|vz{w~}|tv{g~zlux{n}{w}~{unrz~|ty{{xs|rz{jym}{~~{yng_}wyxw~|xtv|sruzn~p|~nzz{vs{uuvw}tx}f~xuzm}xy{}zklzsu{r~yytskv~~syx|v}xqxpwq~|yt|}v|x~h{~vz||tzq|ryx|}qw|~x}y{{{rnwzs{||~yi~{p|~q~|~kv~ztxiwxxszuw}qz{mu~xysg}~}m~uzyywysrz{{y|{~~pzzi}rz~yryy|~~pxwjr}r~ztr}s~|{|xx}zs}|s{z~~vv|x|l{z|uy{pt{}y}srv~mo~}xxy~||{~y~t{zsfqw~xv|}}t~y{w{x{wv|y{|~zwq{{r~{o~s~|bpo}pHjmxc~}dsh{`uwq{~=v}yxl{xe{rl|}y{{}zzu}|yxt~|r}}~}{|~t{~{`zwxvv~|mamnvt~r{rwln^Kwczx|w~zz~|qypywt}oyszxwypkqzvj}gt~{y|wgx}{l}~~|f}x||r~ks}~~~xk~t}{zyswn}mzvyzr||}~~zw~{vxv~|wz{|w{zux~ur}|{}uectun{}}xq|}}tp|pz~uw{}{}yw~|~}{r}~||}~s{s}~{y|xx|vz}~|}{|~{{w|zy}}~zvxr{}yyruv~~}~z||vy~}~xwh}}|rw}v||yyx}xyzngq|zwzj|opz|ant{gkyZ{szou|}ru}q~wxqt}t|H{Thwh}vxqgsv}u|1u[su}{~|}sydv~o~kv}~ryrjyxZxzgy}|w~t{{~y|mzxq}y{{|zvv}w{u|z|}}~{x~ux{v|xz|w}~}~}y{~yvr~z}~}wz~z|njz{jmz~x~vys~lw~zylmx|ux|vh~{tvzw{~v{zwnzm~zn}}{jx}y}pwvzr~xx~|ww|x}~}|~u{}{}{}|s}ny{u{~myu~}z}nqrzp~u~skpsyonszklws|yrl{rw|}~tzxsvwsyxs}{~x}wuz{m}{{{zpt~{y{|~rz~tm~Z|uzgwsyvs}yzvlp}{}o~}||xwu|y~z{w}{|}}~wyv}|}xxr}|}}~{wz{ry}}}}tz~tql~||zs|i~pxz{z}tnrdx~ipyu~tpyo}ltm|uxrpmny~yl{|}wdzy}}i{||kxq}uq}wqpz|uzprqxvxssy|ry|rtny~w~q}v}}|x}t~}~r}|}}z}uto{t~~y~~u}o}|z|~pxvvs|rxtlr}|~qsvrxzwlno|qxyq|~~zowx}vz}{|y{~~~|r}w~|{|n~w}{t{}}}yz}}~y{zy~y{v|}}zwsxo~~w~|w{z~y~|{|~{||~xn~sssnzuqsu|z}yj}pwmswx~y}|ty{c|~to{z~u|y}|v\g|n~{hm~uvx|qs~ntbsxzw~~q~}{|sx~{}{}}ypux}v}xzrv}zxym~o}|u}u}}{z~|xz~r~|{zzzz|{y||nv}~}|z}p~~kz|wy{l{~~qy{x{spy{x|wl}}}}|~{{g~~{xz~w{s}{|}|{}s{~|}~{{|zsq}uwxlz|~~~qnzo|xrsz}h~{xy}jy|}ruv|w}~z~wcjcokygx}|nqu{z}}fvzvti}|{|z}wy{}|x|qw{s}zuz|{}~|u|}vtj}}~{{~|vzx{{v}~yyzw{zy~{}~}}{~}xx{}z}|}l{ts}ur{||||x|}{zztxzssqt{|hwtutzxy{zs~xwvy|}x}}t~{}nh}|}v~t}}}{}y{srzt{y~syyvux~n{n~|wx|w}wv{|rzw|{}{{o{}pu{{{|{x~z~x~{q}{~|v||}y||{}}~z}z|~}|~||qzuzty}|v}wwu{wxm}rtu~}w||vx|||yz}~}~}xyxzy~vur{{x~{|{|~~uy~{x~wus}wwyvzxyzz{wywqrw{w~zwmy~|}|z{~~vz~yx{~|xq~|vw~x~|{|uxy|r|w{||~s{w|{y~rxtqy{k||zrz}ttvry|vv{xvxx~st|~{~i}z|}yfquox|yzc~sry~x}y~|qqc~yxtoy}ktw}l{|ry{yuz|yx|wl~|zvxu{|}|~|m{~}xx|q{}|y~svostv{{voj}{{zw}}|o~u~|w{z{vv{|}~qu~yn}uzz}yo}uy|}z~yxziot~|zszs~xw~{||~~~rzsmsx}v}r}uyzv}i}v}~z~|x|~}z}~}u|ztz|~}{}|}|}~s}~~xxoxxnxjml~~~uv~uqr}vxy|txuYwwp|y|}s~nt~|{w~~r}z|v}x~~|xx~r|yyzzwy|{xv~{v}~~}|z{w~~u|~z{{||~{}|}us~|~x~x{u~{ys|yv{~x}yy~xj{}wp|}{}zz~{xzxt~xqy~{zy{vwz}zw{}u}~||y~}ytyyyxzx}z|vzzzx{xwox|~f~||s|~y~}w{uy}vz|}{~}|w~u{s|~u~z~}_}zzv{wrix{}~~xz|}{~z~rtwssnn~~yxz}zk}~wv}}v|{}y{|}}{x|~~tyu{{z|u{|~vr}}u||x|y~}~v}|||}}yzyp}~~g}|wx}z~~~|wt|}}y|ty~}}ju|vqwvyvxyr~}}}n|o|}s{vt~~|w|{|texhx|~|xwu~wymxzxx|}x|~}{~}}}xyzy{|{v~v~|{z|zw}zw~yt}|r~_zmuywuyyd{yitvlpozvb{r^y~q|}w}y{~yst{y{}z}{znvy~z~syvy~{{n}lnp~x~t~emr}xovprrid|jsq~|sxz|mw{}|{wv|zo~n~~~~s|uw~x}uv|||z}|~{w}y}}k}u{y~|{x}{x{~}|{su}rvz~z~zzw{~~|~~x~z~yyz||twy}{{sy|{|{z~~y}{tx{u~vz~}m}wxrt~}~~w|~{t}xyps~uvsyuz}xy|zz}|{}~q~~{||twzx~~}unwp~v~x|lwxwzuyyc{w|z}|x}qouzvwx}{|~~~r{}~w{|q~vy~~z{{~}|}oz\z{xxy|~w}}|s}r}zz|yzzyy~}}~}|{uux~yz~ztz~}ax}q}q}}r}|yxv}||w|xw{r{x~{v}v}y|xrlqzk~sYsx~zv]y~||wu{Wwtfz~vxuxvrr{y{|du|juvr}}|vqv}mxv{ywrwwyqsy{plylw}y}|yu}~v~}{}~z{|zuywwry\z|~g~eb}lvjmxxxzk|{z{}xz}yyWx}}yunxsxttz}vz|}u}~~zlzeusu|ywx|{x{e|vuu}{|xv~{xw}}s{lq{}syzp}|y{{~xozx{t{|r~~{~|z}|ur|w~~wyzwz{y}x{o~z~{}~{{{~xzultw{s}}~v{y}z|~wxu}z{t~}yzx{v|z~z|y{zqy{~uw}}}~{z{|~{}{qt}~v~u{}{}}w}~o~uwot}|p|Tym\}p{v{z{ppx}xrziwg}mtzosp{}hquu|~y|n~zxht{u|wqv{uyn{hyspo|swz|p{~uxxu}|x|z{x}}]yruz|||~xr{}y~wl~~zz||{~}vu||u~}wuy{{rzwxj}oun~{}{y}|oyxmos}{i|q{xzzys|m~|x}{~}t{|x|~{|uyxv}~qozyxzy{y~{~vwwy~~|{{~}zx|~x|z{z|u|o}}wv|txf{w{om}s}y~~|{|s~~p}p{yyV|w~|f~|~}m}kykz}}~xz~ovruf{oi}~u}{x|{zu|ekx{}}xx|}lxzs}{~|Txvwm{vt|zq}twuxur|ov~||x|xux{}wux~x}q|x}|uvvt~wx~xy}|p~|xwm|~putd|xu|w}yqsyquyvk~lz|zyqo}|wo~yyv~{|t~|ywzp}y{zsww|r{{}|{y}x}|tx~zt|wwzyrqxz{y||x}}ty}~xwytqxuz}}}l|zv{}}~ytyz|~{uz}s|~{y~~~~xw{||~y|zz~}}~r{~nzkwzz}sx||||{~y}~}{}{z~~|zyz{~wzyz|y}v~y~y~vzv|~}}}{yytzw}{{zwt}~{x{~{~{|~}}se{}}t~utuq~rpvc|}vum{||r~|mpt}{~ijqiyyvhy}w~}z}nno{moysy|knu~~~|qw|zt}|~{u{~}}~{z~|{}~yz|q}uu~|{~s|}|x}~~}tw}|pzo}z|w{x{yqv|~ytx}~z|tu}t~~tyu|||s|w~|}n}~u|tzu}z|z}xz~~y{vru|~xxyrvyyt|}~z{zuzzywzzx~o|~qwqt~~~rxu{uz|||xwtv|s|vrz|}}wwvsy~x}zxt}xxz^r~gtsyyy|xzb~xrw_~qutyzsqxy{t{~v~|~wrz}|zztz{yxxsup~zz}x||}~yt{uzzz}~|{|v{}xyxt~|{|~ps|r~us}uzx{}vw~~~}{xy~y~}y{zw{~wv}sx|}{}}xwy|v}z~t}t{z}}z|}zwt~u}vt}yj{}{uvqwrw{qur}}vy}~~||y~s}p~uusjw}wxuzz||ww}|rx|}wswtt|}y}xskv~zg|t|vy{wyyqtvuz{ww}|}v|u~x{yz{u~qxhixxk}vyvsnzj}~pz}y~}hyzq~x}}j~~|rzyu{~~u~wx~~|{y{|||~x|xy{||txyo~z{|v|xxvsvy~yy{~{|{{{jypr}~z}~o~~}v{wx}~yt|}}t|xx|~}x|~yu~xor|t}}rxzyw}{}|}|}z~x}|xq{~||xww}zzz|{~|y{xxznv}~}~{c~}}u|v}q}{wzw|}^xq|ygf}q}mxz~t]zs{Q|rvt|irpy~y~s|W}xos|~}|q{}vvv{|hzwox~|yz{o{{vwmvz|nxrs}rz~|~zyvw~ky~xopow|xys~~|xt}~}t}{y{lxyc~||ytz|~su|{y}tx}w~~x{vu{yx}w}wwtyz||ztv}|z~w~wz~w}w}}y}}wxz~zu{yx~x}{|w~{~r}{}~zxw~y}x}t}zw}~~w}w~φw{zw~x{~}~wrf~{w|q~~yx||~|~~uc{xzu|xw}yz{|ytrr~n|{qzh}o|~{wx|slzwz|xj|}|z|x}ywnvus{|~ytvzo~cj{vwo~uuw||ry|}{w~wlyxs|zy~wz~zzzxz~x}yx~|yw{vzu~}|hyswuv}p|frtn}wg|nz~{~xykm}ts}rzsz~xr~~v~}|}n}yzzz~~~zz~n}xy|~xl~xD}twr}}m}~}~{~~~}i{rq{usx~vkw~myyvhvu~yxrxznx}{lwvu~wxyzyxx{z~}nvybjxxjr|v~}y{|{p{pvrt{}|y||zxxtxx}wyuvzvmiqzru~ytw~w{|~}ts}uf{wwW~~}{~}xzw~p{z|tta^{zy~oy_p|v~|uvkbzq|ynzt{qgzly|lzt}~|w~|~y~~|yzxrqxtvzyx{tvw|{{y|yy}zx|{}{ywyui~||~{wuv~w~kxuvosus}x~~}~yxt||}|xs||w}|{}z~}zzr{w{{yy}vzx}|xvs}uyawx~mou~uz|{x~py}{wyz}py|~~|twq}~y|s|rl{~}w~vyp~}|~zx||~q~xuv~xnt{~~y{tyvlo{osyv}|szw}yyrwnv{v~tu~||{sw}zy~w~zuxws~wr||~{v|xy{|~uyz|w|i}wwx}txv{~}{~mwzxwytw~|m~{|{yp|u}wt~~vzn|~~}{{mw{c|qgryu~}~v{|r|y|{|zy}w}~|~}}wp}}xvu}~zx}~{y}w~~{~{~{xyw~{|sxzsw{|~~~ts{}tmqy|wyqyv~}zvn}}}zzrwv~u{w{}v{otyq~{rzz|fmQaz|~v{|}~w}xwz}uxlymz}tu}sz}|qsp{|s}{xhlr~~v}opxtqwzvpmz}roxz{~ywu|zrzy}~z~zzvssp|yyqwqzszy~rztux|~}}xw}vzs|{zzvy~}y~~~~}~~xyy~{vwz{vonntu~s|~|{xs~~pzu~~x|~|~|}{{{|zy}|}xsxzqu~n~q|nw}ry}p{y{tuvzxu~{wu~}w~u~{~}ts~x~s}||}}~~{}~~|~|||yjqyu~{{tzyp|z|smozu~}~xq~pzm|v}mp~|w}}~}~~}}~}yx~|}vzzy}|~w|ss}vul|~wumsu~}ww|yzwxuxyo}z|x|z~w~qdqwzywl|sxxkgc}~nqywrqyZnvwx~~{kusviwuquwk~zek}uszuw{c}{z}y{}xmxzzzuw~n|{}}z}z~o}s|z|oznursz~ywzx~|{w}~xl|{|}u{s~|~~}}}|znzzpsq|rsuyw|}wsztuuyvu}tyyqxvxs~{}x|z~u}}{}z{~}|}~}}~|~zzx|w~xy{z|}~{y}y}t|y~w|v|z~{~~yz~~y}~}x~o~ur|zwxvo|zq|s}ruy}|qw~t}zvy|wp}z|~{~zx{~zprzyxt{nqrwvu}|~vp}yy~||zu}{p~~yur}|~u|y~}vp~s|u{{y}zxtz~}x}~|{|z{~yqxx||syy}~zwq~~}s||~~}|~}xz~{tux~}s{l|rouso|x~vuw~txxtyw}{zwlny~owv|~}}{{}tss{zz~l|}~~xl}u~{~|xuyq}~{{}{w{w~|vtq{}{s}yxrwuvxv|vzu}}{|{~|~w}xuvy}u{i~z|u{}x}twurttz{mqvz}~~zzpx|t||z~zvyrzw{~}{|}ruy{wrp~vxnt~vy|w~y~~v|t}|qr~{}{{v}}xt|{stpmotsyn}y{xvu{ytp~zzztyzrjbqwsw_c}yhp}~z|y|ltv}xlz{ww~|my{s}h{~wyzkwvulv}xkt}s}sooz}{}iy\{vyt{{x~}z~}~vyxw}}}|~{vyw~ryw~u|}}}xrtxuw}~utzx~qwyhu|}zmvu}{t{{q}wzz|z}o}{t~zz{}pry|}{o~v~~~}ozy}ux{xry~}z~yu~y}~~xr~}v}q~}t{}w||}~{q|juv{v{{s}~~}}w~yu}}|~yzl{um{~}g||}xtkx|}~{{y~|~}z|x~|}ztjprur|lvyx}wy~zvwtq~tow~{}qvuT|}~ouzom~|~zu~|v||y{}{{~|{||z{ryrrpununzq~v{~~r}tx}rvwx}wrz|x}}{wzxtr~totq}sqwr~~wv}t{}w|w~}tzxwoz{yyx{y||x}|xz|}yxwx}|~|u~{}}~wr}~~u|{~~||yzy{vrt~sxyxqz~{otv~yy||yy~{}|~u}xyt{zx}u}w~wr|r|yvptv|uqyuy|}|}|r||utro~}lx}x{|zpz|u|}||{{}}}xn}}v|zrum}~wzo|{ke{t}t}~{xzz}yx~uxz~|yyv{z~t{zt|sw{|xs~u~|x}{w}~}wy~{xr||ys~uz{w~xtvww|v}ts}|}}rxt|v~zsvqx~X}||~~~nw{|q||}}|zz}|yx|{w||{z{z}~yq}{x{z}s{z|~{}zHO~wx~txwyveez}|}{suwx}{m~xrwxtv|le{t}mfkgylgf}zolqsfuu}}w~w|xpz[qrxyt}x}~||~~|zzzw}s}~|u~x{{qzw}vr~s~}xzpvxwyw~~z~{}owzvvu|zw~~ozt~zy}yt}wt~~|{v}pz~}|~kzw}ox|}}}v~sqw~~zvzz}z~}{}|~xszu}wqmppt|}q~y|||~t}zt|pox{zvw{w{v~yzw}x|u{||{}y}qwx|~{w}}}{{y||~xxy{}~uxxs|tqquv~zw{z}}~~zpwy}{||rp}xt~{|~}|~}{y}xry{yztu}qurwzt}~tvy~{r~|q~{gsw|y~{rtt{t}x}o}|{pnxytx{}yt{~y{tnvf~yqxz}|twk{}z~u}||~{}~s{~|xw||~}}~{{x}v|}o~||y~}yt~xvzt~~yosv|w{|~xvwx}~twssvw{y|~vp~{ou||xyzt{~os}rxz~s~}ptys}{zwz}m~xws{{yu~~}zy}}v|~vujwt}z`w|xdizsw}vhk~rwqsmutptiztuwtxn{uyp~wzkowcqvy|zsv~h}t|x{vvyopr~}t|zj~}yz{yzktyvwwzyzu~||zxx}x|}wo~{{}x~y~|~~zt{~y|}ewqmmoztk~}lwszp|r~~|yuvk`ttj{lx}{o~vwqzcoeq}{pszzlysrz{htf_}o{\{|hwmockvy|~~~qztox|zz{o{qz}m|i|~~|{sy~zu{f}~|mńm~~n~~ztvpo{r}zw}|vr|x~v{}qlx{y}{{}~~w}xur{vnyxzk~}~wnyu}{~zrt}qq{v{{y~uyz|u~y~xz|~|kz{|~y~u~~~{{~w~v|~{~~zxx{z|{u~yrysrpvvrystzz~{}wyz{zp~~}}m~xq}|{u~~zw}|~|w{~~}|xzwuz~~|x}}xzkpu~jv{on|yn}yjxkr5l|~~{y{uwznx|{n}ixwot~tsu|{y}srx~y~}}{}}y|~~~{wwztttxx}~}z}~qywwto~u}ro}~uy}ozvwz|}~yz|{}|y~~y|}~~yzwt|zrqtwz|r|xz|{u~|}{~m~wwgxy|zzuvqvvzp~{{zlwu~{wz|wwx~|}s~}|rqz}|r|rzv|vtvu}{|xt{q{r~|vz}}vy~~{{r~{~}~||~ssymrvxrvz|uxg{~etwytv~{{uy}xlnwpxwyrz|{rzz{}~|~sw~|{{xt~~v~q~~|~~{u}}z}sqx}`~n|i}}u}gU}\fry~|tqr{}~qlplu}~}r|oodOrx}wgensy{zp҇~z{zw|v{w\ux|q_cb~n}nuzkh}zspmiz`}u^}yz~gezq~}qn{ttk{zru}~||~xy}|z{k~|v}tyw|{u|glnv}pq{vxyqtx}zwtwmv|z}r{yyv|vu{wxt{k~{}{~|qyzvr}sy}{nwx{|w{vlw|{r~~}~x]w{{xxz{u~|}wr{yx~~tzzosnrqguz{~rqyrz|gx{shqv~mk|wtsv||{{yskvo}ytx}xz~ydyyyuy~{z~~txvm{|{x|qx|t~rsuy~u|wt}vu~}v~|}sm{snztvg||kx}|zqn{~|w{}tyqg}}}qtqv}||x}~{zz~y|q~p~~x{}y~z{}~z{}y~qy}vzzyu~{{ty}}x|}r{tlmr|}nyu}Mw|~twz}}x}l|orzxw|{|t~wx}zuov~~~{x~ys||{esysr{y|u}~}otuwwu}sxt|rx{kt}zrrq{~~sv}s~usty{}~{|{y{|{v}}~{}x{zzx{qztfw{x~~y~}t|{sxy|~suy|uzz~z~~zv||w}xx{~~c~y|z{z{{y|x~u|zw|xrot~s~}vx~~v~yt}w}~{~{{{zypxy{}ujxsuiks}vz}~{y~z}{z{qx}y{}t|zx|f{vq~|~h}{zsv~y|yty~u}w~{u~|zy~|o}~txxxt|~vzs}tx{xr}q{{wt}sozy|ru~{{zt{}yvyzzss~lzrm}~t|{yu~}xy~~t{{|~q~~wt}wx}~~zz|z}~{}ywqyv|t~z}}~z~||~{y|}yszu{zp{oss|w~s|xzs{y{z}z}~w{|py}|}z{}pw}xz|jvxo~wr>yvpr~s{}Uxpzxy~rn}vt{~yyys{xzttnxuiwf~|qvX~mv~nutRyvz~zx~rx~{}qsmo}~~z{zs}v{tWxty}vyt{zs}uv{t{vuvrx{~|v}xz~~||~~~x~vq}~|u{}}{}~yrx{wy~x}|~y|}xyxyszrxx}yssxptvnrvy||{yosrvr|}~}q~szz}x}w}zxyst}wr~~{}{{v|{~|}~uqt~~}w|}|~|vww~uvr~v~~}rww}~vntuwx{xysk}x{{|{r}zu~w{~}uxqzxz}}{we~jyxrx~v}zqjy~|n{{z|yzowm}}~zttn{}q{zpl||tvpun}rriwsozzru}vvu{~}kzzj{}ux|ith|j{|y}tzxk~|pXj|zhpr~Ņ~n{ujy~zwko{pwlTLk}{zz}xkewuz~}u}{~~}}s~yu|qv}y~muour~}uz~p{szywz}y}l{t||~~r}w}|}~w{z|}xv{vq~vv}uo~lutz{zux|{~xvz}x|{{|{x{s}p}~}tp|r}~v}}}v}~~||}wr|}|v}|{~~wrz|}v}~xy}~|||ss}z||{w}}}~z}x~qwy{||{~zxwv~~}kx{o|{z~uxzx|}{~u{y~|z|v}{~wq|z}w~u|~~|}{~~utz{n}vyu}~|s}}x}}wxt}~y~{{{}y|u}{r{u|~xy~|~y~~{|wtp{x{t{u~|xovwrx|wt}twtzg|}~xz{z}~n~lrn}vkxy{r|qx~zsyz}v}zzv{{~|yn~vrz{|st{}tt}x{~}z|zzz~}uxur|yxln}qxrwqx}sy||{}q}}p|vyzryuus~w~{x|yy|~{|v|wjsl~uuv}w{}nvwo{ntjaguyw{~wryd_ofy}kssx~zzrzv~x}{vlxzr|}{u{|z~}~~~i~v~yv|}yz}|vx~~y}w|~vy~zu~xw{z}~~}x~}}yy}}{}~{|ys|k~{t~yz}zy}||{|||q}y~|ux~qr}{x~qm||k|~z}|~xx}}x~{~}}xy~w||y{v}}v~w}{|}|yt{|~{|x}zy{wz|x}z~yiv{gu{aSpsn{{yqE{zaxws|wzjw^~wszt{tzvukq]tumpUfhufkoowzujyxzylpwyuxe{tfzx|gq\}~rqb{qfr}{ymVaoikywxu|vw}owzv|w{teu{zrr|t|~swmzxv}x||tp|pyryz}ryy{xv|v~x~supmyxy~~~k~}~}~{~{|qrw}}zu{}y~xrp|m~|}v|{{}ywy{}ts~~~r~{|~~x}w}u{z{sss~}}|yrwruqvz~~~~u~}{~wvwt|~vp{}s~r{xx~ur|{|oxzl{xpx{{uitzs|~vyn|{n|x|{qsw{~wy}~~ruwp~xk}x}~|z}v~||x}||~qsqsrt}{{o}q|y~y}~}~sw{z}yzvz||vz}zq|}|~x~sr{}yr~~wq}{u|}yz}z|yyv~e~zw~~}~o~zq|y~}v|}}yuqw{~|||}y~~xqzuxuob~|y}uz~zy}wyv~{y~}|x|~|sw|r~||yuzzx|yyvys{rr{{{x~vu{uwu}qzxzui~{|~o}}zv~wv{~s}uqt{|nwzy}wu{uy}z}~xpz}}xxx~ouy{wzu}t|kz}{wo}wz~|y|}~~|}w{~~~xzq~y|~zmzqzuxzyv}{u|{uz~~{|~z}i}}}u~~sow|zuy~~||~x{}p{tz}t|z{xr{}y|~}yozxxqskz~n{svn}~w~sy|}}xwy~~x{w~vz~wvw~vzusryptv~~}s{||{rz}oyqvttwxu~vzz~k~}xo~tzwpojy~[~x|{tyys{{{xxz}yt}xsw{zz~p}}|mxu{yt}u~xzuz~~}~z}~xsyzzn~{{sy~q|qxu~~xtvpovt|xx|z}}p~{}s}}{xy}yyo}us|ozlzvq~r}v||}z|r~p~{x}~wzuvtxq{y|{vq|uz}v{w~z}{x}ujzz|||vxy~|z|ux|zp{|~~v}}ymz}ru}r}|~w~|uyp|j{ww~~vy}{xz{~xezw~s}{qy|yt{{zwtz}{{}}v|v}r|v{wwwvt~s}x{|wm}~yywuu|}ovvx{~oqstywrr~qysttx}nz}~v}ru~}{}|yxpwz~|z{~{vsu~|ps|nxu{y|y~x~x}u|xoyxt~o}yp|}~yuxxz{tt|{|}}{v{sw|ws}{~vvf~ywkv~j~w|~|xwusizts{p{wx{{|xd~ouszz|}~xrhovo|txnww|{~{~x}{ypxpx~|~p}}y||z|}}~}~w|ywrsq}}y{qyz|lr}~{s~}x~{yw}x|t|xzzq~uosu|xt{{}}z}~}|q|yunz{jrj}pxpxysy}yqlu~zz}{||yxx}m|~voxw~q~|trpn|ww|wopwmv}z~u|srzxpuq{xvos{tsvp|}x||ra}wp~m}{s{}}|z~x}}{}~~|}{vq{}v|}}}~|}}}v}}{{z~}svys|~vtmqrs|r|xvwzw|}o}}}sv}y~|x~||wr}{~|u}~~|}{~~zq~{zv{{|k}m|}~vz}}~t{v|v~{}{|{h}z{t~r|yt{xuz}rurz}}y~~{y~vyuy{ur~xnxuwzt{|ztv{xyu|y}||x}y{qc}`xYXopzm}|yu~{ws|zqx^bupxyzz|{g]~fr~cf~~|zl}p{rwrnnq~t~wr~~~v}|{}~|zvwxxwrt{ksxxvq|t~}cxp|w~}|~z{~z~xv{t~|||r}|s|{{zx}xxt}vwt{tw}xi{{}wrv}~~|u|~x}z~yx|r}|u{}{~|}}nzz{|{~z}|z}vtyu{sy{}~}y||~y~`fxxsfy{l}~zu}vlp{l|U}{}yvn~ssxx{zrxs~w|vqvzf{wg~rrks}ls}twx}}tlltwtyrx~sxwpjyzft~yq}xspsy{{ptktr{q}hu~w{wqs~ky|xn~uozufyww~{wzk~jn~vrx|s}wqnt|||ymv~}z}ozsx|z~zy~p{wzy|yzsvqus}z{vz|~qur~mzu{{{v{{}xkz}~hw~y|}vsll~}sr|zy~g}lzq}eyhw|xx|ryzsy{z}rszw~y{~~zwqq|w{~}y{z~x~}~}~wqzlv|~pw}~~r}{}ww}r~y~~y}yx{~vw~zz~tt}rs~{yq|y|~{}|oz{|x~|~{o|tmwxznvzrxzrvszsz~~|y}yuq{y{oyt{}|q~yt|~}~|wttw||v}{}|}yz}||y{|x}{y~qw|}{l{y~rqux~s~{vx|xux}v~u}z|wz~s~vks}orswrz|u{w~}}~~s||~}rwzy|~}{ut}w}w|runrss{ux~ux}}t}s}wr~~}~v|y~rtq|~~|}zr~s{b}lphuy{v`y}r}ikw{porzscnUvk~zpg{vz~ik~q^luxxt|~}~z||s~kzx}yz~u|~r{r{|}xs~~x{ym}y~~k}r{zx|{x~xkp}|y|{|}~}|w}u{w{v~|xzm{xu||wvppszvkz|v|z}}~~{z}~{w|z}}~|}~{{~~}}}zyw}x|~|~{x|x~vxvs{z}v|y~|xy}m}zq|{~}~}u}~t}{}|vz~v|~}~}w{~{xz|yk}uz~{wz}vr~}}~|z}iuuvr~|szcuzz|w|v~~k{zvw~`}yy{r~kxqvu{mnwt{n{~}xywzutqsw{uu~r}}wxm~w|u~xvzy~g~k{yxqwxw~{mh|~t{y{|~mt}{{p}}yx~}y}tz}y~||}}y|z|{}qr{szv~~rwx~~syz}w{x~gw|s~t~uu~~|}x~|{p}z}z|z~}w~x|z~|}y|~wzr|}~xv|}z~|}~t}yuvwvp|t}uz}~|zy}~}~p~~x{w~myugsfzv}qey}}xhx|vu}|msvkzcvtsl|yv}wtont|j}qzwW]rn}ouy}lt~]o{p~hq{anv{a|vuv|j~Yrvmsr~nyx|x~{vxw}{q{|x~{r~|zz|{}~vr}}}|u||~}|v}|pwxurw}|{tv|ptt}xvx{r}|xsz{|w|}}w{|xvr~~|rvpuv~|}{m~}yuxnszsu{~~|yvrxwursvyys|z{k{tvvs}qovu~}|~uy}w{wqyzr{{xmuu~yw|{{syxyt{vntwmywy~xzypwu~ouuuqozywz}|jlrvz_|{ds|~{uz|~||{ptunt~uxrvsz~~wutwv~~}p{ts{tmzz~~|}}|{{u~uv~|~x~}{xtz|kus{|}zy{xywz~~~mx}w~v~{z|~m}{|}wyq~|q}v~|vzwx|~{wzzkxz~~z{xzv}v~wy~|zw}w~us~{xxtv{rtvt{zr~yo~|~z~{v~v|{}v~xtxx~y{p|y{wx|}{}j{|}}}i|}zrpxwww}t~yvx~~~ppynju{uuv{ypoz}eymvnjwvy|w|rtr}l}szr~y}}wv}uzm~ytv}~vpzouuyupv|zitt{||ktz}w{zwu}|y}}x{~xq{wirxyvsv~}~wyxvjPcz؅rswwoxwu]wocr}qdqIyh{v~Y|jzduunw~a~x{]iy|tqvayzwuv{{znnxizq{zpx}v{{~|}y~~qp~qqx}}us|{ssl~}lw{{u~osszo{lxovtws~~}x}v}}~~zq}oo{~x}vz{y|muyw|~}j~~|vs|y}}tuqz}z{z{y}~||~~{{}}|~~}z||{s}x{zuqm~{}yo{~p~~{}~x~v}}pvz{y~x}y|{zy~~w~}|tsxxuy}uwxz|{uz~vw}{yx{}y}}w|~{z|qzpyoq}yyx|yewlx}yt|qxrtyuq}rvq{rvt|r~u{ywj{uy}|}{wzzyzjtzu{|{rzqvqw}ztzqo{y~sVu|iy}~~{l{b{}}~wrs}n~~|stx~k{xrz|s}|iq~v~pp}}o|}q{vmmu}xw{ta~pokyq~~xsiwp}iyzk{zzw}xu~{{~wy}wvz|z}xqxy}{z~x|~yo}~~y~xy{y}~z~v|z}t}vwuzsr|}wyysmp}vxasp|{y~orslk|zwzxtwyn{st{uryxpsu}zyzyuzi~zroqt{z{r}tku{~woutly|~uxx}tupb{~ykvzo}t||}m{zq{qm{s}|ujzx~pkq||}o}uwq|{{us{|{pvup}uiyyx}zxt~}}{}vxmov~z|p|yp|l||syw}~{k~rqs~~wx}|{yo|q|}{yu}v~x}xzz{v}mzoptupy|{xnzv|x|sv~}}}{wo}~yo~}~||s{~xsz~{~}~|zxyw}xw}z|yz|~r~ea|y{o|}~ifzeYfqqqyhbsw}rk}z|~|^xbxxr}}xzwvu~fwk{yvjq|v{zwvvot}us}vq|uvznu}um~zvznyv}rzz~|~}~v|y}vl}{{{yx}yy}|z~vtz~|w}xxp|qlx}u}|hz{uyv}~mvuum~wv}n}}}nw|xx}wyu~zjwp}{wy~~z|z{z{wz}}wzwtvk}{~}}~|}x|zy~wr}w{|zputyv~{~xzux~u~}uv}{~ww~~v~~s}xx|z}{{{}ytzzxw~{u~{zyz|zxo}~vz~q}a~|n}|{yu~~|r|{|tpzwqz{}z|~{xo}sk~|t~q|||o|wy|g}`{t~oyzputqyuru}mt~xv{txy~hz|l{ynuzky~wnyztvzrgzvrzt~n{t{~zqxytxqql}ylxux~m~~u|orpx}|}zsiu|t~tuwlw~}xp~v~euzrsps}{}|pu~~zgkzu}vv~x|||yym{v}nt}||tyt|u{~}xyywzo}~txw~z{}z~}~||{o}kwv~ujx{xv~|~{y~mbk~cyungls}wxnl}~|k^sokLqzZeqvilU~luqeul~s~~hiunqjnptbjzuvqwu||ifvnzyq|o|sw|kliwe|ow~yuzw}|uozvq{{z~z}~wsutv~}~ny}{u|x~x~{t{}}yy~{~xx}z|yx}|{}}|~w}||zyvqmtvz}zgy}wuzmo|hnurz~|{s~s}x|y~u}os|sw{zx~}{x|{~{{~z}}kq}z|my}vzxi|x|}~{~rp|{y~s|}{||{z|vu|uiu~q~zvm{|zu~y{v~~{}|~~wr{sv}zp|v|}yt~jw}wyr~~y~rv~w|x|x}}v|yux{|~{v|}}|p||}}zmw~~k|r~yu~|r{{oyxoxztlxyi|~yqy}tuts|||p}{{uy||y}yy}y{z}y~~uz{zzw~}zny~xmvyn~|x{}zsx~x}||{m~uy{s{~|yv{p{~}|w|rs|~}~nw|y{z{~y|~p~~x~{w~ym}~{|q{~m}|~||wv}wwuy}swt{zwot|szsx}z{~w~s~~{zwu}xw}zwwz~~~~|y{~}}us~~}m}~ww{y|~~}nt{w}~}y}rw}{z|mozs}{w~|h}xtziuxup{{z{pru{~z{~zwi}ywxrvu}}vmqxp|}ts}}}lsyx~~xxit}s}~tvx||w{qzurxvzx||tztwsxvzrwu~n{~vvp{y~~~frt}u|m{ltq|qo~~y}uy~~fl|{tj{s|s|p~v|~zrrwnh}yjr{{wyzm|xqwvyqrp~x~q|n|}y{~qz{nwqyuse|{u{fu}zz~lx{|vrtt|q~uu|jz}yyu}q|}{}r~ytzoqzw|}{ut}|{}{|x~|tx|}nwk}~|}~wx~yt~uv|wu~wzupxzvu|x{tz}xt|uwtxv}j~}|mx{|~x|x~r}}yu{s}sx~q{{}v|}ys{{|yzwo|}n}m{txzz|}}}ozt|{y{{vwt~tz{~z{vz}{tusxzzuxw}~ww{~}}}{{|w{tn{xnvxwztr}inopvvH~x~h~togqfzvxy~y`p}jpym{nhq}ox}z{y}|vrvc~qzw}xn}|tvvwyyz{{q|~w}v}}|yv{s{|}zsdvsx||swy}{msrvwwzz|~kwy~|uuv~ry}z}{{wsv|{~tr{tvp~|~~|xzyu}e{{~uyq~}vuzwus~yqwy|{nyvtxr}}v~p}r{{m}o{|tlrypuww~zwqzz{|y}nw|o}~wjw~q{yzzqvo{po||~vurq~}zzvmv|wy~v~{z}|~{s|}{ft{vt~ousxu{zsvuyh~zn}ux|o~~s}yxzz}y{vxxtxu|~wv{vzz~xpxux{vt}{{xu|~y|~y{yqx}|pnu{~{zxuzp~}w~n{xvm~t{qs|ot|vwt~|x~}yqxoy~uwr|~qyxlwz~s~|z~w}~z}zvm|p{z{}w~}|xtzx{zt{stx|z|jnty{nt|uyux}lmxg~}w{s`nazo^z~|˒||[{x}}l{zw|}v}w|y~~|rxxu{wx||xv{~}~}xostz|v{|{|~w|q~|sow~ww{}l~{}}n|uz{l|~{ou}t}s|~zx}w~}wvxx~x|y|x}}|{zw|~~w}o{v|}|y{ot~~n{twxw}{v{vpt{s~j{q}}u}us{|wx~|m{~~}~v||}~~z{~~{ytywvm{|qu~|~|}lz{okrxzvvz}}~~~yv{}szyl~p}~yy{~}q|}un|~|ywx~pux}{}~jy}x}~n~x~yrwz{{|yu~|}~|~y~{{|yyxr}~v}s}z{}xnxyt~}{~xu}vq|zxpu~lzzsv~w~s|yvtyxo}w}qxw~x~}}~|}~}{z{~xu{{mo{pvol~zt~t{~u~wmx}v{vxvtt|qqzrm|mu{|ym~x}n}~z{p}zuyy}ys|mrru|xozwz{|{z{|nwl}~{twk}vx}{tssw|{v|zywqqp}l{rvyu~}kwoy{ipfpy}{v{x|uyotxwztwnu|~vsz}y}yqtpwr}rps~zmwr{}w}tmrtzzwxu}~|y{p|~ss}}ox~iu|~{{m]{v}r~vr~xw}yzx~yx{xxn}ww{tyz~w|}wr|~fnyy}|{|y|}zzp~}uk}xlwt|vu}|xg~y~xlipy|y{|yy|ryyzzh}sv|~z~xv{u~rzs~|~w~ox~~zmqX{t}x~{~|{o}~u}}x}}}fss}zwz}y|o{zyy~{{rx|w~yyyq~|~{zwzprwy~wzvr~}zz|zuwluMq|srx{d}swzxzvgrf|vz}ytzx}~|yqpsw|smzyuz~||uy|~t{tx}}yyyz|mzwy}{x{}yxxyz|v|}wyy~|m}x}zy{swqy}u~r{|xu{}o~{xrzv|zv|~}|}zq~|y}u}~~}}w~~~tx{wvyw{w{|~z}w~}ypyzvzvqyp|xrzwyxxueztlz{ms|}|x~yvwlvwz}|~}uz~|}{{}|}{tz}}qpx|x{r|{y|}zs}yxrw{zy{}}z~|y}~||m}x{zrvzv~}|ztovy}z}z~w{t|r~ts{|wn}}{y}y|}~{}~~~x{puu{n{{|z{w|z{}~pnx|w}|~{x}|{v~x}{|z~{~|x{z|v{wtnz~y{}uu~xv{}z}xrq}zx}}xp|p{xyxxz~|y~t}~v{|w~|x~z~r{}}xqvsv~tyqo{ux|x{o{n}tuz~vk|}xuk}~|m{{w~t}s|uyywj{nx}xz~zx~{~}~yxz~xzvxl|ul}rxzw|}~zy}~vzyy~~x|t~wu{~~|n~v~|zsztyuzx~v}w}uxyv}}tx~y{|u~vyy{q~nk}ǧkvwqtqyrl{y|m}}}tzyqu|wsosw~usp{qyz}y{u~|s}|~|||t|xwzyzw~yu|}}wx|{{}tu~|pnv{y~vz{swxxxxv~zvp~yv|x}~z~tvszx}vx{sx}|zvv}svvt{wz{||}l}|s{u{|{yp~}~vv~u~uwzy}wxj|y~r{~v}q|u~|~wzr~mt}xrzq~}~~w|yy{~r}mxz|w}r~vyz~|utrs~i|zsxtqz|ryst}y||xvyyyxz{xv{u~vu|~{zxwuq{p~pzzm|{yp~{}~z{vuom{ny~r|lc~}ovrzmwvzwsjtzZ}zzuzznozljowhr`lwjl|qvss{nvur}mw{}`p}huX{zm{vioisqp^qr|iz|{{umxnqo{q~v}jzz~uk~~}_sw}zx~|uvt}}~}zx{}{wig|~ri{|yzx{zw}{s~vwy}vopxz{u}~sv|ry~}|{szt}w}zu}uyyputy|ytu|{|u{|v|}v~s{|wiswtw|x~~z}~wu}}}vv~w{u}wqz}~o|}vw}|x|{}zv|{z}~}|uhk|s|lsupxo}xzxynnnstx}ki~dwrzq~w|kryyzxwxx|{tώmiblkUwn{u_~{yiohyscizn\|xrtqmt|dl|yjuSqYd}{|eeyqlit|_fp|jv~ytu~vv{~~yovo~ztwuxyr|}xmv}hn}zsuu}~u}yntz~~|~zzx}z|}zqwuyz|{}vzuyq{sxuosquugz|w{xqkwzuy{vpzyt}q}r~xzw}z|dy{xyzp{~w~{z{o~w{vyu|~vowwUl|vrzjsszksz~|oizme{~qtp{sxxzxu{y~|rcttw}wszzq{|{yzw~}{qlz{|nzqup}r~~v{q{~y~}xqpy}mm~~zvyy~z{lz{~~~nwzzpt}s~|y|jhm{~ttx{w~fs~t{y{}yz||vzyxmzwl~}|z{mzzx|xxvyzzy|jt}tu~~uwvzm~r|}twshw{wv}z}z~xxcr~|t}{~w~iqfq}ts}}s}~}}uluy~uvy}v|~{wz}~wu|~|vys~|v{}x}~y|}z|xzz~jzwyvz~z{ytt}~}x}}|yz|o}p|}ytpxj}yy~v}{p||~s|~~zvz}x~z{zroz}~s~z|wz~y~|~wryzuwy{y{zx|~vy~}~{uz~pt{}r~g{vz|z~{vu~s~{q|wq{sxxqm|}xozwy}y}~~u}{t}y~}q~pw~yu~vurv}v{i|~smy~xws~}w}|x{txg~}~|z|}~x|yp|ywzq}zm~kpyv|su{ss|xwyw|yn|{w|mw{yo{p~y{i}~|{hryxn|u{ytzz}s|~{n~wws|{~s|tsyx~utv~~u|y}yz}}{[|{~~}potsquw~}yvrwu|{~ws}g|xtxz~wyo~u~{xyv~z{yvym}}y||{{ly{~~xty{|xz~yurnp}}r|uuw~}{|y~o~ty}|}}v~z{r~pMz{zw[{a~h}J}tipd|zpthvvym|l]rcpUpUje_z|urՆwyzyxv~{yzivwrzm{|{ul]wx}lv|}wovyyzyvw~zkr||}mz{xw}|~h~~w{||q{ytxpxu|k|s~yvptr}uk}zrxy{{~r~{isp~x|v}yp{zt~~x|vu}o}rt}yptypxx}sw|}r{~y|x}}|oz~vz{tr|zxv~~w}txvz~wxu{ym}vz}nytx}zul~wx}zt{tyq}}{y{{tzh{uqxtjxzvyqz~mfx}i{ozz}{xwwgvi|{l}}iyt}zny~f}uy|yz~ny}prw{wy}zx{{nst}ysuguv}xz`~ygwyyts|x{vtumo}uu}}v~{mpwuzrs|xo|vgzw[ussqx}zy|pxynzmzxuwxirxyz|p}uxuqvp~ro}{sxk~vz|~w{y}v~~zwy}~qyiy{ymwv{v|nx}ky{|y}uqed}t|sx~~z~}qv|}~wyvy{~pp|uvur{ziyszxn~w}wuvpwv}yz}u~~~~{tnr{|{tz|~}zluewv~zuz}qt}kxz~v|yxq}zh|ooyoyum}~v~rv|||}}xx|vv{~zxxruzx}}w}x{|wxuoqh|x~xm|h|rtw~ygvv~~~w~n}|{~vzs~|y|jx||ovnxpv}t{{x||v~}}}kp~{u{ytyttp{|rwxo}xwwo}~~}~x|vs}~vby~swzg|z~yxy{yz|hty{~|hi{rzmky}~wjr~e}w~Wo]m{~k{zzxlrpvk{xsr{{jnuw}yswpqzoj}tlwrmjrzXw~{{{nsur|~nqnu|qgjown|spuzts~|thOtxtryz~{}{}oz|~usp~q|yv~}vx}|zs|vv~it}wy~k||t||wyu~mp|}v\}}tx|vx{v}wzz{{oqyx{g~t{msz{u~utzx{osrpv}wkp{n}nuvovu{u}}yszttrys}lfzuo{{pt}~}y~vzqzyypz{q{vv{vsuz|ynouuuu~ov~vyzv~{~zry{{xw~}}s|{}ww}|{u}~|~x~|r|vu{rv}}wg{zm{xzvyqy||zy~ux|xtxx~}jlrvr|w~|{|sww}{xx}|xwvu{xz~|rtl~p}~uS~~rsw~}wynw~iy}vr}cttz}r{ysqvqxl|}xuu~|z}}|wf}}ry{|}t~qx{y~vyqzw}{vxpv~`y}{r~}|u~y|~~||x~z|uw{wz~}{t~qyyz|yx}~swn~~zov|rsy}~~u~wyzzt{~ur~z{|~}~u|}|yzvysz}m|~fns}sj~mkrb{pw}~xosdzqtvN{gerzuhrp}|}zu~}zvvfui|ku~_~tq|nnz~ytzu~x{{vw|}uyn}o{~|w}~w{}~y~~znwzy~|{{|~{{hzqsystyv|~{|ytr{|u~|~y~{v~||zn|xy~zt~w|||yp|nnwt{|~z|y||}pvvr{yu|yy}unqxlrzjw}z{rqdu~yxwt|}rx|d~{|x~rzyzu{yy|{~}rrzt}~|zn~~{x|o}t~|{~{~~{mxv{~}{v|~{o}{o{|tmx}q}vsn|l}~|~|~rx|uow~r|vwoxwpyz}|w|w}v}yv}|{w{xx{}~~u}yo|zkxvVv\skrtz}|}`{jv~~ywlpvxn{yvshzm}vz}pwyswsvqzohpgm|dvov{mxpyKtZpm]{y~o{xx[cl{Ėfzuyw|}rv}tulw|w}q~nw~prvyy{r~|nnym}r~rzz}|z~x|r|~|~|}zs}uzwz|w~mxt~rx|xz|~{~uyw}yn~}zzms{|k|wz}}}v~{~~|n}yzl}l|x|rw{{wny{w}|}xv~pq|q~}qvpsvx}q~wxzyvtsw~su}}~sn{wtynws}mtnw~vty{xyynx}py|~~x{w{zw}|yz}y~{~x~xr|o~ul}x~}|}}n|v~v{~y|t|}xzv}{}vyov~{||~zy}}|zv}zn}x|t}zxw{w{mu{~x{z~||~z}|pvv}q}~{~{}}~wo~~}ux~yz~wy~~z}}vw|rn{mvr{xy{v{vz~}y{z{|}t}zmxvryw|w|y}yy~w~}t~myr||u~py{}~|xlyyyss{{}v|{|t{v|y~}}v~~~v|jxy{~wuy|{|~yryt}~q}{}xn{w{wq}z{~nv~}w~n{z|u}yyzx~wuy|~v~x~it~zw~zssvzlyxrzspt|ty}}u~^fy}vrtlmz~}{lqyz}|}|utvy~{ws~xuxxw|s{y|~~y~uv~}{yzigp}|zynvzu|yq|v{xzwzwuy|uv||xwwgvyzo~y}w}{~tvrv|{vz~x}~}~|~v|~u|wzzzy{}z~{vflztyp{y|v|sxlh~kvuwv}~x|~ynyy}~rpwuq{vlw}}|zts}|o|kh~x{zzz{|}|tjwu||{tx|lxu}}x{q~q{unvnt}opuwyruuurzrs{tztq{~q~y}~ksuy~nzwss{ktt|{sxxuyrx{wtyz~y|t|uu~y{}}~nwp|u{xs{{s}}~vv|r|}zw}{{}v}q}m}wx~ywojx}mj|||s}{tozyyyivxpt|uq|~qp~op|{y}o}}ru~ynz|w~r_}v~|}{|{~|ws{~k|{ytwz}}}tt|tkzs|}|zxww~w|l||{p}r}}zs|z~{tzysx}vxy|qytzu{~svn{{xv{~{}wyy~t|unqttw|zv|yzswzvly~w|rw~}{yr~zytuy{|{r{}|zqv}o}xwwl~}yvq~wzxyxvsuxtuy~}{yt}~owwm~t~}r}n}~}}rz{vquxwrxr~}w}zuzxppoy|swwz~fz|}qxosyi~zuwmxxvs}{ix|{y~y~zz|zyovv{|ruuly}lzwxjp{wx|wxx~xxvz{~m|zx|s~|x}}p~w{rquzlz|{{txtw}q~~{ro}}vrxxxp~m~lotn}svvk|x}}v|~|Uyx]^^`sn{upvvY|hvcp|ygyy’s|zxno~vvtxpuf{d{lstq|nosyz{nwynpyri~bdvtxvzpz}zk|pyq~^v}xlvozx}q{py~ivzylr~|~}|ut~{{|}nsz{z~zkyquh~y{n~tstq|~|{w}s}y~{x|zzzzxj~~xmut{zu|tlw{pq}dtw}r{~}uwvzst{wzxtyt}|yopo}{uz{szyxrzznywxy|r{y}tw|{u~v{{to}tz}p|x{v~xn~wvzyq}||}{}xv~x}y{ow}{n}}z~zy}~|xyuw|nvnus~~xy}}~yqzr}q|xx||~v~vuo~yty}}t}|x}zvz|}vu~r}{v|~z~rxmz{tuuw{}~|s|mu~o~|irv~pp~o|z~xwq}pzx{rzp{pz}|ws}nyu~{z~~|zw|ty~{~}~~{~zwz~}ty~uqx{ptq}~|vy}s~z~~|~u}suu|}m||}{|~z|z~y~~}}|}z~y~wzx}xzk{otrtpxyh}xut|~~~r{z|ws}{w~x~s~tv}}||~yt}{}~yy}~z{|wy~yn||nz~}{{o~o|~q~~|~y~}u}{|znyzr~zsm|vx|qw|szu~|uu~{}vsr|wppttwiuzpqu}~x|stt~{uv~}|xvy{uyy}vl~tsw}tmkxqmuvw~{mx}q|pvwzlcnuo}~~u~w{}p|zzx|||}~}~zs{nq}}t|vxuz|~vzto~~gux{wz}~~v}i}{~}nz~w|kxry}qw{x{fo}~pupw|||~~ys}{u{zsxvg}vy|{z{}xtw|}t|o|zyytn}s[{x~xzzsw|trt}~rzyywxx|t~wvytxzw|tz}y~otd}zt~{~s}}u|{{w{uty|tnst|uvoyxy{wousvcntzyr{pxt~szp}}zhsx}wwtvtyqxux}wpo}|}vsrw|kpt~wyq~~zvo|zzgpvos~tuo{~b~wxeby{s{|zr{wz|n{{rz}yv|{y|~|xn|}{srxpyq{~|}opvq}|~}o}x{www{~y{wxyy~v~~~}vwy~~x||z|y|ko{{~xw|t|ot|{y~}~~}z}||yvuvsn}p{s~|v}w}pk|{s{~z{z~~}|}x|~uxxyozmznvykx}yz}|{i~ny{u{|uusyz}rvsswl~|nuz}~{yzr~xvtvr{|yzp|z{{vxxxzv{ylo~|zxzxzpyyw~|~}ysv|rr~zwykq{~p{xy~~rv~u~xy|p}~~mzy|v}vy|{zwvz|v~yw|k~krsvgp~~}uv{{lwz{{wj}~{tvv{|yum|u}nf{puml{{yu}|ywzz~~myk~k}yyk~{t{|}rs|t}usm~y}vxu{ly{kw}~~x|v}u~xwm~~z}l~{z~~zw{s|xxwx}yv~s}l{qk~rouzpo}{|xxv~o}}rz{w{p}v~|k|~nvwwt~z}}|y}wxv}t~kzy}|ovxn{vzuzp}zy}|jt{~v|u{wo~xx~t~t{~~}x|x}~txzzypy}y}v{~u|xvxyvxyitz{~|ozv{vzz~w~xzz~z}y{{ws}u{}uy}q}y|zq}xqvw}~kq}|~|tzwy{ywcv~||~vqzxyyrwn~|w|z|yx}{wr{wh{{x}}my~w~w|mywixtqury~y{tzoz|~y~v}ztvxwuzz{~w|~xvqxnz{tx~}xvvzus}|~xt}}wnx}~z{zrzjo|xzszxz}s||lvr|zp{v}~qy~x~zxv}y{{}}u{zn~tx{z}jswpg{|s|wy~zy{~zv|x{~q}}tz~sz}sv}n~lrszwt}{{vs|s~|yuww~r{|zvxprx{~~}x}zy|syzr{w{~r~v~|~z{~~vz}y}w}u}s}rq~}yw{h{}}x|~mwy|~xs{wz}vtzvk}zx~v~x|{zuyz{wxx}tm|um~z|wstpz|}|yv}mr^~~r{s|t}uy{qz~sz~t{|o~fztxz}uwwwuwvyy}~wxl{plytsygv}pwu{x|{lvn~vq~w}wmzusnl~~~vszp}~~xr{~z~~ousoyqxz|}w|x~smsy~}vltzn||}{~t}s|v{|w~z{zvzpsnzys~|w}|r}{~ytvv|gy{|z~s||sosv~yvzl|}pu}|~w~t{}|vzwsw{u}z}~s{~y~{{|{{|wyxrzt{vjzojqwysn{wwtz}|{}}ox}|{ztpf{myduyin|gon{vfpk}oxzw~yvbvs}~zp{yvmX~xw`yzruopnuzq|yxrztrx~n~nw|s|pwxu}u}~|swy~xt~yw}z}wztplz{~x~~zxzpv||h~{m}tu{{muwz}o}z{|yq}x{~z|}~~ys}u{~{{n}v{{{o{~zxwuyu{tz{yx}o~yvwm~txo~~rrw~|usr~sjyy}ww}}|xx}}}}z|z{zz~v{n|w|}~v}w}||}wx}}z|zw}}}y{}}mz{{s~y{~~yg|y{z~zt|uq{}|yˆ|~|u}|~twqq{yi}x|{x}uz{u}}|}z}zzm~~{p|}v|s||r~ps{zt~un}|su}kwly|}~w|t~x}xo~p~}|z|}|y||z}xxv}~wysxvkc{pzo~|~ututp{{qjw~q}~wztu~frg|vj~w|w~s~lzx||||smx~yyn|r~}k~{y~rv~lw~}x|}}t~v{{xnyz||t~~z~rt}ttzw~vzx|w{z{{q{v}}~uj}|ow}r}yz{}uyq~~{sy~||{|v~v{x|xt|kq}~}{}~{q~j}{~ty~xzy}~yx}wlzoo|{m|zx{{z{~u|~z~xv~|}xyy{vz}}~}{nsww}~}~|v}|u}z{|~}x{nx{w}|r~|||~{ryxz{y|vwv|{}~~y{yszu~}wt}{}xz~yw~|xo{zqtuw{~y}v}o|}r|~~z|zoywqy{s}|w}{|vz~~ty|v~~yu|}wv{y|}{zws|sz~~z}zu}q{hlruo}u{}|zS|shp|x|v~vyqm}dvv}tydnb{z|mjvs~zn|zolv~nde|ze~dpxzlmysossipzmwvogY~ehylsoodw\pzetjy{qxifywnfnpxy|uppwv|}|hw}[yz~s~qd}y|yivvz||tvzeyj}zv{|tq{v~~w~}xxwq{zqxxpmzvz}wtmwwxx{y`}vy|v|gw}ttzvrr}dwy{stuwx{mwtrgwyrsoxn~mute{syxuqh|{vwz}qx~tj}}~y~xywyq|{}{zywn|vjwjxvopw|~uthv|yyvvyymqq|v|~uz{zx{}ov|cz~pwup|v{}qz{|sx}t~xy|wwzvnuyruty|mxxp|x{zuxz}{x|tyj|}uuzxy~x|ty{x|}~}||}k{|ouzpv}{{{~Qw{v~qyy{zsv}|ox{m~g{xxuyuzv}ztwhok{{xz}xt~{v}y{qr{pkf~zwvvwr{{z|~{}}~w~|yn~ny}s|~~vzp~w}v{~x~l|}~q}r~~}|zxswzu|{uy}}x{~zzw}xxtxw}ernyt{wu||{}wuu|l~|whuv{||zywv}y}pslzs{z{z~rv|~yvmuwt~n}s{wrm~n{|tllq~po~{zq|~usviq}qsnyv|u|l|zvx}xx|r~{sx|rzuxx~ngvi|uxsvuwr~~}v{stx~}~ovozyxvx{u{usw}|y}y~u}r~v~|qt|~t{wy~{~}~u|wow}{j}}{x{xum~umztw{u~wn{{zu|rijys{{zxyl}w}xz~x|q{}ztvz|~{}}y|{vx~~}z||styw}}y{n~|~~n}{v}s{tu{~s~uxd~i{zm{{zztu{wh}|l|zm{s~|vt|o|y}|~w~w|u}{|o|~uwx~z~|}q~xv|{mxu{u~w~||vy}w|v|~p|~{}}}yz~xs{{|vl~w~x}~{}}|qwt||~yq|x|syzzyty|tz|}|}}w~v~{}{||}zw|~}~qzm~yynw{w{wz|ipx}~~rerp|tzo||~zku}gr}|v|v|q~}~n~~}vxphw{p{s~r}|}yz^~|v|y{w{wv{r{}}ym|~~v{~}|sz|}}x|}wq}}w{stxp}~{y~z|~{{~xx~~pv{}t}y{}}|}{z~y}~{uryxqu~}ww}z}y|yn}|zy|zzws{{}{{w}w{w|r}zqy|iu|v}|x}~{|yt|z{{~sv}v}tty}ypzuzwxt~wn~}ts}Zu}y|{{~w}up~yoxx{jx|}my}yz}}|ttwu}zpz}szzw~|||}}y{}~x|w{zuvv{n||~us|vz|m|rwywzu{~{{~{|z}|ys|~v{yz~u}mtyxqvs}n~pz~s{mztzvz~x~u}ymtt|rz}pwvpyw{ox}}xsz~{}||}}u~t~rwy}rg|x}~~z|s{~y~zw}lyz{x~~oguzxxlqwytvtqy|}x|xs~{h}w|xuwo}}r|zw~~x}ypsvyro~~u~}r|zsuzzv|tzo}~~~ry|tqu~~~v~{{yp|~ywp|}rt{vu~|{sv{~w|yroy}qv~y}}y~vx}q~ypoty{lo{|re{sqwytp~twzmwr}n|z~|wyx~|ryr|wxqsz}{}h|ww{||wzsyvyw|utyrrfxkz}||wxj{}|zkw~yt|r{_z{yr}y}v|zx~v}y{~}s{yx{||~zr~zk~tr}z{~}{~unyz\~x}{~vz{nyzqxzzmyzr}w|tvszuz{~y~{zsxs|q~z~|~~u|~|xtrlz~ynyqkz|luz{qxvyvzsx~{}w}zwz}l{h}}zryly|{}j}~zv{|~}{qo{z{tvtw}szx}yus}}yx}j~{{zq{y}tsz{}yxuv}u|~v}l|o~z|rwwyyv~||~|vwy}xrvy}pt~yy{|}y}w}y|{}|}vn{uy|yw|y}}{toa~uus}nyvyr|}z}sy{|}{s~zzz}o{~t~}i{uqsu~jqjvtx|nrksheol[~cqytp}{u}|vxd|qpspxqwr_qno[gyskqwrN{{{ubr}vz~lszyvo|v{otzv{f`n{rpj{qs}wwomtuhxtus}m{q}ruybwiuwzjs{zjmymqyavqswyjf}xny\tqo|z|swvz{sqyv|us}|}}ywyxrw~|~||{nvz~~q|}{zv~~{q|}uus{mw}zvzl}wxwt{sx|{y~v|q|l|}~{y{}xy~~~yv}~~}~{~x~zv}|mxvo{}up~{wqw~g||~~mt|xrt|~v|r|lxx}wy|~~|~}}~|q{n}u{ypv}~tnw~~wjvf~|}}l{||vqw~~~rx|q~mzzu~o|~~x{|x|}{zmy{zxozprs{z~}yvs|ygyyv{ru}~z~q~wu}yq|~lvu|s~yzvy}|y|}yrl}xm_utqxwv}xrsw|c_zn~h{uw{sw~waj~{z|mwu{x~|{mw|ltx}wm}uw|~ys|zr||w{{|~}yot~}vq||~{wyzq{}rxemzmyrxt||wpx}w}wxxpj{l|t}r{|uwrrwvxqryvy{y{~~k~ystx{wv}y}x|}t}}ru~{ou|sy~||~{y{yv~y}~wsx}n{wvuviszwxu}o{}~u}vo~}{lxv}v{t~sy|~{{{~|{oy~vw~{z}sxop{x{u}zvz~kw|ssv}ux~||t{|w{xz|zpsp|xp~y}wruzxp|{~|}|~zrw{}}|x~yt{ty~{v||zzu|tyu~{{y{||w~|}wtyxro|||rkqt}~g{~r|xl~y}|{yuzz{zz|uty|`y}}|gxmqs{y~y||}spvwslzuzyv{qvvwjz|||zyzyy}zrx|s{z}z}z}}|rw|u}y|zytyy{v~}~|y_z|~f}~eh}~xyv|yqdpxsrrh\y~dt}kyvr{{z~vj}fyw~{u~vr{vszu}uw}yb~xyyx{~t|~mxwv{~|~vyiy||}|x}t}xrtz|k~k~lqz~dyr{wqyu|qnk~n~kx|yrs~zj{|xu~}~}y||m{ui}tyy~p}yswtm~s~uxvvr~y|sz|iz~y|||xyur{|j{~vyrt}|~}}r}}o{}wtimx|wk|xmvxuq{yxzyyx~~w{vyyzxot}x}t~}y~s}{w|qyzvw~xo{zyxty}vuky}zz{yvzr{}}ss{zrz~xp}~{|}w~r|w|zx{|u{}y{}zw~u}wus~nz~owq|{wy{~vtw}||{v~|yyurz}w}u|yyxiz}~zwv~~|~{z~}zzy~wx}u}yv~jy~r~}|t}ylpptwuyrqspmwrsv~t}y|{skqowotuy~wz{l~}vj}|t^vmpxg|}wsny~r}~|zy~zyply{zu{mmtp}xx{}px{|j}p~wvzr}xy}~vs}qw{~z~wfoy}j{|t{l{vj~lz}uowvxykxss~uur~}v~{~w|~}tws~|mt~~pvurvnzzz|}zz~}t~yv|k|slw}vmux}xpv||}{tpy~xvvs||mvfyyxo|y|rw~q|~lzxyyu}{}~zyxuzvhxrn|zty}rsz|xu|x{w{z|sk}orxz{{xzw}tu{u}x{ztux}uyw~~y~~}y}o|zy|r|vt{u{~xym|y{||r}wicpx|mk~x{{v||yxx{{wvzvwy}{yqqtzx|{|{zx{lu|uxszu||u|z{|vzzw}{}{zzv~~|}w{{w~u}~v{~x|zz}{pz}|u~|yn|{}wzz}x}zrtyy|{}nx|}zzy}sv}}uz|uwz~kw|{~}|~yv~|wy|y|w}}{}syzzj{~z|zvvt~~vqwk{|wwyuwxqxkyjz{wr|{{rz|h}~q~|w|~ww}y~}~lyyvxy|yt~{}{yw{|~}|{}zr}rx{v~z~z}zxzzy~{~v|olxs|tyvq{~}w~{y|q}zzvlm{w}p~|o}}}y}}~y|z~}~}}yoz}z~y}zy}vzv{zy{vx|jm{|}x}a}mxi|ymvz|zuytq{wz}}ixvpoz{}~tzy|skutzrzl}|{yv~z~|}^yy}~otp~}xu|~p}tkwj}uxm~||wn|u{r{w~}x~{yw{|u{yur~v~x{wwzvzu~{~xw{~}rwy{sz~sy}svxx}|}{{~|z{{w{yu~a}}|oonq~|||zvt~o}{wtso~iy}uk|zlzwsyy}v{wtus{rs~zv|rr{zx{|~t|}~ztwqx~wuy|ym}u{|{~{xxyq~{z|xwz}ywzv|zs|m|}yyqup|vu}y~|tz{p}~ytj|jwtm|zl}{xxyz{}}x}~||yyz~y|u|}}{tu|~zz}r}}wwx|w~q|~~Tvx~}wvwqvpÒ~zw~}n~yyy}~|||u}||{pvw~r||uz{}}{xq}~{jzw|t{}ys~}pmrvxpzrwq{n|~s}sxw~qtwuzvr{zztvqunz~~}{~{vz|~~z{yxz~wyu~up{zwqv}~|yty}zvwwx~z}|szzsw{}{vuy}~y}x{~}~vywn{||rpq~{y|w~zzr~p{r{tjzj|m}ymxnxyvzwp{r{sw{}zos~{uy|t}~v}s~xxxqvzz|{~}wyzl}}|w~}}||~|}~v|xzmz}ur|yntz}zƏr{~~czxxtpwzyukwzz~kqv~rvl|ywz|w}ky}|wl}{wXu~udwxxmwxxuuw~|tp|ryz||y~{}|~|zm{wqqq~{uu{}~zwxxov{tk~j{l}|lz{u}uz~}}w~x{yvu{uv}qt{z{~{{}x}}wswpy{wx}w}|t|u{|urt{}}|oyvyx|z|wuxtsuqxzjyp~zzm{|}xxoxu}uzm}w|zyxo~suxpuvtvsryw|w}|~yuyzsv|}{nymxvyt{tsx~||}z~}vp|{|{{~zz|{~o~~}}wty~v{voz|z{ww}mwpxjzx|kvtl}~u|~}{u{wy||z}yuw{iszoxv}|{{|~guppsx~xwyqyzw{ulkz}znzoq|oz{x}y~q}urz{pv}}~}}z~~}yvzruv}}x}wt{{w{}|`vv{xo|sqy}}~{szvo}vthizp}l}n~nuqv{w}x{yz~|q|u}ltot}qz}w|zz~{tuzx~w~r|xy{~wttstyq{{z~|z}{}t|tty~}~~~{}||z|uyu{m}{~y||vt~~|{t~t{|tyx~|x{~}z~}}{vt~~sxmx{}~z}~~{y~~~{}xg||qrry~}}~xxy}p}}quk~zj~|mmzow{rvzx|x{~{r|sy{rtxz|yw}w~~yxw{{|v}v~|{o|~~zoqvts}royw~vnqmzxxzjuxywr~{lbuw|zjk}zrzgv~tzs{xnsy|qz|vxhk|ys}y}}}z}q{m~hjzsynxqvts~x~p~yv}|pwpuwvorxt}}i}}twy~jw{}|z}kqyzw|upzuzyyvxuvxzsyyxwz{pv{k~}v}{y~wu{npz|zss}||xvyxt|x{~t{vxwuwmc~n~|~[yppsw~ym{tsrtzjn}qo}wb|pyz~pwx}tsz}r~wds}ypww{wz~||v|w{~fx~nnryzm|zz~k~zu}{n|~ysjyk~yvht{jz}wiq~~g}v}sy{yz~wiz~o{tnt}zix}tg}hv|sz~q~~|b{vzrk~~}|t{{|xyxpz|}u}o{oq{wv|y~~|yvwo{vri}jv|zx~l{u~lls}zx{q}wt~ryr{v}smr|o{|u{q|yws~~vt{wpq~}lr}nsxrvwyrj{oxg}u|rpnyv}x{mvv}y{njs~wtwrt}o|s}}~xm~zv}y~qqv~ty~kz~yq|w}~kszo}|yu{ym}|{k|~|x~u|y}{k~s|w|wzw|k{{}rspt~xuvo{~tu}skylvz|kxxmuzur~w}}s|}zwuw{x{you~s|}{{n~~~{{zus}}|{~uo~}y~~|vtyn}~zwqto}}v{{p~vtm~jol|{ow|vuz||x~}x|}||tv~xwqt}}xzyz~o|~~{w{uw}~tyzo}uqÏsr|~~wxzysssstryyRmvv{|m|syt}zqxtsjzzx}p|uqz~lzwzwxruwtttzis{x~~u~|v|w}||}vl{ux|ptxz|mwto~{w~{wvp|o}}wv{~zqv|uw{r|px~[sx|vz|xNzy~~px}srqt}{y|v{|zxzy{~y~l|x}zzzo}hj~z}y{~wtyw|~}{yz}ryz{hy}t||rwvm|szwt~xw|wuq~zxwpoxuyw|x}rxtwr{|wzwz{~||~}}y{t~{tx|ru~|zxw}}ytw~z~||~xx}u{~{wz~yz}txsxg~x|w{|~~yz|yur~{tzz{z|yvwwxql}yzx|vn|~y~{n~|zt}w~xxxx{v~{z}t~mw~v}|yw}vsuvurw{x|s|xs}vzv~yxwvv}y{}v~{uy}w~yr|}w{w|{|}yxry~ryyx{~|yzxx|y{}{~w~|||xz~}}~v}w~Xor|{zuzjx}y~|y~}v~\zyv~lwuu|xi}rSxq}~tsl|zxep|x{{y~vrvuyz{oywy~n}}uuyww|p}w|~xzxuxtw}s}uxz~|xxv|yryu{x||~xv}x~|zzct{vp|sr|{szzw{o~}uh~jz{xm}z{mrx{}w}y~z{{{s}wwtq|w{z}z}|o{v~}{unzx~rz{yw}~~}zwyl}xptoxyz}zv{{ozuotm~jz}zl{l{xzx{x~|zz~}|r|uu~syq~uz~|}zz~t{{y}q}t~yy}pvz~yo{v{yrdp|z}ly|tnw}xvzn~x{z~~xrzwzq||z~|tn|vuwywz~~wyxxwp~}|~uoyzqzm}uy}u~}|{x{t}{txxqpq}ztzkynwevyzw|~qv~{wuxq~wyv}ytzwtz~}~zzzq}wtrowrou}zszltv}z{t}{}v{}|z}w{~}usp{}qtw~{w|wwtyy{~stws~~~x~{}}xv|vh|~}vprqn{~qpsutl}j|{l~zoyu{|z|u~|x{}q{sv~|~n|tv|~z}}|}{~t~o}{|~{x}~n~qvuy{~}}}v{zoyv~uylpq~tox~m}|x{v|m~}rs~p}~yjyztsv{rx{{vs}wxqr~qxn{wr~twz}z~~|x|x|z|s~~~y~o~p}}y{}sv|~~{|}vp|o{w|v|~t}uuuxpxxv{{s~y{}{v}rvyr~tyw|vzqwr~u|}v{t}zsz{xkwpyss|zsy~|zwo{z~{y}swuu~|~x}s~xvuz~y|vx{}~qzw||vuv|}x}}z{zws~}tyl|~x{z{{y}v||utsm}xy}my|i~}~|{mcpz~p{vtx{u|z~yyntut~}i|iz}f{dw}pu~mzz}}{ktw~x}p{u~vyh~}txxrzw|ynxvtno{|lxvt}~}{vqw}|uw}|}zqtpuqr{os{~z}uyzw~x{w{zuur}y{x|wx}~vxy}z{}{}}vh|}|v|ux~tqy}q}lt{|hquttx|zsq{qx}|zv}u}{}t{{|{~p{{ypzu{{x|zt~l}qzrz|zyy~w}u{||vw~r}|ms{~kpvmd~}b~zyt9akoxexzjxpwqisz~{{k}xqtqu{y}v{~yq|kuyvoyxzzvytt}}tlus|wy{p}{|spyp~~}|}{|}v}~|~~n}u~x}|~~tw{S{esXswzl{v|yy}~vowvuy|pwrw}|z}yyz{p|p}s~yu}~twt|{}}k|zyyyw{quyzz}y{xwzzz~}qvn}s|~zkz~{yuj~~}}{~uw|uy||vzf}v}q~|yޏqu{|z|v|r}zxuv|gk|z{{~}ztysx~|||~|}}|{~zx~}roxpz}j~rzyz{~{zuy~}}|v}xyw}y~{}~v~{rw}r{}u|vzxkw~t{}mxyx~r|{yz}}z||~s{}syypzy|~z|q~prorv|{z~p~|wto~j}ql{zox}tyy}x~{}v|su~~uto{zvy|}m}~y|wwlzx~xw}vm|~w~y{yspqzvz|nwu~zpwvz{zvsmzvq{{x}zq}{r{xx~|}n}w}~vty|ww|~tvnxszuz|tqzy|ytuqw{}~mvq}qms}sku|}o|t}zqzzssw{|~stu{|~nz~~w~yp{~{x}oww{|~qqpzywt}q{szxz}|zv~xx}roz||v}{u||`}zoqqm|{{vv}p~}ytm~jzxyk}{}opszt|}v~{xzxs|qv|t~qs{x~yyv}|z~}~tztzyy}}vvulx}t~w{xzuz~z}|}{z~{}xzgzvrto}zuw}o}wtk~j~v|n|ylzy|z{yw{z|}{w|w~||pyrv}zy}y|~vw}~w}ys{x}ym{~grln}~nxtzvx~pt~{||~{p{~w}yu}wsw}zy}~~q~y|y~q{zu{w~||u{szszx}zsy|k~zpr{y{|dw{}}||}xx{vvx~}jt~r|xuy~}vx{n}w~}sl~~uw|{w||~~w{~t}w||uz}{w|{}{uz~|}ny~||{~zuyw}|w{z|xs}|x|||{~{u{}y}~|}{y}{~wy~h~yq}np~v|o}|yzp~sk}j~{l}zk||yryp||}x|yyvs|qu~}{y~nt{xy|zu}yvu|zv}t|yky}vz||}||z}~{gu|qpq{|mx}zrzo}}}jztj|jx|zvx{l{|im~vwy|w~x~yxxt|~rztzvvxr~pt}z}yv}ztuz}~{|tyvmvvy|yt}sw}~{{rsqzr{oj~tr~lv|qzqw|zvju}pvt|vszt|~uxuycw~uqyn~}~{xxlyo}f|{qx}|suixwv|Jrua}u~|y}kuwq}vru||pxm}ms{tuw}wyo}t|zy}z{}~yv~xn{zzq|zuyzwrp{~~h{xt|v}w~zzvz}wxuvxzxw|~wur|}zx{o|wrzzr}y~|zxuwzz}x~y|}pu|y~{ozwyv|~y||rt}v{}|~|}z}x{}x~~z|v|{|u~z{{}|wy}z}xlg}}Y{mt||zmo~}tyvv~|pt{p}vr{bzsr}{~|xxs\n|xZxuzer{y~w{rsxw{}ry~}m~t{~|}o{ry{eoyv}{~{z}i~Xhtuyuwg}gz{ttvz~}rqsptz{yv~}vtjzvspk}~|dz{kpjhpsy~pjzgzr~}z}{x~tkw{~qjn~}ssows}xriu|zrmw}rtxt{myox~yywqvttufsy}~}_~qu{urqt{mkxxzzswu}}~rzumw|||w{qx{|is{otwoY~wuzmtztz}|k~n~}t}sn}vuzm}iry|}z{}|~~wzwxvy|~}}~}}}{~vx|q}rxxzx{m{zz|xy~~ppwt}{_~}wu{~zy|gtgiqiz}{qnq}ymz|tu{tvwq}wuyskvx|xur~w}wzs~r|y{z|{|p~xw~{rpxz}ut~}}nyvwt~{z|y{yxy{sy~y~s{~}i~}mmo{p{{{p|}~{y{sxoyytmjsql{|~j~~r~~dzvsoj|wpyuzqps}{rt|}u}uwx|z|z|yszxru}my|uzn~zqz}|ttx}~{~y~}v}zz|~ws}y|{zx|~unXw~{{lvwz|vq~x}z{x~w}~|ou}{u{~u{y}wtim{|}~{w~{wuspz{{~~~t^}}zz}}z{bppp}uoyy{{xwp}uquxvzy{|qwx{|}q|}||}u}}z}{{sz|z{x~rzzz~qkz~}v~}}vy}srywy~{zuyx|u|~xt}xivt{}x~{szwz~{}||~|~sz{}|v~}~w|z}~x~~||z~{{{}zry}p}n{|lrr{|{{p~~vuyo~rtzt{|x~lw{psmzol{|z}~{tzd|~u}xz{ox{~~i}|puqrvzl}{~ww|{~yuz|f~}~pqpvl|yyzyxp}}tk}i{mz~zlyyotsx{t}{zwx~tzrz~}~qryrx|{~v|tz|{v~tpzvuxbsl||~||{|i}}ug}vp{ztxt}t|}w~vlu|}r|z}~}qzfwotpo}tuzz~m~u{svzwzp{xnptzmyou|t|~st}s||xwuy|~~sx{ys~vwlsuux}w}~t{xtvyvn}~{|~~~{|_k}xtt{suz}|x~|r~~xxkp|tuwy{vtv}z~}}}z~t~ty{~~x~}~xxywzuvu}s_l}d~}}xrws{}~{ycywvxtvm|ypnux|zz}{u|~}{x}|}|{zt}|y{{bz{q~yt{u}wrxzt|yuv|xszz}vz{t||}{~}|y~{{z|z|v~z{xw{~~xyv}{~{w{|}zhw~~}}wwvnm~br}}veqwqRoz{tvwfrq}dy{{xyy}horl~gwy}w~ctmm}v{unn~trzt}qi}ysltuhykss~{qxut}t}vq{ugy|]q|}k~z{|phzy{sy~r}{iw~st_gzp~|w}p}zixw}zr{~x|wykw|vzxc|u||]v~q|dtwsnvu}tvy{rwzvouu|}|xx|sxoy{|z{{ztzryy}zwvyr|zwx~}x{v~z|ur{{yv~~yvpx|{|~~zt|xyw{|w}}}}{|~{w~z~}{w}st}|ay~v}pzvqwv{wuwy}u}r}x|ut}zt{{yqyyr|zw{yy~}}|t||}yq~~}~w{~zzy{~wv~~|y}{{wz~~xyz}Uh|}z|~xwjtpt|szzg~|{{p~vx~yz~rs|tzyr}}p{wzv{{y|}lu{|{btnx~~zaam{~z}y{p|suz}}|zyqx|xu{xyr}n|x}vywwnp|cb|y}|xxx|tsv{wyzs|}sp}dx|tmnwlxwxsmztyzozzrz{oyysoxp}uty{q{ki}~}nu{ht~x}}wxv}st~zqspt|x{yzy~utyxr||s{}whu~~~wz||vtox|~nv~{{~yxPyo|r~u~vuk|}wv~op}xkp~a|oj|{|z|u~r||||~{v}y~{z|~uttyyzw~|u~}u}vp{ysyzkyxpvtv}u{zxx|z|w~{zmvvron{zvyzg|yy{xu}zzrxzvs{w{wnz{p~y{~wy{~~zznz}r~nzxx{zx}}{|yyuw}pt|zwvyr|{{|~twu~}q~zzxyv|~{omxyzs{zz}{yv{}uw}|w{}~}xy}~|{yur}|}sz{~xz~msz}quy|y~ut~{w}||z}||t{~r{{po~vn~um|{{uqwkwzzz~}~~|r}npw|yu{wvzk|~wz~x~||~sm}z}|~~ryz}{quZz{s{k~yqo{|}|rzol}wxzyl|gw~yyl}|{yxrxtr~{{wzv{yyxx}||}~wmxtn~u}q~tv}~|v}}}||vv{|{~v}~o}wtzxxxuvqtzxizy}lzktz~~{tyv{zv}~sQvx{~~~qpwz{n}}v~qb||q|wpqxusts|mymyvz{qw|oyyswouom}lyd|vv{vt|yswy~r|xskhuqnypy~vwvu~yy|wnv}wu}||}tm|{z~tqjxyl}tup{}}{}l~wvu{u|}kxyw~}rr{}{y}w}}}{{upw~}xzwuyzs{}|~z|}}w|vxiyprro{|~voz~oytljyvl~o~yolw~yx|y{{{|sx|~ruv}~|xy|~}~||y}zw~sv{~|muvjt~{mp}vtux^p{y|_tw|]rx}iw}ko|{lyu|w|}z~tv{w}x|n~n{wqxr~{spl}s|a|wx|w|wwxprku}w|~w}i}u}~z~y~{[yswvwt||gz}{}}y||o}m~myy~|}roy{tzsx{|}~y~}}osww{xs|u~~dystv}r~|vywb}wzrm|}uj||o~ozzw{}~st}}zw~~t}txyx}{y{z~l~xs~q~vy|{||{~}uux{|v}vxv}xpx}wxw~|k|rm|y~|}~ppxy|ouvv}stnr~vyyspsw}{qyvwz}t|u~qy{q|z|qjvryr|}{ou~}uwww{|{}p}}k{|u~w}juz~~t~sxu~}x|y{~~z|txty~||~{{}~~t|~{}w~gy|~|}w~m{on}t|~|~yuv~n|vorhlx|xh{vp}twvw|m~zvl{u|pn|yorx{zzxyt|~~swzxzyx}vnzvsv}z}|}|Sj}}z~skn{|mihw|mz}}yu}rkx~yz||n~yvumuf}}{{n{|y|w~Xr]|u{|v4vh{~v{|z{txuoms(iuFmw{k|{|wpzvT_~{wetzonyyntm~{uk}}z}v{{m}wpax~jn|pz}zupg}t}}y{{j{{quwxr~zz~~cw~~pppz|}u~wtpztnmj}x}m||k|{mz~x~y|yw~t|tuvz}qu{wzo{~~|zw~sx}woz{rv}{xwqvz~ktu}wwzp~v|yz|z~v|vw~xyw|}}rtu^|~x]pk}ku~w}mz|zkwr{zgws~}v~fwzs|~~}wz{q|wzzz}w{x^}xosp|s}~xtuowyshi||m~nymkvrzs~ty{wy{r{rs~y{}ps{v|x|y~|~~~ptx|}~u~|p}zx{{}|u~~u}uz|u}~|}}{}|p~}|p{u{u}||{|~~}vxz|ttys~x{{yxtu}~Vrwt_~|nz}yt}ygyw|sx}zupz|nq}}wv}{~wytty~~xx|}}}}|zw~u}w}pvlyvhvyy}~vqzwlz}z~|y~{u|w~|t~k~zn{vvyy|}u~zr}}ru|symzqzxv}z{uyl{||{wv|xvytus}k}szpxwu}zxz}|{xvwp}|}z{|}v}}zz~|}~x~u{z}u|vwyz|~}~sn|r{|}xys{s}zzws{zy~stxs{|z}}xau~vvlsxrrb|wws|ssx}|ueyxuslumy`hswzl~r\|{sp~o}{vxvg~{znxxowspkv{ytvz~|}lw|osx{}or}rmku`vpkzsk|sxxtynyyfh}y{uqt{jyzyy{vjzyx_x}f{tokvxwo~qkprrwwvs~~xruvw~}sxvk}{y}sv~vwutv~x{x~mjqhos{ox|rsxxz~||yyuq}|u|wy{yst}}{}zv{uyqp}}~~~zv~qrt~x|zp~ls~xuzvwql{h~}zs~|}n}vus~v{}}z}|}{usu{pvu~~~vwx}}{xyz~}yv}uyx~jw}|c~yuwy|pzdzp~{z~uys~vvjvwwvqtec|uywpt{v{h||rtzm|xyty|qysw}||vaj|vvsz|{xysrryuxqqzro~ykx}v|vx|w~vv|v|zst{xsvozv~|u~{~wq{r|}|xy{xpvztt{uszw}vy~~v|txw||p{xwwz}zzqy|}xvu}}~{tsutuu~~svvjv{zv|y{{~{z|}{x~z}}}zoxu~rrm||{~sx}}oz~tm|j|m|}l|~y{}y|zt{|{|wyy|}|suz}szzy{}yw}u~}r}}z~y~xgp{zy~}tvw~wryzpws}}tw|vz|y~||ou{~wy{|z}}~p|oozx{ur{zvcxuyx{xzxvv~{}}w{x}}zvux|ywtxy~}~{|rz~t~|}sx}yy||~xszzzt|yx|{{|y~szrqzrnwzr|x~n}{yso{}|q~v{yw|zvzw{vxzunsr|vv}~~u}urjzy{}v~xy{q{vsx~{|}n}zxv}|z~~wz~sw{vt}r{|}z~~{~y{~w|~{wxw}}r~|}y~{}yxxz{u}{}{y|{|}~|wysx}zwvw}}w{|tvztp{tr|tzvx~qsyr~}p~t|x~w{wyqr{usk|xt~sylzts{u}yy|zyo}}x{{|k}}{vw~{z{~tu||xw{yz|{|x}{xu~{zw~y~}}|}|~|z{t{xy~x}~yyzxr}xy~{y_~su}lz|~w{|vv~}xtq}x{mv~u}zzzzlnu}x{~w|}}}|q|z|~~w~|j|~z|}nrz}l{t{u~v{v~}jqyx}ypnvu~|{|vvr|~j~~{v~|uv{z}zm~}}|}sw}t}}|{}z}oz{pvrno}l}{oz}}v{wqrls~|ki{|zzxvqy{~u}nunl~wyy}x}x||yyzy|z|wtxsz{}}|w}u~o{{|qx||}~{wzqtz|vupusvxtxtw}sx|{|ry{|fr}|}y~uzxr~mzs~ws~}z{rywxuywyx}u~yyz}wvdys|stujov~~}oysm{uu~zmzww|pu}rvx{xuz~ur{{pv{z|~s}}|~v}|p{{szuzdzx~y{y|{tzsuzu~yx}||}{~{zwwzuty~~{}}~y~~}svu~}|^tyzp}sq{tz~}{xxpumfkzsyn|}i}n|{v|{z~||{w}wy|xqw~y}{{i{|~vpy}z}}w}p|p{|}ul~v~~xwuzo}~twtt}{{{r|v~wopy}xr~|}t~~s{||~|{}}|wxvz{|x{vyxxu{{}z{|n{|vh||{uyr{~~v~}z{~~iu}xx|vxxw}v{{v{|l{~}~}{rxss{}|ys}|qxwxukkqwnv|nm}~rz|{{yy~y{}|y}|vxxxznvwo{z~zzqxr|yx|}rw|wz{~t|~txyt}||}~z}~{xztty|~{}{c~}|t~}rpw~ts{sylqx|v~lv{yxv|vsvu{z~|t{y~}|zoy~uwzvnwworyusq}w{v{syvxz~t|yn|s}uustz{{~~t}}}zrvnu{x~yzyr~|~zw}w}yv|y||x|{}~xxy}yrwqxyxzqx~{y|ozllu||ymsy{ux}{v}{tsoj|j|dr~gzaxr{qu{}oxxu{r~v}q}~ywozyzzxnxsl}ugyrt}}{}yvxv{zq{}tqrowyu~lvyuzxzuzxwjtu|Uuw{rzwn}vw|}~yuz~y||}s}~nvpt~y~xul~snrv}ztz{{}|myw|iz}rysbuztr~t}vo{u{uxszyyx{wq|w|p|tx|rwrypq||~szz{w|r~{{wz~rw~r{~yywp{~~zw}vw~~xu|xz~zs|~xt|{|~~v{}~wyxpjyqttv}s|pzlw{~u{wv}su~{zluz{pm~wsvn{{yz|yexw{~s{tw|xouq}ttp~{w~x}prxw|u~}v~w}{wwv|}u|t|}}|~vy{}{uzx}|~|}rz}|{zvtz{xz}|~wgu}~}~muoj~~ot{xvquwpx~~y~x|utgyzxo|zzw~xvqpvs{{}~}xyyy}llu|yzp|qoz}q}zv|xv}{~{}tz~xnm|w~lh{s|zox|ysvo|z|wzz~z~|{r{||r}x{}~xt{}v{~q|nzvx|{|v|y|xvxh~yp|oo~o|z{yyowtki~{wl{xkzp~ryy|wx{x}~t{r|}}qs~zx{|~~~wzu|y}xwlvwxx|p{sy|yuu|}~nz}tw}vz{~smln~x|xr|~y|yv~}rs}~m|nm|}tjr{ix|i~wx|lo|z~t}n~p{vyl|oxw|tz||nxn{wn|~|xtvt}n|~~|vs}ox~}nrusp~~rsu}yp}wzw{y~vv{}Zyopp~{q||vrvo}sj}i~x|m}u|lrxmzv|}t~yzwt|t{rt~z{zrs{zyy{{}z~{{u}zw}v|~~|~s|ww}~y{yy{~x{nzpopux}zzwwortrk|i|tjzzl|z|t}tt}{{yp||{zrsw}{rt~|x~{~n}{zwuzoxrymwtwzs{mw|{~~}m~pp~s~|zu~{oy}{{sj|i~zzl~y~n{xm{~u|}w}~z{|yt}uq~{}|mv}~~z{~xw~vl}vz}}q{z~||ppt{{u|zyuzy|}|}|z}~~}~wt~lv}=xquc~z~|~}}htz|t~ys{s~yn}q|z~}s}~t}|{y~|yy~{}~|zzyyt}~{~t~~zbx|~sywxn{svf{}xpz|}x~tu|vrx~~{uvssh|}xy}x~|zr~zrw|tyu{~|wwrwz|w{v~~{zz}y}~{}y~vyvs~r}~gxxzvyzrm|wx~a~{zv~txz|zw|}x{ttwytr}|{s~u}{}ucnr|s}|}|~outxzv}p|}rvx{qyt{}~{|}vz~~}~y{|~~qz|w~ytx~{uv~tzxp{{pzs~q~~z}~{|}q}}}v{{~x{|~~vy|w~|~t{z`||tpop{~{|uywu{p{y~tkjyl}xy{n}}lxyx{tzuzwszv|qz{uxprvkx}||y~}l}q~z|{}w|zwwqwuuZv{o|Y`|xrs|}vx`dqroVkot}xxr~ifu}td{rwty|zk~yt}cyy~opvzyzk{{y|}ohkt{}rsxhw|uz}u|gup|{utrpxp}p}utzwyo{~|j{{mq}wvx|swzto~zx{huu{uzsrux|~syw{t|uqu|n}~gtnxusv{rvs~owtzfxv|ztxmw}u|{rvy{y{ixxnz||~|u|tu~rvk~zw}u}|~tzz~wz||y{xxqmu}~y{z|}{vy{wx~}nz~xkizquz}l}{o|z}}x{}{vxwz|{syt{yyz}ztz|~{w}|tz|~~~yuy||zz{swv~wyvz}{~}uxwg|wqqpw{z|~vxtspqxtlzirl~yzowxs{vy}~~uy~wy}u|rq~os~xx|}x~}}}y|sy}}|w{||nyq||zlpi~|yur~y{zxomu|zkuts~r|{x|p|h~~{nt|{y}vo}v~vz~y}iyx~{~}s|u{u||}vwsp{\x|p}w|t{vs{~x{|yz~}zx}v}~iy~zn~{|{{}|uu{y~t}ruz{x~{zy||ww~|}y{vuv}vy~{y~y}y~~zt}}{~zzt|}tyw{|~{|wz~}nyz~n~roluy{~~o~{tn}jztk||n~|uz{}x~~z}v|tvwrut}w{w|{|u}twy}vz~nwz||~oz{}rwqu~{x{~x~|}|~z~~}zzww{tsx}|z|zTqivz~tz}|zzR|t|v||xn|npQrsu{}x~dzxtt|uqv}s~ttz}y~juowvy{qrywz}nzvqrmk~vlov|vkwiy~lwxt~{qxo}vyo~{itw~v~^oxt}~|opv~qvt{w{x|pzuh||~v{|{u{x|`|opn}~~v|}xuwo|rxskyhzy{l|~{l}s}qyu~yuzw{}|q|ruwrvpry~|x|x~||x|~~y|s|vy~wuo~tz|rv{~}{uF\}xxj}|lx{{u|wsl\n|w}}pz{zqwuux}qcr{~{x{uxsgZ}xizuuexjnzpn~}~wy~}qYt{o}|oju~y}{||x|{rs|{{}yq{s~|yy|p}{w}{||z{|~ttxv~~~~|z}}wxvzovz|xuzs~|j{z}|}y}{ttj{uyy~p}|mxn~t|d{qmv~t}zm}s~|uuw{n||q{s~wy}}w{tx~|y~}t|nz~yyzv{p{put|}wz{vu{x~~xzwz|zq|}yr~{qmtpx|{zrz||||}}vtpvs~|p|ox|gi~uxkx}}}~~p~u}~u}o~|x{xy}}z{yxzz}}yxqxxs}y{}r|wu}z||~|vx{{~z}}|{yvmx}xqs~s}y~~ztz||z|~tz~tyz}}}~~|~s{}{z~||{ttxx}{~z~y{vy{rztwyy~~s~z|~pu{pqo{v}x|uwxps~{{z}}z{|}~wu||tqx{t|qymvmssx{p}}tsyrwvz~x|v{ys}wxv~z{ykw{r{xpzwnu}|}{||ysptz{y{rzmw~}~zz}{|x}r|zz}~ysb{dnvpmws{wyr}qpx~rwjqsm{pzxp|v]{w{{rxzwpzs}t{|xz~mlswvw{}u||{xv~r}sxlv~uzzz}~v}xxt|vzt{}|xuz}sxwwvt|zqwr}x}oxzs|vwyxtwxw{xt]ywzq{xzwwv|mu|wxsj}zwz}uxz{~|}ssx}tu|qpwyuy}y{{v~z~yr~{}y~}xy~t}s{z~~ss|zz|tv}y{{v}|zutvpm}xx|}x~gzx{|]|u}t{f|ksqwvf|uvtf~|t[|vpsx|rx|oxu~lz{|{|uz{{uy~|vyz~}twtz}}x~||w}ux}us}ztw|~}y~{x~}}|xy~fxy~~|yo|qo|v~~yq}oz|tkl~uyn{z|pq~svoz|}xwr}vu}||x}luzt||zxz~wz{r|yw}usyy~n~b{ruz{xzc}őrq~mytzu~z~~~{{v|y}o{~|~v}|~v~rn~mazi|wsy~ywquywu~rpp|xqww~wieky{nvxwu~{y{|xurg{}~zvszfs}yz{xmwnt~}{x~~t~ouy|y~{~|zl}yyppbynv~vlm{zv{~}|~|}{{{wx{|r}o{sy~xxwxyvx{lzrzq~x{yxt}vxfzx|wsuub~ezywol~y|e{ytqzn{y}xpy}r|vry~x|ig}tt~nw}{~~yzubtuuvnppo~zesuvxtvxtytwxt}zsryyttrxs|{g|{}z~uo{s{{|xxvuqvywo|xupzwxux~uzuvwwupyws{z{zydvz{|vvt|{|z{osspst~}ttu}osy{uzzxz}vu~|||xzzyxxwzuuqrqxr~y|{outlzk~|m}{|~l{}|{x{~wxu~zu|z{wsv~~suywz}yu{~~t~~{vy}x|qyzvrxtwpwy|y{o{|xwx~ruypq~}z~y{|xhz}~~v}v{{{zrzvwvx~oxtuirwpux~zywysuwwu}v|w}zx|x|y|y}}}up~~nyqxz{~{~v{s{zx||{{vtuy{}ty~zv~qpzz{}|y|~{w~wqz|}}t||q~|~~wwul}~pxtyy}zwokswym|so~}uix~v}w{v|{zoztv|wysr{z}zv|yu{}x}{us|yw{~~w|t|j}}o}x~y~vu{l|~n}pvp}~v~zuzoy{{unkuk}|m|ysx~|{|}|x{}wvyy~zou~y~x}~s}sy{xr~m|~x~|{x|jyz~qtr~{}wx|p~}v|ul~yk~~xm|{m{~y~}zxzyw~~t{ty~}|~qt|}}zw~s}w|u{}~~~w~zp}z~y~suxk~{{v}i~`}bky?wouot~wcdvxyx||kv~o}}}}}sz}wdtv}|}~wvhoxoxuoq{|z_{x{kssyuu~~|z~||~z~}{vty~~~uzp{z|~~y{{~ti}v}u~xt~|xv{u{}}{nx{|vu|ryww{sn}m|xx}|}v~}twmzutvyy~{{~~wy{zwe}{}rxlssszyv}{w~xwzrtztvy{xu}}u~{vz}~oyvnxy~xx|~xr}~||~{|~~}|s}w~m{w|zxz|wy|~vwzxyx~~~wz}xtvs}{wx{yu}}wyqyq}o{|x|zqz}}l|y}y|wxliv}|~{{euvx~xx~}o|}ẇokvx|{hg|vtx}xw~s~}~p{ihkvjvzx}plw~{~gytxu|~|vqzw|x{zy{~xp|||}w|u|qy~~u~us{ryku{p{t}v}t|yv{{~s|||xqiz{|z{|}o~|~o}iwr}}|xw{n~wjxyysy}|{pyx~|}xz|~o}zyfxoy}u~w|ir}vy}uu}r~}w{nex}|{}{wxxp{v}~w}ty{v{uywvx|w|}vxn~p{y}vyx~}o|{{yxw|}r}|~~{yt|zz}|{yty~~o{x|{{~sv}~n~uwxzzrnvxu}rv{xysg}ttt{}wzyz|w}uzu{ztz}{vwnq|x||~~zprmxlpk}ym{wr~y|{vv|wt|z{}pzv{t}{~uwzk}wws{t|}wuo}||z{{r}w}vyvxxyovntw|}{|x{tzt~vr{z{yvwz|z|vthtzy{|wn{w|~|r{woz{oBv}nu|ry|{|xm^i{{zv~|zy{}qvjxsrsso|vouvw~|urx}~vxnfwxxpv|x~yzcwsy^wws~txsim{m{|{lz}{x|}zr{iffm~{t{wuspoz~qo|x{~}ut}~o|zwtqsy~{yxz~v{wxqxwxwtv|~}~{m~u}s{{nnu}zr~|{iirtp~e}r~zl|wvnww~ktwm{~{v{s|~tzix{zyux{rzziv~w}}{tpt{zz}wzs}w||z}iwz|t{wp{~py}{zt~r{tv{v~svvxqt||yu{wsqzzyysty|oy{|w|}~ty|tzu|}zxyiq}yy~t}y|w~ttryttxsr}zvzwu|w|{|zx|}x|}xvw~{~y{|vr{~}ux{t|}{ury|v|wxy|zyx~{uzu}{t}~z~w|~x}xyvr}|s|y~z~w{~z~}wy|xwt}~txz~{}~z|z|~}{L~xw]~szlyt{}mjzzylt{{|y{~~}}}{|||b~zzqzpritot}oyu|x|w}vpk^Zyrpiqqwpwwwxlqcmorwumq~lxlv||}}wxrzotx}umqytpk}tkzzqynnr|}~nzxs|qxlty~s|}tvyzz}pt{~}sovvwk~myp~z}oyw~v{{}z}|r~s{xp|}}|}yw{x|y{y}qrz~||w|t|w~z|z{}styz{zw~~u|{tyj~|u~puon|z}|yw}p|vvtm}jnv|l||wnxx~z~~x{{y}{u{u{~trt{x~y~~{~~zs~t~uxwqvy{v|~wvyg~~|up}nq~}~yy}{|s~o~y|skzjzj~yn|vzz{s}|xwt}s{sl{vqp{}|~v|u~pz{z~x|ox{~x}~~}{vvwqz}|~pno{xzwzz|vw{oxwysixh~t}zj{x}ow}v|x}{~~yz}}r~us|pu|~o}z~o}|}{vyrvtz|qp{|szzz}{{}~~ty|}g{zq|nq}t{~qyw~uo}sk{iwk|zm~}{v~utssvwu|q}ql}|zxqx~x}{}x{~~|zyuxw{zrw~|p|zx~~}c}f~n|z{z|}}zmjLypyt{z}u{{~~yx|v{nwqwnt~v|~lz|kyrvj}}~ynymno~}}|}uq}w{izzsj|}{cxul~y|cuy~vnq}q{xsryx|~t|z{ots{w~~vs}zl~um{wmysp}~{uusuusq{u|~vsz}wpr{zns{~jquwqzt~v}u}{|~ut~||s|{ks|~|}xuoz}nzvt~|ovw~|||zu{rswx|wr}}jv{tyuy{~onz~}smw{{}~w~}~zslroz~~y~y{yxy}stxytxv~|vye]n~gzyl{{~xn{~qwhrj|z}ttr{s|gny}z{x~up{ozmz}}|msziru|~v|}w|qnz}~}}}{~u|{{v{{|x~z}|z~||y||}u|}{{{|~}z}wz}ys}zy~{z|l}yus|u}mz~zysx~y{v{{w}}~~xt|~j~q|zc}~}}}y~q~{bwvrws|wwvr}t}{unvv~}{{x~{|y}|wr|s}}zzx|y}}q~{wy{zz}w|~rt{{|wvz}cx}~`wow~m}}{j}~rzv{ymzi{~rzzw}~jpubtxn{y~|ux}vw{vu^}y{zwoxk}~|os~{mt}{v}{}}u}~y{~}sq{vzvt~oo|wvt~z{syyyu{ztp}mvm}xx}y~{x{o{pudu}|tss|~kxz|s~||~y~~tv~{yz{}{z~z|}||~v~r{}}yv~~|~{}||{~|||{mtzxir~v|z}w|~x}|y~vs}py}r}wy~p~{~xx}zy|x~o}uq}uoxr~tq}|y}tvz{}r~~y{y{~f|}|v{~~}~}uvqro{~qutpmzu}{yp{{}vyt}vvw|r~~|~}}~y|u~yxv}{mozyy}{{tvtyz{qy|}yw~y}|}~zrwzxvzl~puw{h|qu|~}v|}~v|yxwv|y}~qyozy{w}}rxvxvw}{u|~z|~v}wzvv}vuv|}}s{yv|}zivtz}p~{yrz|~s{zr||}|yt||xyq}||~|y{yvy|~{|yzrr{yxk{}mxtxvwzxmxz}}~{}{z|y~}zx~~~}~|z|zt~~~|y|}~}|v{lw{y}xr|}wy}y|}~szuo|yuys~k~~|v~ww{{}|yv~z}|puvy{~zzy{}~z|zxyyz|\zym}nu}{{tz|{{t}|}{r{}~~txz{}swy{||t~z}|r}xr|~|~zvw~nmw}{wvyoy}o~~~x~ynsk{z}}{zzz~{zz}|~~z||~r~|z~~ywyy|}w~v|{{zqy|~~zn}uy~zzxw~v{~|~v}t||usrm~zy}|~x{y~}{z|x~z|{{}|~z|~z~}~~~{}}y~v{~~{}|{x}}{~w|{|}vz|y}mxw~l{{}wy~~x|zy~rvx}z~z~zy{{p|{y}~}}s||~|}||zv{v{}xt{~zqxyysvxz|w~}}z~}}~~y~w{yux}}zw}q{wyy}t~xz~{}{y||xrry}ez~~{~xyd~yv|ys~{~|ytr||{~{wzzxw|x~y}{}~zd{u{}{x|y~|u~vz{~zzts||{uxwzn~vs{qm~wx~~z||}{|{x{w~}{}}|~{{|}~zy~~|{~}r}~wszxy}qwy~wz{|x|{~w}u}xvf|x{}sy|w|}wf~zgyY{z}vlwwx~|xjrmo}z~~o}wvzs|~pk}~{|~hlw}ycz{uymn}sznxwuzw{sr}f|}{o}w}m}x}~~zsyno~thy|yosylx~}yv{w|wvyz{x~}}~|~{rx}|~w|}{{}~wy}|~ppswr{}|myu}wk}}y|wz}}syq|u~~{ztyq~{~~|}}~y~y~v~|y~y{t}}~}{l|r~zyujqt{~~}v|}z~}|~pmyt~|~w{}}tz~|vw|~~m}t~{m|}r|r{z~y{~}{~z~x}y}}yzyo|{u}|}yx~{zwo}z|l{{~~~{vyw|yz{|ux~vxy{}|~~r}{~|}~}ww|sz}{tpo~{ky|zv}~v}vvzzx}}~u}|{{}yx}{zpy{zvt{}}z}|ws|y|l}qvhq{u|t|~z~{}~qny~}|lrvgq{t|t|~|}w{qny}w}}}ous|wjs{~w}~z{~}x}|zz{{tqz~z|~{lrzxhqyu|~t|~{~~zy|qn{z}y}~~ltyyhqzu{y}~vz{{~}x}}}q{nyzxstylyz{{x~~y~}{}{}xzyv}~|w{|~{}}{~}zqtvw|}iz{{l{}z~|yvw}wi|{oq{y}r|n|v~qy~|{~~|y||~tp|umz~t|{t~w|y~wtsnwpy}vpz}z|u|||~~uy~}ul~gox}yv}vo|pnx}}{|}~zx}w}|tx~{}}w}}{~~~}~|y}~r{urrrmz{}~w{v}y~}}~}||~z|~z|}xz~yu~~{sqw~xmz|~wz~}||w~|w{~|}}~|x~~xv}~z|xqy|u~}z|z~}|ytbd~{{~}~z{y{||tw}}~{zv~l{}u~}|t~~~~~vy{}}|x}y~yzu}v~~}}|pu~|mu~w}w~|~wx|}s{try{uv}}zythow}|ytyr~}urz{rktzsupw|kx}|~sy}oyshtu|x}|}~ru|ytz}~~{|}z}z{y}mqt}~ny~{|z~v}{cuzyxswr~vxwvqyz}z}~|}~||}{~{oz~}{{sy~xw~{tny{~wz}{v|}wx{}{}lwuwfyhqu|yv{~{}uyz|~q|~nywy~y|y{ozzzzy~u~z|}yvx~}~v~|~z~~yi}|r{u~u~}qz~yu}tg{|{}}x}yt}|~}{||~y}|qywxzzsxyrz}~|{v~y}z|~{xzy}t{z|x|~|rx}~yymux~~zy~}~~tv~us~z~{lqzkz~z{wx~|~yzwy~zz}{}yu~z|xzv{|}~}||{{v}zx~~w|||}zxtzv~myn||~{vyz{}yxu~x{|}}|~xp{v|v~}ys}~{|}y}t~wx|qqw|}~u|{o{zu~z}~}}x~w||v}|~~~lt{wiqu{w{}}z|qnx}y}}~m}vuztn~x}}|}y}w{}xxv~~}t}~y{~}}}rtz~|}{{|{ztqsn~wwt|v}w~y}vt}~u|v~~}}zy~wz}ur{owyyp|~}~~zy{uzwz|~}~|~}zy}~z~rz~nxw~~usyd|z}{z|zwr{vr|~uz~zzyszwxp|z}|~|y}ws|z|jvx~w~rkz{x~|z{zyl|z}w|{{z{tumu~oy}ir~v|~}v|}u~{}{y{rs|qz}~y~lrucuhqu{vv||~}~qny~}q}ypw~poy{~}{q~skyy|v~x}~l~w~|~|{t~~~u{v}x|~znwoz}~~r|~||xs}|z~z}~psvz~u{t~{z|{vxj~wy}}v~z}o~||nsw{k{sv|}{zt}~}xq~~~rpz}z|~y{}vv~s~{~vzw}{yz{|p|vvs}t|}zpxxs{w~xuwxxq}fwx||}~~}znxxvwozu~vwz{|my~{|xvvv{|y~u}vp}s~w~}w}xltwgq|t{~zu|~zvx}qny}|zqs~m{~yz{}~y~{}y}}{o{~|}uy~{y}s|w}~~ssp|}t}vm}xr}}~|z|~t{~u{}}{s~}z|yy}py|xy|}}zy}|vztxlptx{s|xv|w~u}w~q{||vstl~y}v}{y~}yw}}}x|{x}}~}~|w}}}}ouw{qyjr}}w}yv}~lx}tuttry{rmv~l{v{yq{y}vpx{~|~w~{qrxt~|~v|~{|{}~}s}{|~~~}qukpz{w|vbxkuw~{~t~z~vz{}tzvr{|~|ts|s~x|}{~|{{q~~xu}~~{}|||yz~{||~{|}k{uzv|w{||z{wy{v~u~~}|{|w}{yjt}zpwu}~rnv~}~|w{|yz~y{~{zuy{{|z~~x||}{}nny~jxzttn~~}yyw{}}y}|~||}|pw}xw~}r~|z|x{v|~}~}}}|v~{l{r|{j~qt~{uv{||}}~}~pmz|k|wuox}v}}pz|{mz_tyyyf{qwr{w~vps~~|tzm{|x~}||zm~s~`{qvt{psdr{r~p{pzvw{u}zyy{z}~z{q}|s}uvus{cyr}{~|hyy{z|~{y{z~p}|{yw}|{w|yz|zzu|~s~{{{w||iu|}~uwv}{}{zz~r~rx~~xz}z}~~}~~|wslfun~ws~qqttlzx{w{tr}|qeyygyanx}~~z~zv~wwnmxe|z|m}q{vxxnx|X^~y}zpmn~|g\h}s}xvym|yk~r~Wurgvzv|pytzg^qhcto{~{u}~tewq{}xqzyz}uyzy}|~m~ywuv}}{|yx}|wz|~|~z~vyw}|}o{x{{zy}q|{|w|~x}~~|yy}|y|~~~|h|pry{tkuzvvwuyyq|srnus|zq~}nz{|~~}|{||nrs}}{xot}m~t}v|vwz~{~x}~ws{}}{{~s}q|~}vwzqr}ql}x}}xzw~{~t{v||}|}uou|yww}}r|wx|~}~{lr~vhqu{vv||{~|}~}q~nzyz|}srpey`jyukw{~zsg|ropl{{{{tr~swjitt~~zynonzvw{y~zpuvzv~|xyto]~upwo}ty|qyqy}~|yy~}}{}}y{~~~{{{y|uzmz~{{{u}}z{}|~}{rz}|}zzwx}{|j}z~{yvw|u}~~|~y}x}~rx~{}yy~}}w}wx|wz|~x~rtnoxwy~}xo~yw}zwsuru{o~{z~~~tv~u}wqmby{yrutql~w~|}y{}x}{{~}{v|yy}}~y}}{~{}|~}yyqnyxyzu{r|w}y{us|}}~|~}|~sx~|z~xy|izzw|zuww|~u{yzz||xz|~~mvxc~}}}{zwv{xg~|wx|su|yts|sxy|z{yz|y{~z{{ynw}tw{{}w{xzuv|qr~z{t{sxp{{yyu|}lq}xgpu|wu||qzu~qnw}Qdyx{}rzv~nvxy|k}yqpvq|~iz~}{oxn]vxk~mw}vyyÉiuyuwzxv~lwryhy{~~}|vqkn~o|ozy~x~lx}}vn{ynwx{}~k~s~}ov{|~yy|}}|}wwr|~z}syps}utz{~v|||~ym]xkqvsu{atxp}{}o~q|x{{x{|s{wq~xu}z}t{uy}{z~t|v}t||v{xv{tqx}twvy}{{{zr}yw~{~|wuzzrtz~l|q|zsw|~~xtxt~{~{rv}}xv{||oi}|y~n~}s}z~wmy{}v~||}uq{~||{ygvm}puryxy{}}|~oodwv|kvqv{k~vjzlx}rztpx}vsp}z{y~|v~}|ypv~}xq{l{yr{~{wtylwzyxvhz}y}xy~m}}sshr}u|w}w{{q{r||z}w|}|n{~~{uxxy{v|t~ww~|~~||xumz|sqww{}w{}}z{xdz|z||ztqzsukf}xw~zxu{y||ryw{y|}z~tx|y|v}xu{yyyzyrwzvzxx|}t~y}yv|}{v~~pmx}t{v|wNwuv~x}wyx{x}}}k|prywnz}{t~{xwqztow~|}|~mytvq||vtuz|vx~{x}uxwzyxn}{ft}~p|}}{~~kz~wd}}qzzr{u~|r}xzuu}}~mqwuw|xws}}~lqw}{sz|}yozl~~xu{{~~}yvwwy|~}vv}zz~y}{xvyko~}|~xz~~|wx||~x}yqu{z~~x|~}~zn~uz}t|~{~~mz{}{}{{{v|}us}{}~~xwy}}}}~|x|mp~z}{x~{{~{|~w~~{uz~ms|~\vfqw}v|}~t~}pz|p|q~{~ry~~{vyt{po}y}oyv|~|wsyy{zyr}~|~w}~}t}|}v{|o}z{y}zkozyqyy~|yo}zz}{r}~yzr~|{~}zz~}zvz~}~mp}twmwz|vxp|w|z~zuwtxv~}w|yw~z}utiy{vzv|}~}pqjv}}zw~w|}}r}{x~zu{|w|zzz||y|xwwpx~|koxvV~{|}|yxtu_|~~vtx~t~|k}ykz}}{w|~vyqtmssyo|~zzuvwtvv~_{~u{}z~r~||}pxtmo|y}}{zys|v|saurw{vws~yv~sv~|r}t}|~plzr}|iqu~|{v||}|~}|qoz~wy{lqzgq~{u{~~u|}{y|~}~qnyyz{zn}t{|k{s|v|}||v|~~y}}|rp{{|~wo~oozws{~}vzxuvvt}s|sqmqz{zwzkygmqv|v~xmz|~}~lvx|yyiqu{{{v~{~}{wy~|qny||lsyhqu||{t|~t|zv~~zqny}wtrpm~ww{{w{z{uu|}~w|~{~|wz|}w}|~|}}~}ry}zs~~|}u~{yo{vt}~}{|~|~zyy{yp~~wy}xtq~zy~{ztw}v|}|}ujzx|}wwsn~r|sxz|xxu|xahx~~|kxz}tyxo}u}yujsustva~~|twjpw}z{v~mwky~}~z}ty~{}|w{{{{|y|}qqw}w}~|}}w~uy}||pv}|}}}u}u}rvzk}w||}yz}|y~~w{u{z~y}}w~vzw{~y~|~~~~}|w|~z~mqzgq{yu|||}s|~w{p|~{v}~tsuroy}{zms}wiru||xu|~u|~|~~}z~r~ny|~lv~soxhqu|v||y{}q}ny}}~~xtl}ty~~~yhqu|}uv|}yv{y}{~r~oy|y~~}|{m~w|}t~}|}}}{}ox~|{|ywzu{pxzm~|uy}~~rx~|W~~}z~yzzl}{v~||y}~|}luymwhq~t{v{}}}y{{qnxzr{|~zrx{zxv~v{vuuy|ix~x{}xx~~o~~xyx{vy{}}{puyw~xy}}}~q|}|~xpwwl|z|}}{p{~{w}}su{}{{w}}~{{y~|~{~p}|~~~}x~~z|{}xnz|xuvv~z}y~|rqhl~|{y}~zl{}z|s~~|v~s}z|zsz|u~tzz~uwx~r~z{zzu}{|z{zxt~{~}||tlw~~n}zw}~wx~x|wt{{{x~~ys~}wp{z{}zx~y|~xp}|{}v{{}{|}s{|v}uwnu~{}~z~zywjszhr{{{t}~xv~u}n|vx}z~~|~rw}~z|qx~~uz~~ls|~wiq~t{~u{}x}y~}pmzyz|}p}z|x|~y}s~~~x{w|xyz{q|x~w}{|}k~vs{wy{}u}w{|~xt~z|}v{|~}ys|z{y||quqv}z~p{y~v}}|~p~}z{yjy|x~{}o}x}h~w}k}xz||k{rsw|y|t|y}}}w}y{xzzt}vf{g]w}~}z~mutizuz~ywsvzx{z{{pttqsxqwp|hV|uqz{sy~n~w}}xxqvpgyzz}w~h~{rxp}q~wyvvxn|}x~vzl~yx}w||~~umy|wsx}|}sxxvmyz}o~~~m{w}ryz|~q{|z~w~yyz}|}~yxy{~}z}~~}}ppky{pqsz}zw~|~wzr|~t{|lu{~uw{y|yyv|{usm{|{zcw~}~~{~z~|{|~lr~vzltfp}u|t|~}x{{~~qnx{|{}~w}|lskvfpxu||}v}t|~v|}}}yur~nw{t|xy{~mt{hqu~|~u{}sy{~~yr|ox~~{lz~~l|~}tyx~|u{z{~|z|w~t}z~{t~q{rz~~y{||}{~}y{~||}z}o}|pz}}{yv{}~rkqz{t~}yv}y|y|{|}w}z~|q{t{w~{oyup}~z|yzz|z||uz{t`xx~t~|vqnuozl|utywx{|yzr}{yw~y~{wxzy{uz|zwr}yw|~|z}~yy{mrx}~kzz}yyyy{}}~wx~tyt{p|{~|w|~}~xz~s}}tuy}{w{{yx}~lsxxhqyt{yzu{~}{z|~pn~zt~z}ltwhqu|~v{~}z{~~}qnxxzyzwv|o~v}o{px|{y|zz~z|zpy~tnz~y~xv{~|zydo}o}y|nx~trx~uxy~~zz}{||wy{pzz~~uwxw}~{{{{h{}~|ut}|uqt|~onvzz|yz|{xp|y|}}}tx~q~~x}k~woxw}{r{x~rpy|v~zv{v~}y|~|zy~}x|rv}~~}{|~~y~p~~wsjy}uwsxz~}pstzz{ux}|wv}u|x|z~}u~{}|xoy{|xt{n~vmz{o}|||x{|qy{vn{|v}}~~{}xt}yty~{zz~}z}r{|{~|vz{|~}~~z}u~}{ntz}iru|~v|z~p{~y}rpyt~v}~}ls}t{zry}w}y~uq}w|z}|mrws}|t~z{z{j|x|xsxx~u|x}~v}}}}{x{|~}}z}u~xv{}~|~~svrslwz~y}w{y|}{~{zvz~}|}~{~|r||rxroxzxzovtzyv}r~x|zv~}{~}zz~}w}xqz}~}puvk{xw}z}~~z}{yv~|}~t}y{w|{}yx|yxx|qszmyz}|xy|{}yx{xny{~~{|y|zs~}|}nz~|~mz}xz|vz}~yxmw~xqwz~w|}|{zxxqy~wdsp|~~vv~~{~~}zzy~mn|xgqyu|ys|~~|yp{xroy|}}{}~~}{}z~w~y~}w|}vx~}m{~znx{w|r~}r~}~w{u{|xxxpv~u}s}}}|u^~zcu~utvumzt|||}~}wvxxwy|}xv}xw|tz}z~}wv{v|rxyy}|xmwzzzp~~{{{~rj|~{}~r|~t}{||{wy|}~}z}z~}mzv~w{y}{zp{vhzur{{s~zuz~uuvvu}vvz~}qo}~{~yyzy|uy{w|zxqu|ru|u}~wwqxmlx|{{|}x}{v{}{s}{{}{|~}wyxzx~~~~}zzx}}|wszpjzpznt~|t|vyx}xrvq~x}s}~z}|z|y{{{||yzrt{~pgzv{m}ts}vwnn{}o~t~~r|vs|{x}xq|t{~x{zzsx|}xx}~}~vu|xsw}{{vxutzm|yws|ywz}~~y}|{xt{{}}v~|x|wuz{twwl|wz{zu{|}x|yw}~}{}{{t}}w}{~}~u||yy{}~zz~{z|~v|{~z{wz||qvs~z{wuxnxxv|xzi{~qxz}vuvxwz|x{~s{|~|z~pxy}y~ty}|y{yz|{i{vu}~{~lsswgqzt|~t|~v~z~qnx}{~}w}~uz}}{~|}}q{~z~~{{ltzwgqzu|vu{~oywy~zq~nxuzps~m{~r{{|vz|y{xzy{~}ywxzzx~|~{xzx|}|~|wy}uz}|{}~y|~~y|u|~lt~ziqu~{|~v{z|zz}wqnzy}{wl}}|z}~pnry~z|zup~m|~{}v}{z~}zxy{x|}xwrt~qlx~x~~|}xyw{|~{|{~zww~||{z}|}{~~}~x|vzvue~xb}X\o~z}o{}wzy~v}mZgt~xsyw~|i_}js^o}|wkvzmspiq{u~{{luvyiq|u|w{}|}z}qnw}x|yxus{}}p|y|~z{uvx}zz}~|s{z~~{u~~v|}}z|t~}utyxnu{y{|r}}o}v{w{}s{~ww{y~}~zv|lq~yhqu|uzu|}{{}||vx~r~oy~t{}|}luwyiq~u{|~v{}|}zwqn|y}}~{|~pz~r}|}~v||sv}yx}vzwzlzzvty}||u~~u{x|~w}s{{{y}~z|t~~qjtw{vqszwozx}~u~f{|p}v}wwxpxmor}a{o{}{u{{pgqv{~ve}wyu{}cg|||yyr{{vxso|{yposwy}t|z}y`y~uyxzw{~rmxvwzqxx~t~z}|~~h{z|zy|wary||Zx}~~~w|}~}w{`yov{{zxrz~nnsr|vuqx|}ty{}y|z{}b~wuyo{{vz}ww}wyy{y~~{mw||ywyy{~oqvjy|zyw}{{wxx|s{|yy~|~~xz}yxzjv{|x~|t~}~zuzxux~_~~}~{x{}ol|}try}zx}|k~o~zq|}~izyz}oz~z~|~}v~~~v}tyx~zpmv|hq~u|~v|}z|y}|roz~{r{}pru{y{|puy}~}q}x~xx|zz}zt{vq{w{}{y~zv~wwuywh~s}~zz|~uv|}|x}onvvmzz~{|zs{~~yzwxtwzv}|}tyy}}~~y{~uz|}zwy}s|to~}}}y~}}|pwp|~w~|x|||z~u~x|}x{~z}~r|zyr~x~}zkxxy~}}{|}|twuzmn{wwv~}zz~~|wzxvn~~}~|}u{|nv~m{}}z~wv~zxwnx|zy~}~xy}y~|}uwn|~}{}z|||r|yqu|}}zupulz}yq{y~|wz{z~{~ty|{|~~~{{}|}~}y~~~{|~ls|z{wiqu{{~w{|~z}z~pmw{orp|{}|z}z{~s}pya|n}ku}d}u{wz]o~q}~fgxyoioxs}jWs~j~pf{{vx||hipZh{txuyx{r|{ysuor{~v}yy}iyywz}}}v|~wyvz}zz{|||w}o}x}|}~tv~|v~|lt|{Vthq~t|s}u|}}}~q}~nx}y|}z{vn}w~|zvz~yyysz|~i}~~wx{zywmy~z}ttztw{{u{|yty~_y{tywyyz{~}xz}~yx}}z|~w}wmyr{sq~y{vy~}z{}{}~{z}v~x~{xt~w{v}}}wz~ot{y|{z~~{r}n{{~}vx{wm}y|}|}{}v|yl|~}|uzzny~}tw~p}y~{w|y{{~~urwy}|}zx|~z{|q|y}{{}~}wzuys~{r}pr~sz~}~~upjx~yzxxlzx~{|z{~|nq~|xywy|}}|{s{{su}{|t}w|{}uw~|zzo{z~{v~v~~||ox}|w~ly~|}tz|}~|wzyyp}|}v~qn||{xt{z~|wlzzx~{t~~ts}|opiyr~ly{}x{~vy}}zpzyv~{~~wr~}zw~z{~tz|x{y}}}||~o}x{{}}|~s~|z}~}~~|x~||~w||~xv~{x~zzz}~lryziqu||~u||zys|xqnyztvt{w}xuv}r{|cnsxx}pu|w|vvz|ywx{}}y{}y||f{~}{}rx~{{w{wquvj~}|o~}l~~||zi{z~wvytylyww~pjv{}~m}|wvyzjpiosn{x|wywuwm{{xwsq}|{yz|z|}w{p|yy}~||}~r~|n{zz}z~wxwy~s}y{ts|kv{ryz}zyz}|~lszxhq~t{}xu{}}y}}~~~qnyvpwrum{|}}w{z~|{r|zx{y}~~|qwxzu|~}|}x}{{~|~}{twp|mnw}~}~ty{z|yr}}xzz}}{}}|}{r|rqrny{qy|x~{t|yw{x~u|~~~~v}vo{|wxt}stzpmx|{y~|xxvwq{z~}}s}x|}}{}ut|v~}~~uov}zjruv}}{}u~~z~x~y||}}|tzzs~{y~xt{no~zvzpq}z|}xu{tzy{n}{yw||vp~|y|{}~~|}|u~uv~|~~~y~}wtzkrs{}z~|~ywz|xnqyhmxp}w}{|}z~u~sn|~}wyzz{z}~r}||{tz}ww{{{z|v}w~|y~}z~}}{r}}|{r}||{v~~~y{qywy{y|}vyj~|y|}v~z{xxz|~wyuxyx|u}ztdvwxvizpcvpw{zk{yxzyzoz|wr{qr|qyxwpxy{~c{sszm|g}vyss~pyrpv{uzg{unmtzt}xvivx|twjqny{rsx|~uzts}t{xxwomymkwwvovvm}|fzjztyjqwix}{ptwuouwm|sjlrxyovu~wvrs|x~rzwuzwy{wtzuy|xqp{{{zxmpzrns~zjut|eryyuxuvw~uw{y|wuowu}xon~z{u|]}vDvvxrzt|vpkv~{y|~x~}{{ph{{w}w{ww{m{zo}soznxox{sqt{wwwpyouxrl||}}~|{u|pxt|bkro{~{|uzv~~}wx|~zs{uvsykv{w{~hwow}vtxs}v{|~rv{}yyz~mz|o|~}js{xnz{}}zwyvazztxz~}umx{}yww}z~{|||{xr~|z{yy}}tyxwos~l|tz~z|~{v~ty{u|{z~~{~untwmyzxtvy~ktswxi~x{yz|xxpp~{}nx~xv}~z~}y~{l|w~~ywwszsyyury~{~~s}xuzvv~r|su{{vyuxv}u}z~yxv~rs|zs~wuyyq}z|y~|zu{txwuwwu|~~{x|}~nw|}jozo}~{|xy~|wrm}o}q{|{s{xxos{y}xzum|}rm|~~~wo~|}zlsxz}tsxz{|yxuyp}u|}yy}i|~}vwy}r|}xywxxv|t{~w~{wv|}yy}zv~|ixxz}yu~{z~}~uz|{vwxyyorrwrrsu}{ywzzi|y{|vmoqvzqry{x|u|y~zw~pk|yy}swn~yx}lx{vo~{qxy~}~x~~v}}u}}~kx||vqr`{zy||utzu}wxxqqyztopyv|{}zs}|}nds~{trqx}|zv}|xqy{xt|{lzxyzzxz|~}~}zxvs{~{{wwmy{}xyw|ttvux{u}~u{{kttvzvxywz}}vvvyy~y{n~qu{tk~t}~|}~xy}cxz|us|sxvw~|}z~{rt}~|x}}{}|}~y~x{z{u|yxxrx|tu}wy{|{wt|}z}yn}wtz}~gl}o}|yu{||}w~{wzs|}vxvoxhxrywsurwmyw|xrxs|xrplmn{unvvsyspvrurx{swy{{uqwiw}i~py|q}wwum{zmvw{zqzr{{}{ty}{}|vz|upx}t}m}}y}~|szrqz~}|sy~mys|tzzqq~vzy|~v}|x}{v{p}zw|}zz~zzuv~{w{t{~zy{n{{}ywvtu~zwz{s}{rs{{xq|{z|z{|~{{|wbw{y~us~zu|~~|~}u{}w|v|||~{{z~w{z~{y|q~{yxv}{zxn~|z~wv||xxvzm{|}}r}{zm|y{yuxn~uxxww}nvushxq|x{xyt}}|kwwv{xp|vw}m~ve|zuyz|w{v|}l~xvxywxys}u}w~kulzxzzxv}wwmxks|rkynytwztnozsus{xuyyrt}x}}no~qv|{{t{q}vtt{vwtprxw~twpmxuwtt~wpqzwxp{tptxxt{vsup{~syry|}nv~ywvy}t{~ymzyzss~~}sxtp}wy{|}~x{{h~{{}{zxq}t}~~zw{hy~xx{p}kv|x|}{z|}{~|}l~~u~wzw{v}v{xt|vw|{}qz~y{}{|nuysz{p~wyz|z~{yvhyx{s{vivz{|yzwyxw~|}|xzxid~}~}wsyz~xrzvvps{rx}ut}~y~pswxy}~s|~vywt{v||uxu|tv}yx{~xyx|s}yo}z}qyyrz|z|}ytzww}vxr}ww~}qqzd~n|o}qos~}x}wvqtv|mt~}{x~mx}yuww}s~x{k|x}mzzvoyrus~vy}y~vzx~zazrz|{zrttz}tws~p~{yqx{s{~zvzzyv{yxyzy}zxu|~~zw}t|ws{|xowzxys}uuvwv~}|z~~|}rxuq~|x{}}}{}}u{wuuy~x~uux}~wy{}vxzntz}xwww{|z{~xwu|wf{|yz}z}wv{tu~uxx|}yx~v|{vyzx}|xmr~e|~yyrx{qputfrsm|r~zyuxpuzw}r{~|qz{uyrk|zxw}uxt|twy~~ywqt|s}zwp~yk{xuyzx~n|x|vwqyzzy{p~{zm}{w{|{z{Yfjrulzx}}m}~p]y~su~{{{uzy{~rp{||s}~}gx|~z{p|yvkw}x{p}|xw~|}ys}sfi}{vuqxx}|g|tur}p{x|svr{suyzyrk|tr~ovzu}wktyzsxlu|px}uryzv|xvv{z{ysp|rqyxzpxxo~g|u}v{ktxly~suywyxysz|voxuy|ry{yxuv|vs{vvvv||y|{w}|{ts|||{ntyspu|yxx}mvz|vyxzzyxv{|wxyu}y~}~mzxt}zz{xt~o|{|u|y~ywyj}y{sv{sw}xwz{xv|{|xcyq~}{{ro{uz}~|x{{zyt~vvy}ux{yvvyuw}z}}}yvyws{vx|xynz~}pws~vu~wx{|z}pu{jp~~vrowvw}{y~w}~{~|y~w|zzniq`z~kwkx}q~}}u\}{xmrt{dt~st}youszt`zn{~hzgxy||v{xWspxxsttsv~zx~v{vju~xl|pwzz}ymrr|z{|||~~w~{y|}wx|{vz{~~zuwvm|{|w{vot~z|{}|yyx}~y}|v}ftx{|qvw|rx~yxsy}x|vwy{~}yxwdup|sxst~jozzsz~vxw}svztyx~{x{yzy~uzwtxvxzu{}wxvy|t|}qy}stym|yy}|y~ymvw}|}yvu}rv~x~qtpxywyx{s{i|z}~tvvtx~tzry{put{q|o||{u~{zxr~x{ta~~q}iwyri~xo{xqywsw~}x~wu|}zw|{ywzz}wxv~}ywns}w{rxg}z}uuxpxtsvxxu}{u{nr~u{hn}~p|u|{yvw~nz|u~~qo~}~~y{v}|{|yn|}wuywu~|z~p|z}~u{{{mzr{v~vnpyuirzc{vvvz~p{|t}z}us~x|z{ys|}~y|~wx|yuytut~t}v~~x{yxs~}{t}xyvzzt{w~yj}wy~uz{}uuvf}ty{yx}uw|z}{x}wgv~}u||ow{st|zlx||~styy{urtyu~|u}t~{y{yw}txvzwuuy|r|xxw~r|uuxw|vxsq{z~}z{~}wy{wxr~~|wwzzyxz{ot}qzwzx~z~nnx{~s}sw|owz|~ui|xz~|vpxyguy}pwy{xs~|w~~xzthsx}|ws}wwst}us}r~sy}{uurts~yuxvv{v|yuxw~zvy~|}syv{}s}v{wzw{xvy}{|{v}wsv|rvsxry~{orim~o}{|xwx}~|{u}o~n}~xzns|~il|o|{~y{{{{~}|~x~~v}tlsy|z~y~pxfop}ux}|w}wypxy{|}vt|}~y}~o}s~~jmuo}uy}x~||v~~~{v|~r{n}xw|}|{n}uh{muo|wy}zyx}uw{~z}|~}~vyomy{tu~v}tvvq}}szwwv~|zwvxyq{|xyzw~wgy|x}}zvv~l}||yyww{vv~}yrv}|i|y~}z~tvt|v|zzr~~~vwz}~uuzvu~~qxxxz~t{|wsrxyyu~|xw{s|wuyo}zlz~wzw||zzv{v{x{vtyh|txzz|}tzts~{z{|{sz}{mv{zu}s|yvu~}{xux}qqz}l{zyzyz{}~|}~ymq{}w|w}tx{~uxyzvy|yqh|~}xwz}~~y{vv}zo}v~~~~}}o{t}y|z{~v{p{luz}uljp~vs{v|u|~zm}v{|m}}}~|}{uyyqo~yq}{hx|qgutu|tsx}vtv~}vp}{swnv}}}kuw{p|||lt{qr~}vyuf}~rbz}z{uq~{yu~qs~zv}}tv{sor}|}u}p{vzxwx~x|ru~w{vp}{{pt||{wuwyx|~{}fx}~}v}r}pv{z~~t|z{|y{lxwzpv{vtu~y|~~v~uw|{xj}szxrsxt{}~rzt~{t~~{{v~vz~wm{v~xyu|~}yxwq}yzuztz}}}xu~{yzy|}r~s|~y~|qwztq~~w{qus{|{vvvow|t~{py{|{~|o~zfzm}s||}lqs|uwyr~vzyov|y}}rw~qr}}~{||w~~{|zh{|z{}x}w|{ps~{{~{}uv}zg}s}wqvqvy~q~zz~wx}ww}}}e{gyx{zyq~w~uzy}w}|uz}}zt{xvzz~uux}z}zwp~~|yrus}~|uzspy}|ruzy{u|z{zs{|zx{ty~|yx|ytz}zwysyvzx{zy}zzx~lyy}tvuzuvzyw|wwz~z~|x|phtzx~zm~{rhrq}~q~z|wqz{lu}yv~|pvynz~n|xrxxtx}u}~{}~zv{t|wvw{ym||}x}ysxvuw{v~q|x~d~w|{yy{||}y{{unv~x~~||zyzz~q}{{n{t~|~{{y}~~yz}}~|||vyyz{znywyougpvp|x}|y~~~~{y|}rwu~r{i}}w~}q~xx~y}p~{u{xn~{w{wz{sn~n{y~wwxbx}ouzny{|h}zryt~jv|}u}q{}us{}|v|s~}}q||{|u~~z~|~xh~~z~i{zvkwvv{l}}yuz~}}|zt}slg|vvkxvzl|tt~ssyx|ut~rystyzyvvk}msp}u{vzxkyxyvxlt~qy|tqz|w{vv}uzzyxso|qtzxwqyxo~e|v}wzkvxmy}suywuxxx{|toquy{qxuxvvv}vs|wv|z||y}yw~{{sr}}|{os{rou{oyv|muz|vyw{yxu||ww~r}z|n}yuoh|m}}ozny||w{{~|yxvq~mhxutsuq{{o~qrsw~{v|~ywx}qszsy{xxuwp{t~{ls~|vxtvxywxys~{|y{txmnw~{wz|uzyr{p|povx{{ysr}~~sl~szpyu{zowyrw~x~~x{t}u}quqyzsy~syusz|t|{yy}{}u{y|wwys|}|{svvk~wx~x|oxzw{~y|tww|v|w}~qrz~uw||{~}~w|wu}yv~yr~~~ouwxwztxx}|vx|r{t|~x{|~~}urxk{s{~}~wmor||t{}{zxtpw{yv~us{w}|~wuv{zt|zr{vxtz~~szvz}oou~yvs{|ryk{~wy~t{cxyuz~x|vvj{~}~|~z{y}}v~zup|||{vwx~ye}~v|ulvq~ttvtely}{qyxuv||~~|~su~px|w~}rvxnor|}vrusrwrytw~wyum|s|yu{vzprzvzzzx}x{t}nsx~}nxst{}wx}xvx|~y|m|v{zx}~xxum{ys|xx||w}u{pulzvy{{|st~w{xr~tz~w}x{v~pwx~~|y}|xyzix|xxsuywtszvu|op}|umsy}}|ptzv~y~~u}w{u|~w|yx}yux{~yvws|zr|{rwxp}}y|x|t{w{|vr|}}x|lz~yruvtqxsqvuzqx|z}tx~}w|}wx~}}o~}x}yzyt{{yvt~r}{xz}hs||~n~z}{u|~~~t~~~f|v|xtzz{qp{yzwww|{|}y{{{|wy~z{zr|}}{{y|z{v~{{|nsimo|~y|~{}y~~z|uqnr~t}~~~~xm}|yzzu}z|{~|y}u~yx|pz{wo}{v~z}}x|vz~w|hzz{v|wq{vr~~v~uy}||wzuz~{wzy{yy~{zw}s{vwuy{wn{{y{vswtx|{zlxjw|ty|wzxzzzy}{}{ywpt~oz{xyy||z~~w|xfxx~rwts}|nzu{}{zz}x{vryu}pz|}{}~z{z{z~zm|zx{}v}~z}}ks~v|vzxcxv{}{n{wvw}z{zxvzuiezxuvunsxxh}rssk{y|uv~q{swyz{ri}psmv|yzvnly{svmsqx{ukzz}w{uv}tzxxxtv{stwx|ryxr~}fzv~yzotyoz~}uwyvrwxuv}tqowyzsxvxtvvzwr}wszw{|yuxw}|ztt{}}z{qsvsruzxxw~qty{vyxzxxv||xww||~}}xm|yvgmzn}w~||{z|{|~xytox}|tns}zim}oz{~wz{}}v|~t~}rm~zozvwvkzx}{zuxvt~~{}~w~{{|yttz{fm{ox{xwt||vv}nwY}ht~tzuspxxunutr{}rq|zyy|z{||}xzy}{{}u|~ss}~{zxx}~zzxl||}{vwxw||wpw|{z}xyu~~|{|c~xwyvzuooxhq}}zzx~v}{zwmonzvxy||o{{}|~}n~{y~in}tx~pvn~w{wyrww||xz{mt}uxu}xrutuu}yqbn}zzvyy~skv|rzyto}u}}wr{yzxoww{n{wzzrv~yk|xkzuzy{zmyy{{y{~}|{w~xw~yyypz||}ys~wv{z||r{|m~z~}}~~rz}}|{~q{yzvv{wznu|in}}q~}w{v~sw~|w~sp{wu{~}~y~zw}stn{ywrwv~vz{}s{z{t}i~|}wo~}z}||o~x}~|ouuw~vs{}}ww{tyv}pu|~~z~yr~~}nvtzwuxysv~}r}||~}misxx}xwnz}xx^x}x}{vzlffo|quyv~y~sx~}xxozsp}~|zmrzhlo|||{zzxz}~~wz|rnr~~irwzx}u}~yxp{u~}|znyy~}sp|y}nww~qvz{{zww|~vz~|s|}wv}{vv~}zw~y~~yssx|vzt{|y~vz}|t}v{ysy|ww}k{|w|||ny~pzyxx{zw~|}ywtkuzyxsvsuxtmv|zur|~smw~y~}xtv~qv|wuxy~}{vwy~|zwt|ytx{~wn~zz|z~|vxsvs~usznsyxwvrztzwvxsq|v~x~}y|~}{ynsmxz~uuzqp|w~mw~||uxt{|~tv|ztxn|tz|{u~{|}lhqspptzzzp~|x}~}lyu}e|m~mtxz{vrxs~wx{{x{{~nsnjz~mnnxw|{fzz^s}trrwzl~vi{r{mns}vz{vmwz{vwzuzy{zvixyqymy|o|}zzjvpp}vx}{xx}vqqu~zvlwrwww~v|||q|}p}y~}s~{|pv|tzz{y{ysf|~xxr~~yvxwy{zs|~wv}tz~u}zzzw}zzzw{y}}~{x}t|v{{}xp{~{{yt|u}ww|o|xp~|lmq|~}}p{t|y~{~|w|uq|{{~z|yx|wz~y{ux~yw{~}{nqq}~~{x~{rxy|y}||y{w}~thy~{y|xzwpp|}v{~|~~{tv|uvy}|v|wxxyh}vvsuwzwt|ru}xi~~uvwp~y}mq~wv|t~zt}x|~|qzv~wwuxu}~x~|yurs}vvvw{~xpxy{yw{mqw|vr{vxi{oxtnnmpss|}~z~s|tu|y|{}zwz}ivs}owvyvpvt|yxw{z~vs{nxvvvz}us~~nuxw~sq}y~|~}}|xyykz~u{{sy}zy}v}yz|}zzshty}vpuv||zw}xw|||ynx{}wx|~{usxzyztzww~{|}}x~zv}w~{u}}{{u}z}toz|pz|y|z}yxww{xuj{~x}zv|vws|}~}}{{un{xp|{|vr~x|x{ww}}|eurz|wstsxlw|yz~y{{}t~|yy{uww{xzz|zy|~~}xz~v}w}}z}wl{}}yk}un|~vv|{s}z~zrsquzzst~o|xlnkyx~wr{xvx}w~~~z~exxxv{}hvx{dr{}yh{uzw{vu~s}ynpekk|z|ns~|xr}{hs}p{{~~}zuqont{x~yx~w|z~txwvyxuww}x}wutt|}{o|y}xmvxz{|yi|y~qvv}wu}xxn~yp|~|hm{o{x}~v~vrw{|s}sn{x|zlofm|t|z{}~|xw|zuwsqyqktmx_rl}vmt|{fzrxzmhptuu~vrzqt}di|xpymyss~syw{iqhfzxzwkqu|ozfxlwwdnjvwyo}zlhvgq}yy|~}jp|{bmGc}sa]ha}Sx|vzttpiq[onimhw}pqyrx}{sSspqozl~yz{qwwo|q~~vu|xv}|~tyiurv{pz|}zwspxoz{ry|wxx|w|otyxx~vz|{|xyiq}x{{z|zutz}|zw{vxuy{|z|w}r}tyvs{{|pyv{~x|m{~y|}}v}y~~{{xmx{pytyt{y|x|{x}|}x{y{}yzv{||{zqum~ky~y}ty{{yx}}~xx|}mz{vutv|kjwtpxbw`quspyiwq}}ad{yrn}vp{||w}mtpqsyfttrpqw{kvblep{ybu_srk|y{uwpzxqp|}fvo~ovvqypwjqd]w}ydopxtlpw{ouw{zx~ovkzzzofTi~wvjw~zyxxY}xh~luy~y~~|uk{~~xzw{~~sw{z}{|~xty{kxy{z{}}y|s~y|~{ty|uxwr~{yt}p|v~vx}}}y}}zzyutuky{vr~w}{v~}}|x{uty{}}{y{z}~~{}jvw|}n^rpsq|trQxx}}|}vu{~x{~vsyx`rp{{nxy[swzyzuy{ys~\~}dqwq}xs{}z~wyqsq~sw}pyx}zw|v{rpr~wvit||xyyhxpu{u}v|uxg}vxwtu~ov~dirp~{zz{x}l~~wvr{hu}}~k~xqyttzwyq}~z|y~~|}~{}oy{}z~}qlzo{vz{~{z|~zz}oy~\~}ls~xyrspqztozr{twu{{}zxxu~uw|z{~vyvwzzx~x}yq~wi|{~wyu|tp}vvx|yynpimuo|v{~w|uzz~~twrn{{}t}w~zzyy|wvvxt{{zuy~~yy{zt~zz~|x{iZs~z~mz{ytrx~~tswp}~jsyq|q|}nmyjut~wopunqw|}~wqs|yu}~a}wr|r}~|zz||ri~w~z}yztw|xtv{xo~|kv||vxu{z|v~{{xxz|txxz~|z|~}}{zfw|ywqqn||wv~rv~vr{|xvr{pvxotwwru{{}vzwoy~}uzyr~wz|orh}v|w{yw~{zwumzzrxzx~os{{~v|rwj{|zvyyw{vonvwmzvuy}pxyyzzos}~nu}w~~usq{{vyqpuzrzr}tz|t~|ywvqwyytvuywvuzxwvrvtutu~wwzu{ozuvz|}{u}r~uwp|yhx}tx~qs}{v~~}|pkzryu{}{x~yud{~||eszxtywy{lyyv{o}{mv{}~uy}|rw|y~y{uv}~j|yyzr~}|}yz|{t}|l~y}~}uxt}{{w}}}~~ly~}pzz}t}}|~{{y}}wzvwbr{zzrsy~u{zv}y}}}v~vu{~{tzwwzts|vz~~}zvwus|uu}vzwm{{uytxv}vz}xz}tw}m{}}zz{ywyy{~g{rzyyy~}wzq}{xp{to}}|}}~}||hsy|~}uss{sr~}}{vz~x}s|{yy{|}uzzv}syvxr}~}~}zqu}wy}y|ep~qiwsf~~v~}zvyxwzuy}ql|mvtucxomwqy~{jqur|vqaxxsm|orw|p~l^yy~qnxx|}vusws}ovrrj|zthu}pvpvyrywvvtqwqpzxptwnjzuzwykrr~nwpryuowsp{}tlkyrusz~uzvwpzt}nvsspxyzyut~{zqvxwvqx|vrtrjo|wjuuzptxstszy|w|tzxw{|~z~xy~nr{~|i|losx||}|s~}pz|}z~~x}vvlhntvxly{}fsx|nyi~~y~cz~|xwk{pcyotkrs^d~n~}|sx~rwssqqm~u~q~ltrvp~}{u~u~w|zz~~|xxywz}}un}xsxu|qdusrytqlzzxu}{qyx~yx}pht|pwllwvxv~spll|vuvt~mxjwx}ru{g{qw}pzu{z{wnwvvtjs}utyv|}}{sws{sn{sz{ttyxt~xvuvuv}kz}zqsxbt}yzzvmqypywyvkt|sw|z}yzxxx|rqvvzyu|}vwr|~}~psztov~~wmrc{}xs{xz}|w~}yx~y|{t~vwut|xl{vz{yyzwity{uxzr|nwx{~}~t{msso}zrmp~a{~y}vv{t~qyqszqr{|j}|n~vttt|{tvoqt~|uz~s~~v{\~s{voxxuevpmqsw}{ymvvw|~zvpsqqwj|wtmn~|p{stqy`tt{nu{prvxyxwkgsp~iqzwxw^yvwswkr~m~{rhytzsxq|rzyzwonzqqwvxoxvl|e|{{u{hrwjxwpsvtluwz|smhswxnwlwsstzsozvxw}z{vvu{{votz{|yynqxrnrzpttzwsxztwut~v}wtz{~wuw}|yqs{zlq~s~~sx|y|t~nzz}u~|vo|vn{}xz{k{mjstx}{zk}wxr{}yy|~wvwri{j{wvultu{|j|rqp}ezvypw{o{rqxx~usg|sqmnzw~twkyxrwjq}oq}ui|xuyr}rsxyywppyqtuvuouun{f{x{x|kpwmy|{stusjuwt~{rnotwxpvtwrstys~qyvswxzzwvv{{xru{z|yymsurns~|vst{lrxztwww{v~wu{{|vv~|}w{z~x|}}txoru{{zsg~u}w{}zzmxtzxqq~gx~s|{{x|~n}w{bvmjpvtp|v~y{xpl|t|thtv{}|m~xz|}|{wqwswxm~ysp}{i|qruql{x~}ts~srrxyzypk}nrnt{v}vwhz|yykr}ozsg||x{wu|u}zyzrm}ot}yypzxnb|p|tykvykwxsswxqwzv{}vnou{{oxpxquu||r|yy|}}}y{w~zyrr}|}{{nq}spwylxx}swz|yyvywyv~zwyzympywovzvjz|uywv~}sxq|ztuzyy~}x~|~|t~lsu{u|xslpxtm|{|q}|qmrwy|uxx|zp}r|x~~yoxs}wyy{{xppv{~}yw|}yx~y~||}q|r~o{~r}{vs}|{~n|}u|s|v{yy|~{{zwyzzz|u~~|x}}y}x{sk{klry{yn}}~txttypt|}x~~sy}p{}~tov}zjlpo}xx}}}|}y{|u~u{n~~|tw{|yk{z}~x{rxv{}syh}w{wy}m|qw{uy}yq~|||z}~~cx~y}{~tru{}~zpwz|w}tx~|{xz{{~w|~~{y{rt}ty|ynz}y|qvzwymzmuztzm}|}|~{ws}us}x||v}[~y}{{r~pr|~j|{y}~~t}tcy}|xs}vvk{}~~|{v}q}}z|{|w|y~z~v|{twv|wwz|}{~vmw~~yzzqyztzqmjvv|uqszytucpto}z|}pywuy~|||s|}iz{xx|}s}kyzznwx}vrr~y{zyu|}rr|x}w|xy}|tw}lxy~z|vvw|n{}xzwy}w|x{cx}}}z{qqqvzw{xty~z}vz|x{x||{xz}v~~}zxs|~|~{wnyzz~|qs}wtu{{txv|fzt~}}]tr|}{yss}ozdBvow{{szyzsje>nymnzz|{{rxz|t{z{sk}~kl}~zyqxiys{o~viw}}b^uzx|v~|y{stywvzo{yztj~y\z{|{zzwv~~yx~wnxrim}p|~zxyx~|~u|u}ro~~txxyzyy~twzzzy|}y|xy}r~v|nshlwo}~~{~{}~|~}zz{wsnyxx|ot{imwq~r{}}zz}n}}}y|to{|y|~six}{q~~utf~y{qq{swv~}|zkxwzov}}srywz{v|~oq}|iys{ukx|mtxol{t|tsyxywt|x}zzz~}ysx~~}~lx~~}uzyn}~}uy}n~y~tsh|m}|p{wz}}uy~|zzwqmy}nu{ilp}z}{z{o|sz}{z~w}{um}w~y}}~}gw{{}}w{{r~{wz{~|}{|~xx~vktrv~o|}{v{w}{{~|yw|vgyy|qq~zulsyq{|y{~zzw{x|}}{ztkw}v}{t~uwy~yyms{|{xzyxwbvx~zzse}tgp|uzwhwvxo{|j~{nl}xv|vmz~as|}}{xjyjvxwf{ynvxx~z~}xvwzv{bmf}~r~tzv{}{w`~rj}||z爚|quw\n}w~w~{v{~ssywzfrivyyxz~}q|~lu}zy~|w{rix|~xz~txwsy{|xx{sz~suxsv}{{s|~|y~~|yyvypyv{u|vk|~ys|~zp|vg}}z|uor~v}|w{y}{xxtpez~qlt|}ts}}nvx~lysy{|pfm}vtx|~|uzxrzw}~uxvqv~zxzyyxs|whyzzr|xot~{uyqz{l|vu}xwr~|yv~~|{}nr~}|{tt{zu|t~w~}u|}~yw}zkp|k}winuz~{oipzju{ny~x{r|quvzz}s}x{{vmvy|x}|zxy{}|x}|zyxw|{s~ixz}~oyx}tw}x|}y{y||}z~{|b{u}~r~zp~w|t~~x|zzuyww~|w|w}zyy{w~|zvv~s|~u~zx|yp~yz}|rruyvu~xz~t}ot~~jl}p||z}}}|x{~n~yw~~mx}|xyum}{y~por}}im|q}~zz}x{x|~|}}zp}xwrnz{~wnx}hmp{}z|{|v}v~sl}~qwp~zxruw|w~v~zpwxrzy~wtvy~{xz~}||||ntr|~imp}y}}||~{k{u{z}~xv{yuny{n{jmuz|yq~nyu}szw~wz{rt|{fqzwqxssn}q}yn}~{xqxxwz|yvsv{uo{x~yxsmr|su|rw~}y|||k{xq}r|u||ztvkzppw|{x~il{{}|{lqxw}|uxes}~|}ryy}{|pw}qsp|}xu{|ou{{wy{pmzo{zzwzwwx{}{t}z|r|wqr}~}u}t|vzz|~nvshm{o{~}z}y}~uz~wqm}n~uvu|uzs|~~xuwftx{~~vqz{s{}|v{q|}~vx}|{v~~{ttvv{}|{~{wvyq|w|{|}|x|v~xyyl{uu|{}}|{txvwuyuum~~|}}z~s{yuqf}~zxz~syzuvr~w|u||~kxzy~~vzzwtok|~t~wszuyvxyw|t}|xxyzgvqz|n|u{rsyyrrx{r~zyv}|rm{tus{}wwtvz{wy~sytyvz}wxxmu|w~tzrymz~{yt}{xyvzyy{yxv~axxuty}|roy~u~vtuvw~v~{xr~w\yw{x~{zyqwwx}~z~{y|uvzqxp|y{x{|vt}wz~|syx~p~tz}|xu~wxwqq}}}n|}{r{u|{x}x~~n|w}|{vh|}|m~}zxr{y|ywzxuzy~xysw{x}upz~w}|}vzxvpy}xzzvy{vy|tzzyf{z~y|y|}tuypz}y{uuyxvzxvx|v}{wtzoe}zzqrv}rts|lr}{mmz{zpr|z~cnyu||~ytuxyq{~wr{uxy~zuyu|zxvss|xl}}vwwyk{~vypyzmzvt{vpz~y~x~uzv}x|{|}|{v}{~{}|||uzy~txux~u~~pypxyz}~w|p}|x~|z~}z}{w~}z}u|xorxzhmyo~}w}}w~x~qz}}v}rm{d|yxvsztyuxv~{v{x}~}v}urx|oxy~}s}uxz}w|yvv~xyu{ywxx{{z~{{|y~~uxtq}||wx{q{z{y{z}s~}uz{|zwwtu{{uw{yx~oxszzw{wxi{~xy}rx~uzsl}x{vzuzvxz|x|u~v}|x{z~qzyt}~}{prvl|t}y~nyzx|{~|xts|}hzzwqswqwtozrwu}zwsqrwyx~lv{yuvr|{p~rkx~uzxuyvuyv{|||x|~yxok~zzy{m{w~~|zv}r{lz{{zx}vz{{}oyw{zxzvs~|uv}p|xlvxmwy|pyp{ysqyw}yy~}~u{v}}|xux}~}|yk{n}q|xjx{z|x~~|y~wvrx{}xvyu~||tt}rpv|}v~y{}q~~~yz`h~onwlmq{wzfzy|f{s|yw{vruss}qzzdyynqfx~uxzpqo~cxvo}om{y}ozv~q|}{i{mpx~s|r|yovg}~yt~rwz~{xylq}yo~zqv||t{ur|{s{wz~{ynzsrsv{{ns}yw{w~~mz|ou{{srpyy}zxw{yp~x~zz}~`qqhx}s~it{xv{u}v|v~wyvu}|{~r{{yxpzw}}w|~tzxzwt|wt~uzyp}{~u|}pnt}wxx}{vx|~z}}ms||o}{}|y{y}suw~|}v~vy~z|l{yszvz|ztp}woyrt~zTtysez~{nrvm{}uz~||~sz}z|||ut}|otxy}|v|vv}o~~v~|~}{~xytns}xilo~~z|z{}}}{}~xzvsmyt}tsuot~|}jl}o~}}x}{|z|q~ywwyz}|wz~tm~~}wr~yx|o~u}jmpz}zz{y~{{w}~y}wrlw{yv|vtwtqz}v}}q{lyz~qrv}z{{xwyvixxxxsr}yxqx}f}|tzxpyx}vttn}m{yv~u~w}t{yvm|y}zvz|ag}sufutwzuttysmlqyizm~vx~s{~}gkuwtt~yt}w|xm{vzs{uwy|stzxqwzxx|t}xbzysxxpsx}vyszzq{jxwtqxov}||_{wt{zxixqxwxy{}vo}hu}rvytpuofrxno}~u~|vwrbvpuryzt|uy`t^}|zn|t}~vwxdyyvywouysurtstiv}{ruuvtmtfpwmvn~|qdsx}xqgszpqu|zrqmw~}qzuxppo~t|um~~oqqq|svqpowzyspp~|rqxttkuuwsszs}lrntzl{wrxmx{tw{p{ssrt}x}pzywju}ty{{v~zv}qu~|}r|y}}zyz|{r{{{p|{}}y{~z{x}|xvluZ|~t}wt}zsxw}x|uwuxwxi|wx}{{||wvd~ypw{ytzvz~wqz}zxz{wyz|~jtw~uxx{zxtpy}nx}zyw{r}{|}swvv{xnr~wu|xuxxxywvt|}wv{lq}y{k{|i~{lw~}yy{}{z{{vzuw}rn~{|~}zo~vrimpo{xw|w||tw~~~xvs{p~~n|n}~vosim~o}||z}{}}~q|w|}v~sl~dw|pmnytsszy~s{ouw~ws}x|}}u}{{yp}zv{tzwwqn|r~v~vu{|zwypw}}}xynxpknu~mzzyxy{}p|qrtx{zy~}lr{}trs|jx|{xfu}nx}x|{uo}ssoyzyv|oyv}{{u}z{z|{tz|sxwv}~{|{hxttrx{v~u|fwzwtw}}xvumvr~ww|~yk{{{vyzpxutzt}~ww~}z{tvy~|fn{{l}|}~wuz|yy}yp\l~m{ts{}{xyj|xx~yxpyyzyx~}}{zy||{z{rt~zyvx}whz}{~~|~v}xwyzts|zq}muzxvxvbwtjt|xxq~}}}n{~|zt|yzw||~|s|_qz{nzxot}z}{lw{{{x~}yv}tg{f{uvxnx{yc|wwv}syy~uw|rzsv|}zzsistq~r||~{woyzsymur~{wf~{{~v|svtv{zzyrq{qs}yqrwwo}e{w|x}osynz~svywpwyyt|uqtvx{rywxttv{uszwvvt||yxx~|zss}}|z{ptvov~zxvxzouz|vzxxz~xwz|wxxkwzz{{mwtw{wszyzp}u{xw||o}}z|~w~qr|}x}|~z~uzz~}{u|wmy|}{|pt}o}zy|{q|txx{~}vn{~}oxi}y~u{zusr|~xt}|uh}mwy~||y~zw~}s~qxysu{x{z~yv||xxtrxl~{xys~}xzv}ttp|u|wol~z||y}|~~}zp|wv{j~nqv{~|~||w~z}}}ywnqm||zpqzq{xuowv{vz~}v{uwoszt{v}{~{{zo}{krvz{uwyrssys{{yj~xutu~trukmtz|pvxx~us|}jtu|}ruy}nyh|yzs~yzsiwgyqz}u|fqxwzvuyyx]{}xzywqqektnnkqosxwsbm|rzbtu{xuw}y}||qpym{}w{spxyu{}yzatyvowx|nmyw}pw{lpx|kn|s{yv{n}ust~}i|s|ypww|~{nxy{|zzysz}ox~yz~l~yy|tzys|~|xw~{x}x{t}xbuvyyzqiuzyo{||y~rz}}x{~{uz{~wzwuzzx{~x}~zxyzt|ws|~v{xmz~{ymts|~vwws~vtkzy}}|x|xs~~~pz}vw}~}}vuy|}nwozxe{~~|xq|{}vx}wy`lr~w|vs~|hs|xlspv{rtx{|}zx~|xu{z|z{yt{~|~w{z|x||x}vwr}|}v}swxvu}}s{|}{m|~{svu}zu||x~~zuw~{~|n{z}~}n|y|r{~|}}}z~z|{{{w]rvy}~rzqz{wx}s|wvzu|~}w}~~|t{xxywwzw}{w}zw|t|yr{|wpy~zywtt|~vttp|t}}y~umtvryy~zx}t~v}{||||~{{~hw}v~so{{y|q{}z{~~y{~w~r{^|os|z|wr}mqz~zrs{tz||zzwzvz{x{s}uuz~y{||zu~u|uwwjvw~|m}uzuuw|uw}v|}~rtzu~tszq}||~vs}}{zr|{|zu|uyx}}wvu{xkzyzyz{{vtvvm|wv{zswivuz|{|zwcr}t}wtsusqxvvnlx{t~ovwzttzt~u{wu}||vsxyx{zuyt}}uyv{{q{tk~n~mxvtz{w~}xv{mvzvtu~}x|uo~p~wjlwp~|~}{y~x}w{x~{v|un|jzrz~usvty{~~~}yztz~|}{vz|v}{h{u{qylawvsyxzu}xztxnwyvu{s^}qzsvnnu||kyrrs~h|wwru}pxszwwxvug{qr~lvyw|zvnbwvqwjtzos|tt~zvvyss~syuwwrpzoqwwwnvxm}k{t|wzksxly}}rtvtsvwr|tootwxnvxxtuv{x~pyvtwv{zxiwv|zxrpz|yz~mrsqmqzutr~dsxyuwv|w~wu|{}vvumyhsvvts}xzo|qt~yo}wtwxz~}{~|{~t{}quyuyfzrstpy}~r}x~t}~s{|}}}v|~{|u~s~~yvuvzyrpvy~|ypy}sysvmp}{uw}nivz}q{z|y|yvr|}ptlzutpllr|}xtevz|o|vzzwqoyoutxwutw~v}oum}{yzyvwyyourmxnmwrjwwz{lt{zo~v|uym}vmxw{qgs{uy~trxu|zo}uwqzuvx|~zt}swzuyu{sxuwt}{soxsznzuxvqy{x}szpwwzy~v||}|m}|{~{uyuz~xx~s{}z|rys}zvty|x{{{}{{z~{qf}yz~{qxtux|}swy~u||szts{xwypv}x|}}{w|s{px{{{yp{z|rrs}vxt~|x}evtyt|}{x|owxy|w|{}y~|syozz|vrx~yy}ruw|m|xsuuuw}}}|zx|op~zs}k|xzz_qmyq}{~}wpzs|u{n|\{{|oyrr_|u~~owwv~}q|uz}uoqvqqu{sozp|~pl|soou|}vw~tt}}sgv}ysuun~t~|ozz~wzzu~w~||q|u~{x}uz~|~yw|{uy{{q|zur{}}px~p{zzu||urdzstvxscv|jt{xx{xy|~~zs}}~lvu{y|yzxx|}||}{yzu|~uwl{|vxw}uy~xx}sx||sxyt~}ryzszz~~}}xzvv~r}ov|z}}}q~yv|xu|{yzyx~{cy|{|mx|qwrs|utw~yw|yy~|vz}}}u|xw{y~|w{}|zwt{xs|}}yj~y}t|xrr|}~uu{[~x{}uxr}|ty~vwsimuvy|wuy}wypi~{ltw}xy}su{x}qz|twpnstyr|s}|u{~{{|zx}}xnu{wu}r{wzzn|p{~sv~u~{|~|zs}w}rv|x}z{sx{|}}~{~}zuuwr}yp|zv{~}{{~}w{}q{ypowjm{o||y{|~{~{}~}|~}}x}tlvsy|v}~}||~|q|r~qz~|{}qy~r}~x|}|yt|u{~xxnu~il{o}~x{|zv||{~uzw~yxwsmwvu|w~wyxy{~|yxz{v|y~~|s}|uzwwr}x~z{tl|x~|yxqyx|q{zv|qvwzxsx~}{xuigyzwqwtzts{zrtnjqz~w{lq|x|jtyvv}vrz|{|wzuuyywxvz~{{~{yv{t}snvwwq|~yyww|{v}~vr}y}z|}u}xwvu{y{|}~{~z~uvn}r~imyp}|{}v~||j~v{|qn{x_yxsx{~t|{~}|sƐrw|y|qsx}{rr~|wyzj{x{}w||m|tt~||v{|{{kyuw{t~{{zlw{szw{{s~w{z|xy~y~k{z~}|p|yvqu~wyzy~w{buz{{r~try{}w}~ry}ww~s|~|y|{~x{xzzywxw~~}zwzs|zuwtwrz}}sts|u}t}vxz{|{rs|t~ox}k|k~yzrb|l{y|ww}w}lz~m{z~l~zz|o}pt|n~wy~k|~Wxsmq{~z~s}z{}yz}|owv~twxrvwyqwvu}u|pv}y}zpzy}ovyim|~p|z~{~zv~|~}w{rl~w{zy{~}yu|yxt~wz~vyuixi}}{px|~}}x}yxqsv~~~y}xt~xx~k|x}}xqr~xx}ww}~{v{{x}v}||~wyys{y|y}x~}}yyw}|vzzo{v{w~{ssz||wuv|u}~{nvz}tzt{vyv}{~~vs{|p}p}{oz||t{{{w}xz]t~uwt~zv~vwy|}|r{wx|{~|{zz|w{vy{zxw}}}yzpx}|zw{yx}w}~|tzn}o~~~imp}{z{~|nxqyo|y{|}}v}~uns~|~y}nwthmxo{||}}z~}~{~}w}}~yvvrm|~g||uxvrsx}}|}{|{zt{y}}qxyq|zzz~}{vq{q~~p|qyz|}yz|zo}}|x|~puxxd}}}wzwwqrxz}yqvw||ytyp~yuthtw{xx|upxx{{}w{x}~z~stpqv{ruwyzz|}yt{xly}}kzz~zwvxlv{i~t{z}jzzzu}{~|u~x{x^pvo{|uzpmxX~}rxsvyzoml{wzidzxtmrm{o}|{}lrwv~|}ruy}z}|~wvnjo}|zexnmn~{sy}|ftykdof}l{z}zzzvwrrzxxm}vv|}}{n{zv|{{wt{~`muv}|k|oy{s~|xzt~}]z{os~vywq{}}}wzuyv~t}||}}|`xrz}tfyujwox{dy}z|uz}~wpzq\cxuxt~wv~b{suwk{n{x~nt|otqr~xyypg{zp|osxizviywzpwjp~n{spzzszsvs~rzyxxpkzplzwrpwvm}a{n|vyjrwhwoswunvwtz{rmvrxyow}{wurt{opywuyw{{xzyu|{xpoxz~zznrwmuzrvu{ssx{uxwux~wu{z}uwm{v~~~r}{pt~zj|zrw|v{nyy{q~|v|wtx}{yyzvwjz{z~ztrv{ixw~}w~{yxuxz|x~|og{zyyvyxutsxpqrwwxxy~x|~povp~y~{w|vy~su{yyxyvt~y}u{}t{}y}y}vxqm}wz|z||wtsx{wt{|w{rn~}wqx}jly{Ssnml}wq|}u{uvt}~|zogrxai~|wx{~w~}~|z}rpj~~~txoltzz||o{wzity{v}u~o}|{t{x|z~~s{{~yovimp}yy}|~|~|z~v}~~x{ulzn|xrwp{|w|tnxvw|~||y~~yoxz~{y|~gtwu~|{r}|tyyr|s{}xq{{~rlzox{wwzpzv}wz|}}yy{v~yzt~r}{t}z|{~~v{}}x|{vuyv{q}}xxxt|~ts~|m|u~ty{x~|x~xxya}w||kn}~o}xww{x|z~w{wv{x{}||}sl|~{yz~|xznw~g~}x}||x{o|t~xyi|xv~o|w~w~xxr}w}u|y~xzvrz}y~{xl}b~z|uouvr~ssjtrxssqwzrwwwy~~xswz~tzwwwzx{~vuzzxuvmt}xkxvt{zh{zvx~zy~xpwx{yvtr~~kv~z}vyvt{{|zyq}~}~nbz~r}}~~wv{y}qw{yxt}z~}py~|w|||oy}y}gv~p~~r{|q|wtystt}{yxox}~~vxvrwu~}ytyovuy|sw{||srtxzwqy|zy{{}w{|syuyqzy}xw~yxput}|}rv{qy}r}y{uw{s~yz~j{y{|x~}swz|j~}|ryx~~{o{{euuw|{~{|{hwu}sr{vu{r{x~}{zo~yv|~u{|~{wx}z~zxz|}~wzyt|~}}wo|{||}ups}uuuuxxyxq|{ywztznx~vxz~wpvowx{tzv|qvz}j~v{zxi~zz|{{zxw{j}{{u{wtqxszt~t{zdqxxwvuqrws|}qutw{v}u|{w}s}~sq|t{||r~wzuz}ywv}vwtw~}}zv~rs|~t{|r{xot|{xy|{z}{ttxx~zw{y{u}y{||~zz|y~y~{}~yxx~~~zx{zww|zuvz{~l}x}}ytws~|x}{xuw|{wz~|xvw{kzxyzzuut~wtxqq{~t|vv{~nvzwx{~ysyxy}}t{|w{tx|~}u|}}}ywxt|wu}|yp~yn|{z|~yv~twz~}wrz{|||y}}nw~}hm~p|~zw{||}g~v}pn|ny_{rzqwxr}lkipe}|{l̄{sq{ozb}yjwv|{p|Oxnv|_qsriovs}{{xq{}zez}}wyzww}|tp|}xwrkmyxt~vsx~zu|y{~~||~vx{|nwx}lov~wu~jm}wo{|yxyz~|}}~yy|{v|ws~m}yp|q{|}quxrz}ywuzs{|q{tv~z|~||||}}ppw|{sop~}tywmyx|v{yptwq{~sy~{|tiw}xx}xyy}w~yyqtuox}|w{x}y|yv{|{{ts~vv}q|}p}p|pz{zz{u{t~~|xss{rmwr{}{{|xvyzt|zu~vvzqvrwyx}uyv|{yt{}{}{{vx{q{z|{~pt{l{nz}txy|l~yww}{{m}vx}|}mvtp}t|wquys{r~u}}}{y}|}}lr}|}xjpyzy{utut|y}psy~vsyjrzzot}zqjt}ylxmzvmzvvxw}w|zw}txy{{|{wy|v~}r~zwo}w|||t{to}y~uzxzntsuy}u~sz{y~xwyt{}zrxvruv}{uy~zz~{{~ws|||k~}xxsio|{u|zt}z{zo{yyqq}twz~~ryx~}zpy~|yu{vj}xww~svtuxylzueru{{z|zvusx{}|~st{wu}vy}wzwtwqzst~|zz~sw~{uuuezu{|zz}zuzs}{{}{uynwwwrwov~nsswwwn}y~tttsvtwr{utruwou{uzxxvx}zuy|sx~p|w}vz{p{{y{r~|xr{{rrg~w~}q|~y|sw}wmw}l|z~rw|}zb|zrz|s|{vx~{x}x{~}|s}{lxw~v}|{{qizu~|z~w{|ut~}~y}|wswz{u|xz|~z{z~}yuqO{p{z||m~|||z}zpy{v}|y~y~~reszwuvjy}xj~}sw~yv|{|~~}z~yw||~}|{zz|x{|t|{trx|~|{x|uvw|xvvmv{~{`wxuuxtp}mqxnx`oxyzyq~tzzwwkqq|usw}yoy{t}~wg}yumgz~vycw|yuxv|yj}ww{{yrq|lqtmow~uqtxv}z[syvv{~vxxdyo~f|zu|npx}wywky{|ryu~w}z{gz~l{}i~oy}w{hx|v}|pw{vx~i~xx~zyxtn~~ty}u}{zw}~{ty~r{|v~wyw}y}{yu~~|~|y{~zuyy~y~y||}wywmy}~v|{tvx}{|u~yyyy}}||wzv}|uwstzx{|}nyx|v}z{p}y{y{s{v~|{|~{x|~}t}~xzyx~~|xuysw|{qz||z~}~yxw}mz{|vznq}zjmzp~y||}|}qz}||~~~|~u}toxu{}gyrq}axzypu{zz~mrw}t}q}|znzxwuuvwp_|sp|{x~wo~zh\{|ynpw|l}pw|w{rv|sqwr~|xr}z~|{p~pn{imztrwrx|X{wy{nutz|pq~u}vvqptsgxqwxmpzmwp{vusvmz|ynw{}~~m{z|~}~|woxyy~wvo|i{}~zykm|spk{y{qlxzpzu|wyuwquz}y}{xyyvwxrwtzxsxyy{}z|~{vy|z|z{vxmyq{y{o{y{}orvoz}|~y{xw~z~w~y}nt{hl|o}~~}zz}~}z~q}wsn}~x}{|z{|wu|xv|{}}~xvy}~wwy{zzz~w}|}pmx}~ur~xtvmx{uox{zy~v~x}yzzfy~vw~}zrzuvnrx{ot}ssv{uw~{r}xw|v~xy~rv~~}|zwvs}yr}yyszp{|yyxzu{vtv}nzx}gzyzv~zu|x|yx{{ot~oy}sqy}~z}|~yzfzttqvsu~zq|~vy~z|z}v}zy|vxz{z{|}~}|vzzs{u}z}vsx|szv{|vx||rz|hx~yxz}vr|zy{}|wk~p|~o|{uyu~{~{|xtyd{vx}zvrvpyx~{l~~~wxvuv}}wxy|ypyz|}xwx}z~|{y~q~{~{zutx}zwry~{{xz}|uyx~|h~x{xtwvqs{}}|{}}xrqxmz~xt{yy|~{u{y{{va|qvw|rxsv{lyx{|w~x}zx~zxyvuuqz|~w~zz||~|wvtuu{}|vnv|o|sp|wu~}t{}ur{zvpowq|}r{|}v||m~~x~~x~{{qy~s{or}~yutzu|m~{}w{srxwqk~zsiv~x{tup~|yv~~yop}|~}{}x~cw|~u{tr|ystur{{l{zwqxzx|y|}yzx{y|yy|ypw|mr{}wyz~z}unu|v|w}x}t}l|}|qswvxv}w~tzvxns}t{}z|}y~x~|m|kv|{wnusy}tt|wt}top~w|oxvxz}|~{{~{o}mv}lryy|~oquqmg{{{wzly}o{|zl}w|}~{to{~{}{t{}{x{x}ttyys~|~}y{|w~zxz|yj}{|{vyzl~|z~wyvxxxxyw{z{|{~~rzx{|}x~z}n~~|~||us|s}r{{}z}}|~z{v|~s}pywp}}y~}y|{}v~~{}z}x~~|}x{{rs|~~~v|s}}~~~zzt|~zkz~vtq~up{t~v}skxzxcq{~x|swt}{~veqsp}zxxruw{yuxuvf~uu~t~y}{spvwrnxvt||{z}yqw|~|}wzzn}{eq~}|~|~y~ds|~r{~y|xt}zsqvuyz~}|}z{~yz}zzn{xhy|yvvwp~xm~}zrryg}{u{r}z~o~sz_}qz|yytwv~yuxr~nxxyq}y{zv}s|u|yn{yg~|~z}w}~~z{{~{vywzrt~{zs}~qyzxx{z~wxww{{~w}~z}~~kycou_xwwq{rdq|jyqxv||{iyiy|rpjsizoT~v{lw|uvf|}pj{u}i{qml}yzka{y}jhyyj|vumxuszkykynrpyyt~qvfuy{utugstqfqyaxrtrvovptpunlzduwqr{qtwwvvsvmpqptz~yxy}lhv}{lu{fvyoxwtqv~mwlp{vzkuojpqdmxwkutvsnwwt{swwxo{{x{lxws{wwgzpxvv}uyv|zv|vwzlyy}vtstlykurxyv~|}fyxts|i|yvqy|zpyrr{w}vd{yq~o{qz|{tyrw~rvtxkm}r||wgwurvus{swvwvpwuqitvpqsuqzvty~zypixqzyvvrqorwrtzuruxuvruzz|xsruuz}qwxuswywv|uyw{trxywwww}orosorzpr}txuqxyrywqv{t}}wyzxyt}~zv{z~~wv~|wr~{y~z{}}}}|x}y|{|k~~}}qpw{~zu}tvs~yjr}mw~}|t~znx{w|vy~yx}xr|s{~xw~t}{{zw}}}zx{lxltyk~xkz}~w~v}wz{|}zwl~|~{~rwxy{z{|}zs}n~}{yyw{zx}{sv~~vtqzy{{~z}y}~|~{~}rvwtrxtxsngthlywt}vptsoluvnslpu{ofegpgzmo{ywyus}j}pwohroutxgtf}q~mrv{wwztj|ywytqev}Z|vrqurzxzxtuupu|fiuxorrm}jft|vyxvkumpf~|xwyqvx~vtlnoutyot~xtptpntx{zw~mjzxz{mrqu}kx{tsuzjtgumnzvmtzwxksqox|~r}~}vh{w}}lphstz|}{vq{lsquz}xxn{|s|{}{xpx}|vruskrvwywy^ywsxr|mxykxzw~ovqoxv|{zbyznpnzy||}nytywts|ilrv{ut}}ypvtr|rvwuukutodtvonnsnvjytwu}kfu~mzwttqopqvqwzrnruuvpu|}{vsotuu}txyuuuyvtwxt{tptyvuvv{lrpwnpy~hq|tvzpvwpwuluzt|{txwuwswi|{|z{xk{sovuvwztuvz~wvjwv}vquskpyvvsbxvs|oh~xvzlv}yovrsyxxlex{nmpyq{}vxpvwt{inp|}tt~wrwvq}tyxvwnpwnjvviortnyj{ryt|mkvlxz}rttrnswox{smstvwovv}wpqtw~~qxwtwzzxvxxx{sqszxxxw}lpromr|~pt}tzsrwyrwuov|u~~xzxxwt{{~{|{}{sryky}{tu{}ry}u{}}x|zzm|}z|}xz{|sj|~|y~}yxz|}z||vxvj|xt~}~|t}{|x}||z~yzt}{}oyy{yzuz}{y|~vv|xqt_}vv}y{yyx{}|~zyy{}|~{||}|xm~|}xhys}wvtyrnxqyyzqyuqz{~yfzz~wsvtrtxvxy|k|yv~v~kxymx}yqvszzyx|e{|qpsyv~wytz{svr|kqs|vm}ysywrzsxxvwmwvqguwopsupxj{zzv|njvo{zutsrutwux{upuuwwqv}y}xvquxy~tzyvy{zxvxwyw|uqu{xwxx}oswvor{}it}txyrxyrxwtx|v}}xyyxxtwwy{zyj{z{s}tz}zs~s}yqx~}}yu|ul~ywzx{xm{lzl|{uv~qy|vy{}~swtw~vv{jwwszx|}yszsvssppsu{qv|wvpzuyyxxy}zuuwxpw{zw|zv{~wq}x}~~z{wwtv{rqzyyu}wxww~}|s{ywxq|wuw||z|{y||{xx}|z}{{tts{txqwu|psz}x|{{{vx~}|zz|}~vv}x{yix|zru}~|z~~z|~{zpyzr~zzvts|zzozzlz{uwz||vsyvsui{v}wtxrk~qxuyvmy~_zusv|j}yusx|{qzr|zvnd|wrpvz|}~xrdsurwlnq|wiu{svst~swuvvq{vrisvspuurxlxy{wqkyr{z~vvtrxsxttytrpwuuru}z}xtttu{~pyvty|zxxlvxy{usv|yxxx~ornzps|}kt~syqqwzsywux|t~}xzzyyuq~|}zxwz{qw}v}z{y|uw|zz~xu}{~rsw}z}yz~muctytoeyokwxwxztxyqyvwsgzv}vtxsgznvuwn~{y}{zsrskvvqx|yotqwywtrb}zxpovqz}ywstrttzim~r}veu~rvpq|qvurunwspcsulopsptiyxxt}peuoyw}vuqoxqwqvyspkuutptsw{wupsvx|rwwt|yuutuxu{tpt{vuwv|mqlmnozbq|qxrovxpwvqwzs|{zwxvxsy|x|x}{{q|{w|y{}~~~{|z|u|o~|y|xy~|}|~w{|xo~wqrxyifvywzxsup{u|tzj{y|xuxs]~tvyyuz}e{usu}p~xuty}{puryzvwyrdzvrozsz}|wsoqtswlm~r}yh~xzswrtyrwvvvqzvqitvsqvuqwiy|zw}pkxr{ywvsryswpvzurqxuvtvyz}xvsuvt}rywuw}ywwqvywzxsv{wxxx~otsspr|hs}sxhpwysyxtx|t}~xyzyzu}}yx~suwznsu{x|w{o}s}xzop|||t|qzpxyzvxw~|p~sp}oz~}~}vn}wq}|~xutut}|yyz{|~{kt|~vyuv~~~}}htxk}{z}ry|z|zwz|ykwx~u~~zssz|vryxv~~~{~|ty}~~~x}|x~{mvw~}~|hv}u|||w|ttwxz{}|~{|}}{~rzkz~{wtpu{}trc{nsw{xtxpysqxw|xhx{|vsuthvktywxuy~zu{wrr~kywsy{xouruzwxb|zpp|oz}rxuxtst{jnt{}whvxrvsrzquwuunzspetvpppsquoy|xv~pev~pzwvvqooqvqxytqowuurt~v{{wuptuu}txxtxzyuuuzu{srw{uuwv|nsornpyjp|rvrowxpxwrwzs|zxxxuxs{}xyz|zyw{k||~|v}t~~z}~z|m}}ut{~}yx}|r~{|zossyv|t|~}z~p{}u|zsw}~vx}||z{~x~|t~~~~|~x}u{{nkzqmx|vwyx|wt{u~vey}|wsxt`ttxzt}w|{k{wq~s}o|xvsy|zptrszvznczxqpsz|vxt~wptswkkrw}xpx|svrtzrwvuvqyuphtvpqtur~vlyyzw~pixr{ywvrqqrwrtzurpwuvstxz|xusuuv~qyvuv|ywwuvyw{urwzvwww}orstpr|gs}rxkpwysywsx{t}|wzywxutrz|zr}}qntv{xxr~wp}v}|xfx~wsztfqvzztzd{yryt|rxxnxzxpvspywz}wcy{pqmzx|iystwst{jnr}|wm|zqwtsyrvwwvmwtpftvmoosoumz{wv~nhv~o{w~vuromrwvw{tppvvvqu{y{wuqtus~tyyvwyywuyvyu{uruzvvvv|nrvwopz~jq}tvvqwxqxvo{vzt||uywvyt~~}{wz|x{ut{{yr{z}~}|~~y}w|t}}v{|}~{~wi|z|}wxys{~}}|vsxy~x}}~ov~q}|j|~|zzx}}z}qxxtyw{|ty{w~u~zu|x}u~~~|lzz{}y~q}{uzvsz|}pz}xy~t|f}{}|zz~v{}|~{wuyk|zyx{vy|{~h{zpwqrxl~|yzyxl{xpyxvvyvt{tz|~znzv~xsxtszww|vyq{|vezvvu{k}zwry}zpvsy|wxf|yrorz|}~xwqssvsxlnr}xovtwtsswwvvqyvrluvvrwvrxuzy{x~qlxr{z~vwtrztxpvyuslwvvrvv}xutvvxrxwuyzzwwxvyx{tsw|yyxx~orryps|}lt~txvqxzsywsx|u}}y{{yyuu{|zz{gzxvzx~ruyytx{u{wj{v{uqvsj|nv{uxts}wzfxtrr{g{yupw{{oyqxzuypc|wqotzz}yyxs~qvurvjnqw|wlsysvrt}rwuvvqyupjsvopvurywlyz{yrjxq{z}uvsrurwpoztrvwuvru~{}xrsuu{~nyvtwyywwuuxx{psxzyxxw~oqkwos{nt}r{upxyrywvw{t}}v{zyxu~}{~~{u{|kutz~{s|{}}|~}~}{zz|x~jz}{wz{yzuu~x{s|}|x}|xz~z}{y}~|wj||z}|zx|~~wtwx{|z|u}}wv}wzuv}z}}~}t{v~qxzul{y~~{|u}}z~u~t{us|}ywx}}{~||yy|}~y|{}}j}}~z}|y{u~}z|puvs|tzxs~~~}{|~yw||{{}|{~}yt{{|jz{btztrixpuuzwuzr{r{swufzw}wwutp{pvuytz}~n{wtq{m~xvqx}zpurw{w{{d{xqp{pz}wswnurykms~}wcwvswsszsvvuvpxupivvnprtqvkz{zw}piwpzyvvrqrswqwztqmwvvrur||wurtwx}qwxuw|zvvxuyw{urv|xwww}nrrunrzns}swmpwyqxwrx{t}|zxzxxti~}w|~swtt~zs{xxz}|~{sopk~wyxlky~xw|vux|g}}wut}|p{~zxuv{yv|lx{m|vhoqqxttnysw|w~xx{||~rkmykszyrwi_|vf}lu|otw||wpvs{rz|w}tyr~xvt~~o|}vvuv~}svzr{|}x|{}uxszyrzuurvp{r~fulux~zqu{mqv{vrun~wm}|{xtzxxzlwsu~~l|qx}stq}kvy|lju{~mv_yr{v~r|p{rutait|ukmn~o~wss{q|j~l{vs_{}ykp~rw~r{y|l|p]}x~k~ovyo|yvmwrwgri~sc{~qxsupvwlvtu|usocuuip~sa~viqxwsynqlxutsrvmvxlwfyosml~vr~xptnng}|cutgzx}wqtvv{g~qo{vqtvjjbqmowmqxxqttupuss~|l{xx~tuvpwxsx{rhvsqkuty{ouxurw|vsnsyzmsrz`yqq}p|v{vpwy}ug~~tzzlh|rw|e~^}wz~lny~w|vw|xjpyiqrl{wovwovk}t~pyvtuqwwsfqyrxlrnznyqwsznalt}lz~usvqvssoxppnzpwpw~t}yztztwr|~wuft{yyytwxysuqvztqsvqnjtgoxozruvnlru}wtupn{vz{w~q|yykz|~o{~~vuys~~|wcv|zywn}}oq~i|qkt}|}q~xqun|}z~vts{w~{zk|w~zv}puv|q{yv}zw{x{y}~vt}yt}ynxmp}slwfw~py||vs{xlyxrl}{y|zqx}z|y~v}f}ox|~xml{pl}uvpy{pqvyu{fu}|ysvsdzri{s{rty}vxvvwixuw|mnys|}m{q`yyl~pz}|}uwxyxqstyirmxyxg|}uqvpu|ruwtuq|zxhnyrxmttroz|yr}riv{nz{xuvowtsqytpsmyrulw~r{}ssyqrs|rxvms|y|wztyyxusxzsqrv~sokrqpy}fvzsxvrtvxxuv~}s{wx}wwqtrs|vupzonv|yxyuzwq{svtmzx{wuwtgufwxuxtv~}qzurr~mwvpy}z~pyqy{vvc{vqqxpz~ywulptsxknr}x^v{svqs{rwvtvp{upjvvoostpvey~yw}qiwpzx~wvrqtrxrqztqsvuvsux{|wurtuw~rxwtxzzwvquxw{usu{wwww}nrpunqzir}sxppwyqxxsy{t}}yzyxxt}}zy|}x|z|~|~~u~{}wwx}wx{{u}|{}{|{|~~~wxx}znz{v}}xxy~tlyg~|v}xp~zxjpz~rrovujx|}}{wiot~n}{sys~{otx}vti~{~v~pzxqv}}o}|}lym{jcs{vrvxn}wvv|}njw~]{vm|lrt{o}yzuvqmo~yvDypsoqrypxt~roiezltuvt~xz}oszdw}usos|zqpcv|io~~y}nwsq|m|wyhy|xyz~u~~y{}z~vu}u}|{|w{vz|{lt|~z}uw}~|}~}ht|wm}|z~sy{|zwzzzkxy~u}~{sv}{vrywu~~~}~|ty~~x{}y~{lqt}}~}hw~u|}}w{uuwvz|~|{|~||r{k{~{zm~zz{u~z}buxs{}yxs{zr}|yyy}|{~~~|}|}{z}zy~z|jvu}~t{uw|xyst|~q{}~xyufy|ykw{w|zyzq{~|{zx{y|{p{~vxzsy}|yqt||uvvwt~z||~|~ux}~}}vv}|vzv|sq~ty~}wzy}~~}xt{}ww|zswx{}{}|{xyxyyzs{~~~}|v}{~}}x}~}x}xy~~|~~}{|~|y}|}w{z~~|t~|t}uztyv|||{~w~vv~o~zowi~ywlzz~}x|zx|x~u~xuwzzq|s|z{{~}~}|z{z~tzy}{|w{s{{~xv||w|wr~qrns}}zujysssy~tty|wr{twm~}z{wrysc~qw|vyvp}udzxts}kzzvty}{pxru{uxwe}usq{u{~}{xskvtsulm~rv}yovzuuqv}swvvwtzwrluvqrxvszxjy}}zrmzt|{xwssvtxsryvtvyuwsu}~ytvvuyp{vsuvzxxpvyyzutx{yzyypsmwqt}nt~sylpxztzywy}t~~w|{zyvx|x~{zyupxkiv|uzzwxuu}tt}lzw}wvys^}tw~yxnvhzrru~o{wvpx}{pvruzuv|odzwro~sz}xxqyutsvlo~p}}xht~rvps|rxxwvq{vrltunpwurwmy~zw~skxr{y{vvsrwswrt{trowuvru|v}yttuvv~pxvvz~zwwxuxxztrwzwxxx~ornpps}~gt}szopwyrywtx|u}~vzzyyux}{xswzw~~zf}}t~xzso~}v}zk{|rhwzosyv|tz|~z~p|y~~w|mww~~zzzzzk}|{}p|rqsvty}{r{z|{vwp{yxswtty{wwq{fywu}qr}v{ou{qytuzzurixyp~nryt|~{xovyt{kq|p~}uy~ztywsu{zyxpo{omzxjprvn|k}q{u{lqwly}~quwuqvxr~}umtsxzqywyttu|szwww|{{xzy{}wrs{{|zynqyunu~}tvu}nuy{vxurx~wv{z|wv}~{t}~|~ttz{r}~{~}{{|y|}}yzx{}~z{}}izujvzryut`zqqx{uwzvuwqzu}qevv|vvwuezkwxwrz|{{sps|l~~wunx|x}pwrr{v|ncyxporz}}pxsstr{klpw~wi{urvqpyswwuun{uqistioorqtk{|xu~pgwozx}uvqooqvsuztppwtuptwu}yrqtvy~rxxuv|yvwtywzsrvzvvvv|mqmmmqzjr|rxspwypxvqv{s}}ywyxwtvslzvnjwogxxt|ytts||owyzsept{zujlmyus~|ut~{srpu{t{lxm{qwupyy~}usyc~|x~o}pzs|v|qzxzppnvs}iyysupvfx~q|usuitzmiyvgqpjrzbtwuw}qitzxhuuzsu}lus{psywiqtrwto~ruwqspqy{ow}vyxw|puwyz~ymvzvrvzpprrlyy{qu}rwsrvyvwxzxq{w}szsu~|~ztv~u{w|}y{u~zkv}wwvyw~w}~jux^~|{|uyz||zy{~zk~xyx~{vs}~vszxx~~~|tz~~z}|}qy|kw}v||~|w|vuyx|}~~|}|}~|~s{o{~{y|~{||x{yv}ztvwttt~zr|}{w~|sz~v{xs{~{v{~~z~xr~kz}}{w{|~}ov}tyws~z}~}}z~|~}z~~yw~xx}}j|}xtv|yruzqdumwzw|mt{uvvfz{~wsyqfvxwwozoyvt{r|o~twnu|{otrwxwwpsdx|o~nryv{~}xptruqxion|tr~yrxps|qywtvmswmduvdostmxd{lyszkkvly{sssrytws}{smmrvwow~w}wxqsyv}qxuu{zxvpxww{uoq|xxxw}mpvunr|{et~rxmrvyswusx|u}uyxywt{s|r|xtxv}u}z{ywz{j}z{xxtkz{yzy{~bzxwy|pzzytx~s}uz|xtzvkzxu~ov{}|zpisysvoq{s|wu~yxuyuv}u{x{xut|stwxytyys{}v|}~zqt{t|wwxw{wyt{|xutzxytyz{uxyyq|wwuy{|zrzz}|{vwy|~{{ruv|sv~vxv~muz}w{xwywv~}~{yzv~zxwvy{~r~}~w|}oyyzz}fuyyZnw~|~s~oukwmz{w~wrz{~|}|~yv~v|nt||zwy||vu|{~t~}~q~||}~}|~y|}}}{~~~~uk}~~y}~r}v{v|y~U~svtb|~~pzv~uz}u{{}xukzstzs~|zx|r~ux{s}}wt~}z}{uur{s~|qzry~{|{wzusw|}ymqnu}}utmy|}yzww}}w~zzx|v|upy}}z|yq~zz~ypyrwupw{~z{}y}|u}zyrvqX}zsu{{l|~}x\]tzt{}stzz}{zpt{s}xwys~wtx~~`voy~|zpy|r}{{}~{v{z{stysz|}t}}|s~}xyw{{}{{{{vjyrtx~||qu|vuz~nyprx{ty{ziz{~yv~}xrz{~|}x|j~}v|wr~vupz~~}{xm~wrknwo~}wqzq{zmy~vy|syx}~z~y}x~|{qvrug}~avyvsnythvywzywz{s|vyp}euv|wxwsl~twwyrzz~ztrt~j~wvmzzypvpwzt}tubyzqozpy~~~xtppsqylkry~wbu|qvpszrwwsvo|sqjttgpttqudx|yu}rgwozw{vvrpvrxmrzsphvuvquow|ytpsvt}rwwuz}yvvtuyw{uqu{vvvv~mroroqy~gt|rvupuypxvpyzs||zxywxuzy}rx}~yw}u|yxm|tl~{~|zyizpy}}{~xy}{y|qpi}zx~vw}pu{~swwyvzz}|ytw{{m~|xxuh{z{{{j||yx~u|zyuzu{v|}zryzn|vw~ry{~zqoqyswqt|s}yp{{w{ux{v{y}zwv}uwyywvzzs~s}|~sw}v}xxzyxy{{z}yvx{y{v{z|xzzz{s~xxtz|~{t{{~|~xx{}||tv~|tx~syx}kw{~y|zz{yx~|zukvyuxhzrjxxtwzw{zvywstdvr}vuysiziyuwq|znysrs}i}tvox|yowqxzvutbyxpozqzz|~yxsvwus{jnq}vf}tzrvrq|qwutunxtpgsvlnpspugzxxt}pgvnzx}uuqosqwpu{soputuptzv|xtpsv|}qvwsz~yvvvuxw{rpt{wvwv}mojpnpy~ks}qxqpvxpwutw{t||zwxwwszz|{yxzux~uvyu}z~}}r|{}}z|~|~|~w|}mx|zr|yzs{srz~uxx~}|qv}ryz}h{x}xtzuh{ku~xxuszzc{utt}l|xssy{{pxrx|vvqe}vsq}rz~}wxs{sourulor|~ygu|svtu|rxwwvs}uqltvtsyur|woy|xskyt{{|xwrrrsylrzutwyuvsuz}yttuuy~pxwuw~zwwuvyw{tsy{xxxx~prnuqt|js~r{oqxzszxwx|t}}u{zxzu}}r|~{r{xyyyuw{v}sz}}vz~~}v~ww~{{p}os}}uy|vz|zz|ty~y~~w|uwzvzskvxp|z{ur|}{xwwx~}{|yuxy~s{}zzqpx~uutxs~~x~||~wy|~~|tu|xw~uzws~~su}vz}}w~~{v~z|w~~x|sxyy{}~{~zxwx}w~z~~{o{~}|}}x{~vqs|ozrky{sox}v|tv|~szxrzgrz|rwvwn|qwvywxuzur}v{m{sr{}woxsyyrxa{~qpozy}rxxowu{horp}wnvxrwrr|q{wtunxuqesyqnmrowlxvwu|mguozuvtslpqvluysouvqvsv~w}{{vruty}svwsxyxvvxwzvrt{vrtv}oqnskqylu|svpptwtxusu}t{xyyxzumw}|ojzzrrx|ryy}|y{v~z|dyz~wsytevsxxux|{czuszq{pzw{trx|{otqwzvt}nbzxp~nryx}|zxswlusvjl|rv|wt}uwsvrr|rwvuuqwupgruvqutqxvmx{zvohxq{ywvrqrrwjvztrpwuurtyy|xuruvw}pxwvtyvvvwyv{sqwywvww}nqqqor{hs|r{hpwxryvsw{t|}vyywyt~|}~|zzs}y|{tt{uqx|{y{}|~|t~~}{}}{yy~wi~{hry}ytx}qjz~vy{{mrv}~{wdoyxsfxyqvw{txot{{~wv{}wr|p}|xx{{urqmn{o}wn{xvwn}v{zinvl{y}~{z~ho{|stSi{ifzoc|~vy|~z}luwyz>hyxr}~~~}wav{uyzx~z}xzwvz{z~}~~z|uw|xzus}~zz{wqv|l}zzwuy~}yyxzyzzr{vw{rz}|yps~}uuuxtz}||}vy~}~ww}{{w|uv~vw}~x{y~v}}zt}}y~|v}{txx{}|}~||xy~xz}zr{~~~}|w~zsnn|~}}f||cp|zwzy|{~~||zy|umzz}xw{{vt|ts~m}t|t|q{ryr}tm}x}y~~sqvvzxv{pxq_~}}lz{m{rw|}~~ynt}y|yv{~yz{|~}~y~wv~~~wuw{yw~}{~|zxv||}{{||vwz{{~vp{|z~~~tzmxywxn{{|{vqy{~zx~w|}|z~n|}|}ytt~tuqzs}u}~~l~{{ruoe}w{t|wz}zl}t}z~u}}t{|zt}v~yo~}s~~z~|}|~{y~u~~~}ry{{{|t|z~y{q|~{wzu|~~yww~}~}xyy~}xvs{l||~ut~crhuzyzxwxxzx{tiw|~wp|th|uywyv{Qzrptp|{~vynxyxosr}wvwebz}noozyx|uwuzutzhq~r|{uy}xrvrsrvxvtkstobsvvpnsovrzyws~kfu~mzxttqorqvhzzsoruuvqt}{{vsotww~tzxvz|yvuxyu{rptxuuvv{lpxzno{~pq|sxtqvwqxuouzt||sywuws~~v~}yxvz|~tquq{yv~xy|w{u~us}x~vz~z{l|ulj|{wfqyol`trw}urtuqvwys~cww|wsxqftvuwr}zyfwroztr|twqx{{ntowwv|sn`wvnn{mx~{zwutoupzilpz{vk|w{qxpn|pwvrsmwtpdqumpkrpv`yszrylivn{y~strpwquhwyrnostuqu~vu{vtqsur{t|vt}zuusvxuysop{wuvx{mqslmm|}^r|tzhouvqxwpyyt|{vwxvwsz~{sz}~vtyrr{y|{}{|{{}}}zq}~}oiz|uszv|szv{pvsyq~m}~v{{~{ow|z|xpvwpuywx|{xxz{qpmryʅ|yl}vpxyzzpwzwsp~yi{xy|y}y~~y}y|~qw{|||{yu}~l~}~~}}z{ypr}~|oq{p{q|~utov~z~~v||}}z{~utq~zq}y~z{|}}v{ww|~t{~{}}xuzxuz|z{un~{}y{zltg|{x{qz}x||vzwxtypyyt~{|zts|yuutvtz|qy~zzru|v}z|{||~wz{zvy}xu~xyy{{{{~z}wu}|{w}y|x{~~w~{{xrxw{~~~~y||||{}}}~~vxyw|}x{x}qw|{}}}yx}}xzrz}zkwxwb}w~qw|xwnwy|sv`t|{{nrwnrq|}~{z~|{zq{{x|u}~}xo|rjvpq{zr{ycz~fqxvvvx}dwymssz{ix}u{puj{nurupvunivspswxiwzsfpvurtuk{{puw}psorr|xruavkprqxxx~mw{t{qh{{nustxxktvuwsv{uzvt|gouwptv{du}vwsttxwqq~}xfywxwv|lsrxx}uxpzvmyvxvws|poxztz}gwv}wtwtm{ntxwvugzvstzlxvrwzyoxqxyx|oa{yplpyy|~~twvzqtr{ins{whwxtwvs{ruutukyrodrvvomsoulxuxt}mevp{xutonsqvrwzrpsvutquv|{vtmtv{|twxux~yuuvuyu{tpu|vtwv{mspsnox~jq~qwspwwpxurv{t|{wwxuxqzf|{u{fxuqvvxxy|p|uzusukzu|vsvtqsxwwuwqyusom}uwovzpzqqzxvpexwnmryy~{wrsxs{in{pw~tn~wtwtp}txwuwnrwmjwvnnounzzjzuyv{kkwly{rtssnswqy{smttwwpv|v~wrrtz}sxwuu|zxvwxw|vqsyyyxx}mortlr{mt~t{kqxxtwuqw}u~~vyyyvtzu|z~wwtx~|qz{zzxr}tt`u||wtwqzxy~{dwmvl~yvzsv}u{{wuw}tguqw}y~}yysuyrmvstu~w{{xou{y|{xxxs||wv||~|||zbn|}sx{{yzu|vrqvvy{~~yz~{x~|}xy~yy}}m{v~kv{~wv~|y|{vzyt{tys~}|u|}{z}|ryx}p~x~w{}y}m~~z~j|y}}{zzzwy{xr{u{}zzsz~}~~{u|{~~wzx}~~{~wuq~}z}}zzy}|zz}~zu|tr}{yyw|}ygt}~v{sv|~{~ziuvp|{xxpxx}|zxyyxj|ww~ww|}{trz{tqyvu~}}}~{rzx}~}x{|v~{nzx{}~{jv}tz{~{w~{tswwz|~}|}y{{zq}znz~{yskxz|xqnv|}qwi|||zzfwyq{m|twwv|Otqs|}_zzrveuyvqz~vwsvuxkv}c}}uxt{{~wghvs{{|sgszzu{nltxxwxdx}pf{t|gqt`sgyjyv{unvcyzwik~ix~Xnqoxvxlxxwwtiw~vvrvv{yk{vwrxtr|{yy~qk}fwmv}wyvx|{tyt|{\xhzyt~||~xqrwxqox|zvuvo{vwgry~uuj}z|xcqqd|{wx~suy{ysyvwg~v{v~~s{~zr{zsnyvr~}z}{w}{sjv}}}~w|{v|{vs|~|~~}}~z~fs}~rz|~ys|zsrutyz}}}z~yz~|{{ozxiy}tzv|x}u}|wwtv|}u}{yx{y|w~~uy}zxzo~|{v~x}{}xlzzu{|ytps~spzy|xvyuz~xdr{~w}twr~|{zeruu}zxyqvx}zytyvwhvvv|z~ytuyztoyvu~~~|y}zrw|~}~x|zs}|ryy~~}}~~z~ft|sz{}xt}ztrvuzz}|}{{~z{~{{}o{xjy}zy~||}}uv|xszwv~u~|{~s|~}|}z|}xyzuw~}|{iky}uiqvzrb}|}lwysyq~y}ruu}~uvb{{z~|zz{wxvlz|tum{p}xir}vy[||ugyd`~zsi{{uy|{qbp}vy{|wiusth[u||{vw{j{y}txrotp|ntonv~{|tsyt{~|{q}}yiw~yos|z~vvt}y|~}gt~u]}|z}sw{{zsztyiyw~w~r|}}{rx{uqyxt~}|}{sy~~~x{}u}{po{~~|~|gvt|}~|t~{utvuz{~}}z{}~||q|zi{~{xstzzow}~~{qrr~ty}{{|{v}}||sz{v~v|tly~u{yxu|yxzxr~x|ui~z{rv~w|suzwnvz|z~sz~~~~uwxs~lv{w}||xv}zyz{y|}z~~w~p}}w||nx}|}t}s|v~}{|xntx~ssrb}zop{sw{}|rwx{|}zz|~{{txzwywy||{{~xz}u}{wwyvxr~}{nulsq|yw}twqnyr|x}xyu~xy|{st~{tz|~y||{v{ywvvztt~|s~~y|}|}z~zx}y{xy~ltxv}{v{f{zovt}{w~xypw~t{zownyv}vrutg{mwxxt}jyvsp}p~vxmw}y~puruyw~zodzyom~qz~|~vxowvszin{p}uo}xrvsr|rxxvvnsvnhuvfootnxkzwyu|mjvmyy~strqmswox{snuuuwqvv}wqqtw{~rxwtuxywvwywzuruzwxww}mprsmr{qr}synqwyqwvnv{u~~vyxxwtwz|kx{t~ovuwzyzlyy{yxx}xptsxn}vvtTxxvvq}ox{mu~yp|swyz~rhyyonpzs}~qxqxyt{irzq}|s|}}zsy{suyxyxmnznkzwvopul||s|oyuzhovky|qsvtmvwn}{tlztxyoxwrruy~tzwurr{zwzwz}vrqz{{yx~mrtwms|}{uv{lsyztwupw}ws{y{vt{y{|}~}}}}vq~}yxqxw}}zvv~su|yzty~|zyw~nqw~yv|zx|q|T}xztxnzyt|xz}xru~rppxxs~|z}rvzsmwzzvw}uyrxy}ix}}wswul}rvuwuz`zuo|pzl|wvmxzxo{rvyu~nbyyoooz{|}twtqrurxknq~yvn}v{rvqs{sxuvunxtnhwwumuso}yhyzwv~niwmzw}uurporwtsxtovutvst{{}wuqst{~qvwvt}ywvsuww}uqtzxwvw|losvlp|jr~txqpvwqzvqw{s}}vzxyyuvw{|{~w~tsSs|zs|swop~rR~nqsjqw|{j{}uoyopAx\}l~vtyzur}{|x}k}wwxz}~zvp{v|guno|yvnuz|}suufx}}l~x|zgx~}v{ksj}pvtz|||zxvubuv~|f}|gsv}}pvy{yzyuoz~xmwesw~tm|wlym{n|}|~|zttzz}uu{zrz{}|y|}||{{}z|}||~~}~yj{~vszzz|ysznxqqtmow~ux~nmzy|t}{{xx~~zr|x|{{rv{|u|qz~zu{u~{}tu{|s}z|w~|}z|~~~{{y|~}~{j~}{z{}xwuy{xs{nyx}y~|}}}zsw}~{~t|k{twy|xupnsn{qsuuxqyytsly}ov{woclcjwlyujvt|{zyi}k}ts~cmpml]v{nqi|pursz{rv\m_phuroucz|uuwuls{|fy{hjlmyxvvlzohruc{}woh}vxw}wqlo~tu~xzqxlygu~z|wvf]yxrvwtxxzmsyutit~qmek|sx{~tylmwspuyu~zsk{trvvgp|z{{v|y|vuvs{|zzs|~{|}|{{z|~|||}||}}{|j|{}{x||wzstzsy}|w|qw}wv~w|~}z}|ujyvsv{xt`ypour}tyyzrtxwvsnsvyrmptgupov}muuv|uqytj|ztqw{s}jwhxk~t^tw~l{qz~vwyvuktrsymoioztf}ysyrtew{pussthwufgplerpswqeytvozlcvvxcxytsvpwtxsuurmg|qycu~uwxwpvqyw|yvtkh{xzosu}{ztpuyvtlummjuhnxqhu}qwkstwwwswy}e{wywzpqzv}~x{ow~uu}bjov|v}zzp~twus~mw{nw~t|v{y||gxr~}}yz~|~qxs}{rtt{fmfwytzR}luBrjxsyixtqqxyo`wKdt_~bpsw~rvu~~pmel{q|}kqp|{vzz~vdqhfwoqgnpoq{g|zh}lusu|}|q}\~ywv|yczu~wzsylxst}yyt}{|trzxjx|t{zzu|wzwkzw}xvxsjxyxyux{gzus~u}o|xtsx~{pwqyzw~|odzzrqsz|{wrlmvqwlmr~|xt~wtvrssxvuvrwvqjsvxquuq{xtyxzw~okxr{zwvtrvswn{yurowvvru{|}wutuw|~qxvuwzwwqwxx{xru{xxxx~orr~or}~kt}ryjqwysywux|t~~xzzyxu~xtt|z}~y}prx|wvyuquyxzw~vtsn|ruvzu{{{}sp|ozv~w|lwvzw~s{ynz\s~rq~mm}qt}i~~zwiyp{|ww}x~s~l|mtqt|vs|z|zp}uwxz{vtjxnjy}}vvyrxxnxv|t~hyw|tqtrczrvuxs{~dytpu|jxwrv{w~nzpvxvjayypmszz~~txrvuurzin~p~{vkyv~rwtq{qvtuumxtoervtnqspupxtxu}ogv~nzxttqotquwvzspqvtuou|z|vsqsv|}qwvtv~yvvvtwvzsquzvwvv}mqmpnp|}gr}qxpovxpxurv{s}}wyxwxr~w~|x~|y|tuztx~~~x}y~}{y}wx~~yox}y}|}y|lwy{z{z|v~t|{|s~yzx{}wyzv~yqzj|z~~~z~vk{{w}{~|putzxs}{{|{~|{s}~~z~w|{yj}~zx|zpe~|k{~{y~w{~}[zy}oq|x}mrz{~zxm}y{yxux~{yu}z{u~~~~{vysy~txtysz}}}z{||m}yq|xx}{~t}}||rkzt{}zzwv~}}}m}}wwp|}lxxwyz}{w{jzyp}~xz~t{vv}tvz{~ysy{~}zi~xzqz~w|wt{zw{|x{xwx|zu{|{uzto~|}x{psqz}zys}|zwx~uyw}}z~wo~wvr|{~}yjkwyuwrs~r}xvywztzv|yz{xw~tv{ynv|{ts~y|}tx}u|}vyzzz|~z}yusyz|v{y|w{y{}r~xvzz}~|s{z|{xw|}}}tuxty|yzw|rw{~z{zz|yv{{z{~{w~}}uu|tzxr~{~{{|{|}}}}vx}~~{~}i~z^|p}t|rw~}m{zy|s~~}rvtsxi|}zx||riyutvyvy{pv|us}jy{r|yxftsv~q{~o{szy~zzufp~usw|mtl]wvg{hw}msv|xjpr{|zyzu}wz{{|xvottt~r|t~}r~~xw~~}wvz{vnytp}tqt{uyxysz|w{t{|f{w}yvtsp|pwwyx|}h{vt|s{q{yvsx|qur}{wxzf}us~ooz}~wu{lwpvlp~s}}wp}wxtwst|sxxyvsuxooxwtr{vq|yt{|y~ooyr{|vvvtruxjxzvrmxvxsv|~xuuvxuqywttyzzx|wyz{vswzzzyyosy{ot~~vttz_rx{tyxvy}t~x||{xwkvyv|kyz}}r{{z}}zy~~}tvtqw|uv~~~{z|whzywwzu{tvx|yv}n|{r}{yitzv|t{q}v}|z||{~~ylr|yvxrkp[|zl~oz~qvz~{otv~~z||u~w{y{yyrwxwvu~~p~zz}xx}wp{}xtvyshxxvyyy{r|sxvzi{y}xvysg}lvwztx~z}s|wqtm{xuty|{qtry{uzrd|xsrxqz}zwsspssvmmr~}yiwtvpuzrxwuvr|urkuvorwvrvny~{w~sjys{z}xwtrtsyotzvtmxvvsuxx|yuuuvs~rxwt|zxxswzxzwsx|wxxx~psrwqs|~gs}rwmqwzszxvy|t}}x{{xzv|{}|z~x~~z}r}{~z|~}}u}s~}xx~z~y}{x}{v}zyu}tx{}vs{~{t|}y|{||~{zvu~s|j{|}~~|wzwv||yy}~~xtx|~vyth~{}snuyr|yzz~oy~|zyx|yv~{xvvz~rz}{znsz}uvuwsy{}|~v~y}~}vu}}xzvvul}tw}~wzy~z|xu{}x|w|xtwxz~z}~{zwy}xy|~zn{~}}}|w}{z|{tz}{z{s~xzuz~v{usy~unz|q}{|{sy|}{y|zy}zywv{uz~w|qt|vxwwuz~}~|vz~}ww{~y|wtrm~uw~x{z|}yt|~y~x}zuyxz||~|{yz~zw}~|u|~}~}x~}t~y{~py{{~\~vw~uzvsj}rvvo}~}w~~n{}|~|xxykro{zz~|yx~~v~}~pv||{{}|w|}~y||z}s{}~~r~|zn{}uqizuvxtxzywto|nzvzc~z}ws{sk~guwxryx|{tp|nxvpw{ypvrr{xxwdzzqprz}ryrttnssxkn|qy}vh|ztvuuxrvvtwpvuogtvjpqup{wiywzw}ojxqzywvsqpswsyzuqtwvvsuwz}wurtw{}ryxttxzxwqvyw{wsu{xxww}orsxorz~hr}swkqwysywuy|t}}vzyxyukqtuovxqf|}x{p|ozyt}oy|zxs~v|t||u{zutyuyxxzmvh|z|m|r{zw~}sus|v{uzyvf|y{vwwsiywd{}dhui}rworkirm}qv}rswzu{zln}uy~z}qovyno}wwzoy}|tiqp}~y{u~tsvtjpxq~xwt}wvz|}lywz|zx^||xz}|yt{vt~rrr~|tx}xq|yrtu||~vzr|ywyr}s~yu|}~z{u}yylutx}s{z|~|{|~|x{y}w}y~v|v~j|}{}}|v}{w||~tuyt|~~v~|zp}zx}{vz}{}~vu{vykwow~zt{wz}ut}{t~~x~{|}{{w~z~~}~~v~kwu{~z}{wsy~o{}szz}yt~w~vi|x|xw}sh~vzxxvnz~ezvt~v|o|xsux~}qyrz{v|qf|wtqvz~{wuclvqvmoq{|ypv~uwtttyvuwt{wrntvxrvws{yszy}yqnzu||xwutxtxqszvtqxvvtv~~yuvvw{pyvuw|zyylwyz{xtv{zzyyqsr}qt~~lvs{iqx{uzxzy}u~x}|{yw~z}|zx}zzwuyortwtk~{}vv|}~{hzq}a}vz|u||uz{yxwuutm|||w|~{wfvxvtws|x~www{voz~wyyyy~z|ut{o{}{~ypzu~}zw}w~ll{}rww|xwy}w{tyrzwz{}|mx~}yz|{}{|xzxyz{kws}xv|~z|x|w~}ry~s||}|~|{u|x}nxzsn~a{s{pyy~z}{xsxr~y|}{sw|luvplr{||~hzvvytwwzxz~uv|vsyv|y~wvzui}qxyxxxxzySzuuuzpzzwvx{{qzsy|w}kf~yrpt||~~wytwwuxlq}r|xm~x}swsu|twxywqxwsktwwsuvsxvz{yqkyr|{wwtsusxxwzvtoyvwsv{}yttvv~~rxxwv{zxwvzx|tsyzyyxx~qsqxqs}}lr~u|wrxzszwtx|u~}vz{zzv~~{}{u~wvtzqs||}zyw{{z||}u{{|zl~{~|j{y~{~{{v}{~ut}||s~~}}~{z|xt}|~|xwut|~|xjww~{szou{{~xq~z}uy}~x{ug{|xpv{zp~zyxlz}||yx|yyzs~vw{sy}vzpqw|uuvus~yy{~{}vy}~}~vw}|vzwqpp}tz}|xzx}z}yy||x}v|ytwx{~~{|}|{xyyzt{w{~~~~|w~|qox{psyletkw|yv|zzwzutxczwvsvrg|vvxpysyvt|r~otxlw{yorryxxxotcx{o~nqxsz}|xoxuuqzino|unwqxoq{qxwvvmtvneuvdpstnwczuxt{mjvlyz}sssqwswp{|smlrvwpv|s|wwpsyt}qxvv|zxvtwxw{sprzvwww|lpwtnq{|eu}ryprvxrwuqw{u}~vywxwtt{|yr|{|{{i~b}|wpoxmy{|kz|w{}y{x{|x}~x{z}toz|~~~qux}|yxxysur~}|xq|yhz{jt|~xxvvp~y}fzr~uu}|y}pwy{|zsz~|xjwyt}~~yttu}tqzwu~~|w~{tx}~~x|{u}{pt~~{hv}t||~|u~{ttwxz{~~{~z{~|~q}zl{~zv||x~oihr}x~~}`wiwm}ur{{l{}|ynz}~wv}nv||}xtwzztum|rzwwyzz}ryurz|}qu{}gy}ypyvkxtnqxyr{x}|o{sxxx|w{y}~tgv{t{wx~q|{nwvs~u{rwxwr|zpzyxw|wxny{yx|v|uz{zxu}z{z~stw|wxmzyv}rvyx|{|vvqn}yzyww}zx}xuvk|x|vw}|rwzq|yhozzzr{xuz}q}~n|u~zuyyz~z|w~yy|vzv~yyt~}p|{}x|zzuz||~m~{yyxp{|rz{{zn~y~|t|nxwnf|u|yyuiz}xwqt}|zvpzrk|{|{zx{{}~pzy}{~q~{zx~r|x|pvz}zvztmxy{{jp~i{|vv|rxz}uyz~tyu}}vvulvw|t||~yqtswtsqqrx~ywx|yxp{u{xyzz{}uuxy~rx{{vy~r|~vv~w}~y{yy{y|vr|zxv{xzvyz}v}y{xp~wvw~||}v{{~{zy{{}}|ttxvz~q{v~mv{~y}||{ww|{prv}ytmyxoqv{xwyt}tpyuquhyx|vxysfykwxxt}wb{vrr}l~vvqx{yoyqnyvwxazxppxoz}}vxu}}rtsyjmru}wd{wwrvtr|rvvtuoztpesvpnmsp}ufyxyv}ngvpzwvuppnqvorzspvutuqt{z{wsptuz|rvwtw{yvuyuxv{tqv|wuvv|nqlpnpyir|ryoovxpxvtwzs|{xwxvxsxwyztpzrkvpw~zwvu|uyvn{z|vqvrfqxvwotrywt{qh~swnv|{otqswwysvcx{n~o|qxu}{~vyq{nqtszimo|to}yrwqs|ryvtwlrvmdvwinusmzwgylxs{jjvmyztssrxsww}zrmlrvwowyz|wwpsxz|rwvuw~zxvnwwv{voq{xwxw}mqosnr{}_r}swrqwyrwuqw{u}uyxwwtpu}~zwspyqd{vxxxtzsqwxzw{ezw|uqyrk{owuwr{x_zsq~u|mwvqv{y}oxqzywja{wonsyx~swrnsurzioq{vl~vswsr|rvttulxtocrvrnqsouixsxu}mgvozxutqpxqvtxysortutpu~z|vuosu{}qxvt{yvvouxvztps|vvvv|nqosno{|br}qxtovxqxutwzt||uyxvws{po~xnkyicw~tywswxqzu|pxbsy|uuxtbstxxp}y|s{urx}o}vsrzzwnurz{pzwk`x|qmqyy|ywrtotsyhmpvvf~}txqumqypvustkxvpdstinpspsiwxws{nfwmzv}vttluquntzronwrunsrv{xstsxv}pwvqxyuvtuxwwxqszuwtv|mqoloq{}fu~nwhpvwswusv|u|xwzwxrqg~syyvizrovuwzuqqywzvrzx}vsxrkyszxvwnty|~kzvqt}jzywqw~zpvrr{upd{uro~q{|vvoyvtrwkmqy}wotsuorswwuurxwqnuulpwuqwrz~{v~plyrzz{vvsqqsxpqytrqxuvqt{x}xqvutwqyvryyzxx|uxyzusw|xzxx~nonsor~}ms~rxlpwzsxwrw|t~~w|{zxu~yx~|t{wxyy}tux~t~z{|~z}~}|yuv}{{|{}~zukzwzyyiu~vry~yxxx}szut~z}t|szxz||}}~~~|n|y|~x||{w~~xu}vt|}xwq{yxdt|~y{tw~{zerwj}{ywrx}x}|zxy|xj|vw~x}|}{tn}{tpxvv|~|~{px|~~y{{v}|lz~{|~~~|gv}t{|~{v~{urwwy{}}|}z{{{rzlz}zxr|u{w}|zvx|nzvyxv|l}kz|wo|}c|zoy}w|vxzv~~ntxz~}}vnzv~r~~ozzz~yr{js|zi{two|toq|{um~{xuzv}{|ztj{tu||}vst}zt}wy{w{{}yr|wur{}~wpx{~|yqu|xxyyy}wz|wxwzxr|oxzxww~}zy|swuuuswz}tz~zyq|{~w{|{z||x{zyty{z|v}~{w|~}yywx|uu|{|ryzyy|~x~{yzu~zyy~}|}|{}|{z||}}wxzwztyw~wv|~z~~~xy|nkz{szk{nmxvzuyq}wrvtj{|mys|urysnr`wuwq}tfzsqr}iwwsw{yozquywub|voovoz~}qwszuuu{inq|}wb|vrvsq}rvutulxsnftvsnnsouhysxu}mfumyw~utpprqvnxzsoutuuptzy{vsosu{|rwwsz}yvuxtxu{sqt|vuvv|mqirmoy~jo|rwpowxpwvtwzt|{xxwvwspz}v}}zbszrR|{s|w}vwt[|xv|yv|yjr}cmwzxy|yd}|kwyznzk~j|x~y{yxt}|~}pstk|y~{mzuvywj{vx~vz||qzjhvz}xyzw|x}syw}w{rmtq~zt~vjq{w~txsyZy{iavyt|vHr{~~xy~j~nzzr[zu|mxqr}~fx}{{u}vw}xxxxn^rztjxlv~~xlz{yryx{~zxtt{m|t{}zwwy}zwjpz|{~yvyqtt{vwixsqzwuroyywsvzcvx|ur}vzr}uvp{qlvqyzzxr~ko|u~y}eyz|wuvti|mwxxxswnzyu}u}lwwoy|ypurtywztc{zqo}pz{~}}uyuytrss{jnr}|va}yzrwtrzrvvuvmwupftwmpptovezxyv|nhvpzxvtrqtswtv{tpnuvvrvvz|wvptwv}tyxtwxzwvqvyv{wqt{xvww|nsstoqy~jr}susqwxqxwrx{t|}wxxwxtwoswumjyikvwzxzpxvpyo{t~e{{|vtxsftkwuwo~zn{uoro~vwow|x~ovqszvqbzxpp}pz~}mws~vqtrzinp|}w`wrvqqxrvutunytofuvompsoueyzwu}ogvnyw~uuqoqqvvvzsopuuuqtxx|vtpsvw}rwwuz~yvustxv{trt{vvvv|mqqpmo{bq|rwpovxpxvrwzt||xxxvws{{zy|sz~{|{}xr}|~~r{{{~u}~y|tz~y~zz}z~|}|}lzdn~z}x{z|}~~}{r~z~||{|w~}z|uu~y{t|{~~}y~~}~z~~~z~y{~~~k}wzvz{ux{p|{xsx|{|~~|{~{puzw~|t}wy||tzv}|}s{~{y{y}y|stzsz|~w|~|vy~~{~~w{{|{|yx||}jtq|vvvwlzvov{tyx{uvt~uvrjys{vxxrc|pxxxro{oysqs|mzwunx}{owrv{u{{sc{xrovqz~~{wsurtqvknp{}wetxrunr~qwvtvrzvrmsugpsurwh{}{w~rjwrzy|vvsqurxmnztrqxuuruyv}yrtuvw~oxvs{{yvxvuxx{rsxzxxxw}oqotpr{~mu~qzqqvyrywuy}t}~wzzyyv{zq~}o|}|{|}xw{t|wyyz}~{wyxz~}}zx}~{w}}|~x~{z~~y~{t}|}ut~ysz}|~zvzz|v}|ywyu}jwjy~{ut}vmwzwUt}}syVrwy}prfqzf~yyqtw}xzp|{wuwxvoyy|~~}~z~mxw|nttpxoz~}ekr|xoyyt|~u|xfu}~~tz}}}~yx}|vwupx|wtjyokyxvvzv{vqxu~xhyy}urwsiznx{uwo~zoztqu}hvvow|y~oxqxzv|pazxooqy}~}txr|otsszioq~|wg}tqvsq|rvutumzspeturntsotlyywu~ofvozw|utporpwwwzsppuutot{y{vtpsuz}qwwt{yuuqtxu{sqt|vvvv|mpjomoz~cq}rwsovxpxurxzt|{xxxuws{qxz}rvvtd}zwx~xjx|}oyf{l}wyo`~c{w~yzi}dt{|ww}t}x{nyzzuuyymz|xqwxxzvwhz{zua~~du{|wsq|}|nv~szu~~m|}p{w}nm{ws{w}yyizzxnvywzyzu}jx~nvu}w{||}{w~~}xu|tzzs~~zz}|||}zxxz||}~ru~j|kmyw}xwu|uxzx|}v{{{k|~{wzsl{kyy|xd{|x|s}mzyqz}{syt{|{pth}}uv~v{~~zzrxt}nstwp|x|uzzv|u}yvxttztjz{wrrws}zq||zw}oo|qz{yuvsrvyw{|vrtxuytzy}}{yyw|{~sxywu~{y|~wz{}ytu}{xyy~qtzwqtzkwvyqvxywyxsz}x~{z|yzvye{}wstyonvpx~zt|u{v~w|j{zwuxsruxwwoozvu{s}m~vyov~{pvszyy~rvfx|pnqyt}~|xs{vvszjq~p}uqx}syur}sywvwoqxnhxwiosunyl{tyt|lmvmz{~sturwtwq~{tnrswxpw|z~xvrtz|}rxwuz}zyvxwxy|vps{yyxx}nqxsnr}|ot~syoswyswusx}v~wzyzwu|v~x{xxw{x~suys}z~|}{z}|qv~lsww}|~z|z}|xj{}u}}{v{|uutzvr~~~{~}|{|||{|zzxx}o}j{~}n|{{{~u}zz~}y~}|v~{swuty{wyxqwo{zyt}q{{zsxuv}|ytzozv~r{|}~yotuyuupu|r~}wzxxzv|v}{{{xutw|yvv|{twzx|~rx}u|vy{zz{v|}yvxzz|u{|w{y|r~xwvy}~}{|z}zwy|~}}tuutz~~{xsw|~y|{{{yu{{|~s}zy{}uk||xu{~tush~{}uzzuzz|vvsyy}zv~{y}w~o}|zzhtwwuwp{s~yvzwqsyy}sorW~|pr|qw~k{ryx~xz}~vwz}}z~xvxz}xv~}~}||z|~r~~}~xzt{{po~ot|{ztpuyw{{z{~{y}{|t|~{xvwrvrr~xm|{utr~vxtzfq{}t{sts}~|~fqxuj|zyrvty{xryxwguw~r{|yqrv{spwyt|}|v}zrw|~}}wzzv~zmm}~}|}{ds|s{z~{t}zrrvtyy}}z}~zz|z{|p|xhy}yutn}}{xvq|ytvssw|yytxtpxkvy}xqvlrwpx|u{tozzu~hzunw~h{yvsx{yn{r~zuqd}xvpxp{{~~yvwfqvvvnnovxwht|suquuvuuvnvuumvs|rptwvzzpv|zy}rn~ozy~wvuvwsztquwoovsvps}yzyprqw{qyvsqyzvzpu|z|uqu{xzvw~qrpxpo}zotryrqvxr{wux|}o~v}z|zu}]uv{{qwznzqx^~wz||~wh{p|tcxuyy}hzthzqyzx{~|z{|{t|pv~}x|{{{wy{{|}smywzv~vynhqz|w|{oksrz}}ucj|q}i~yjoxvrnvz|xkjtzvixvt|x{{f}{~}|~{w~zo|}{~wx|{}z~|x||zu{u{sy{w|z~~z|y~zy{|{}~z}ir}zoptzn{|yt}ysranz~zqyoy}|}l}zryyy~uw~|w}t~s{}}mxsmzt}qrytzuxx~qz|z|~|}rsslvzpr}zy|}xd~zxvwxuyuvw|xu~kzzr|zhtxs|rzo}t}{y~z{~~wjp~}uz~pnnZzxi}ny}puy}zm{rt~}z{zu}vzw{~wwq{vw~t~t~}l}~zy|wx|rzw~|zss{vqlvv{yuyvq|vtwhyz|xwzsa~ov|zx{x}}^|vqs}u{yvuy|{qsss{v{ke{yrq{p{}}vwtpurvmmr{~yq}ztur|u{sxxvvrxvqlsvprsvrwoz}{w}qkys{zxwsrosxluzusuxvwtuzw}ysuvux~sywuw~zxx~xzxzwsyzvxxx~pswsqs}~ks}ryhqwztzxtx|t}}v{{yzv~rm{}pys}x}|s{{zywy|x|zr}wzuvtq{ywyt{z~ozywv~p{zzqw~s{u{|yw~vl|vt~nwz~}xnttytwns{ry}wxv|vyvvu|y{ywt|svyxvtxys|}x}~{~ru{s|uxxwzxyww|xtxyyzsyz{tyx{}q|xvvz||{|zz~|xuxz|~|{rstxrwyyw~nuz}xzxvyxv}{yyssy{xm{sovy}yx{w{x|uwwnyw}vuutl}syvwryhytsqi~uwow{yoyqqywxobyzno|qzy~}wyrsxvs{il}ry|tmurvqp{rwusumwtoeuvonpsoujywwt}neu~nyw}utqppqvnw{ronuvuptyx{wsptv~|quxvy}yvuuuxu|rptzvuvu{mqhsmpxhr|syxpwxpwunv{t|{wwwuwsuov{}xsxrlxw|yzwtxvvvjw{~{uxog|q{zvyvu~{i{tttk{xtsy|zqvsy{sod{yspzpz||{wtsrwtump~r~}xk~utupt}qxwwutwxtmwx}tozwryqx{x~ro|r|z|wwutssynrvvtvxquuu}x{{qvut|pxvsv|zxxxvz{zxtwzwywx}prprpq~~ktszlqwyszxpx}t~x{|yyuzzvyvukysqw{vxzvvu}uxu{izx|wwvtf|rvxzsxyozutt{o}xtqy}{pvrwzv{|sd{wrp{sz~}wwszmusxlmq}}xiwzswrs{rwvvvqzvqjtvnpsur}wky|zx~qjxq{zvvsrtswruzuqowuvsvxx|xvsuwx~qxwvv|zwwxvyw{uswzxxxx}orruor{is}syppwyrywtx|t}}xyyxyu~{u}{}|~v}tyvs||~{zz|||}~}|v}x}~{{y{jzztvevtz|~oktzr"{pdpqwwq{s~zsxy{ury[z|l^zszssbe}w}{rn{|wx}vpu{kwm}y}yww|vt{vet[~qjzr|fwnez||xz~~~wy{v{~sz{}y}qztx~}}~u}}~~|z|}w||}vxr||{~w|~~{znvtwus}zzu~v{y|}t~~xt~~~}y|s}j}zwk}uy}~|vvw~~xxw~w{|mtypuyypq{wnw~~~{|vzu{~|zvw}y}}{tx}xm|o|}|{w|zv}|}x|{~wyysu~}vztoz|zy|zo}rzvp}{y}ny{~zxxyxvvtxzq}|yrsw|tuuvs|z}{||s~x|}}~yv}|{{x{s|~xz~y|y~pv~}|t}{z}|u|{{txwz|}||}}}xx~xz}zpz}~~{v}}{r{t~hj{|xt{{zqz}fmvyq|p}p|w|~{my~~{~vy~~y~wz~}v}zvxiynxzyxvzw{xz~sq}{xszyqtmvvplz||yojz}m}xxtz|ywzz{{xwpmf|zuu|{rwwpwswuo|}|wl|o~yjvxsu~|}l{tz{yqw~s~zr}~yr~|l}|w~|y|yw{xq}uyy|uysx|v{w{yv~~xthwl~rwtn}lvtxzt~{z}ry|uzvwizkx}sqrto~up{i|{mvy}x}xqsz{zw~{tvttx~su{x{ty{{wwyuxxy||zwty}tux~|p|stuxzt}yuwtzy~q}x|yuxtfzzzyx{{^yyw~x|s|yxux~rxuxzxw|wi{xs~py{{~|ypttxuxmq{r{ws~{vyuvuzxxxstzrouxxstxq}u}w~z}nrzs{~uvvv{wyu{{wrwxxzty~zvwxz}s|wvuy{{ytzy|{{ttz||{zqtu}rv~}uwuzkty|vzxyy~wu}|}ywfy}z{xp|ztu{yul|}}u}}~yzwq{zyqqz~}u~x{y~s{y~|vx|zz}}xsxy~zy~px}w~yptywys{~sy{{}{{z}z}~}yon|}ww|uyjo}{rzs{}s|w{~|us{~yy~x}}uxy}{}vzxwvxzvxo~zo{~~|||}vy}zxx}~xq{s}wv}y|}p{v}ot~z~zzyxm}uzzw{|Z||z}{}tw{qw}s}u|{ytl|~tpv{z}zup|u}mwzt}wm{w||uw{yzzrp|rpzzruxq~p~}|z|mtyqz~wuxwryz}{}wqzwz{tz~zwuw|w{zwsx}|yzz|}{vu|}}|{rv|wpv~vxx~ov{|vzyxzyx||~xx{pr~|~xzww{~v{z|}x{}s{}xyui{||{{~Y{{zzy}xy|{yzv{w}zqzvp~yx}ry}~zrzz{tusw~s~z~|{y|u{w~{{zvuyz{|y}|u|~~t{v~yz|{}{|v|~{xx|z}w||~x}{}zsxyv{}}z~|}}yz{~~~uww{|}{yny||}|}{zw}|ww}}}uzuw||w}|~w}~wzumz|~tz~y}zyvq{|~wxx}yz}|v{v~yy}r{}zzosuxuyr~w|~{v}~z~~{ru}xyusrk~|qu|~uxz}}|vzz}w~x|{uwz|~{}{xwy~xz{|s|~}}}}x|{rzy{v{~y~ďttzs}}~vv~{x||zx|sz{y|z{~{{~wjv~}m}~w|z}~~xyr}o|xpsntswqsv|tu|xwwwl~^}}y|y{p~zv~x|ky}}~~q}szvzow|u~}m{}xvw}|~xr}x{~z|~uzx{~ynzyxr~t~}xr}w}s|~ywww{{}|{{mxe}|zn{~}~z}|xyv}|~{yl|~y}vzpxpu}zx{zxn}~xwvqzrtlr^}|~zxz|}{{|zzvw}w|xvq~{{rrr~uz}r~{w|y}ttzs~z||{~{||}{}yz|~z|j}wruzw~mxsmyrztyyy{zst|rss{eys}vxvse{hwxyquzmzsru|j|wuqw{{pyruzw{zkdzxqn}rz{|}~uyq}ttrxkop}}wbuzrwtryqwvvvp{uqirulprtqvlzzzwrhwp{y|uvrqsrwst{tqtwuuru{t|xtrtv|}pwwuzywvyuxw{srw{wxww}oqloor{~ls}r{sqwxqyvvx{u}|xyxwytqjv}{ywfypmvxvwwrswz~t}jpx{vsrwgufvuwsx|{ssvygxssu|z}oysutu_z}uooy|ztwy{ztvszjtiv{wfyuuvpv~qzvsumyvrjpynqqsrvg}uwv{nltz~iywutyuprurzsrosxrynx~zyyytvtrz|pvvmx|y{z{tw|utqr{usrv|spjokrxgw}twoouwwwtvx~u{yy|xtsqwt~}|umype~v{xu|tt{yytrjuw{ztqpnzkt}uuu{yqzswx|g~vrs{tv|muuv{k{{_{|snmx~{}zyutuwrxlrp{ug{vusupyw~nvuuqywpgsxpnxpiwhwuwuzojv}oz{|vtsnquuowwopqxszqx~xw|yu{sou}mvwk}}yyyuux|uvsq|utxv|mnishtxmw{tvtptxzwupuq{vy{wztupqy~xssyunh}x{{nxmrzzwxjuz|{rxykzppwxq~u~hwwv}y|qzsqvw}m|x{vtq`ytpmx}~uwy|oyuxiqmx{wk{wpwvw~qzvsunwzrhn}wqorkxe|uwtzljqzsy{usyossvl|woouwrwlww{swwrot|nxvp|y{vzuwxxtqu{usrwzprsojrz~bs|vxpmvwvwus{}|v{~s{|sur~}~s~y~usxxyvw|{sw|}~~||}|}z{zy~~~}{xsz{}}zo|}x_|zpxaxguvvzw|}znsytyqvtpzt{wuxsixlxwvmvy|}{rqol~uxpv~zpxrwyw~reyypm|tz~vrvtszipzow~tox}wtvsq}rxxswqvwnjwvinouo~ym{syw{mlwnyz~tttroswm{zsoxuwwqv}y}xrrsy~}rywsz|zxwwxxztru{yyxx~nqmqmr{ou~s{cqwyrwwwx|u~~vyy{vuz~|s|r{|wx}|n~~}yp{npz}uzxh{~{zqz~{{~y~v}y|~yr~~}}{mw{zzjwmzv}yzuys|z}{{shll}no|xx~uny{x|u}w|vv|r{o~}vy{{xwztz~{z}mu{~z{orum~swj|wxx|m~zv{nx~}zx{zrju{}ysiy}|gu}xuz}vpunp⍠nyYksxzhw~ocUmp~du:ɸL{{cjw(Z횚U܉VAqm~mEnn|R+~sեV^6pptSpGF~'ѕP+)@:0q>y:P43DEf2HD5H?% .;^RzZ|JhspnUVt5/i&Y=( יPai|72.>qB%AZ3]Y2_TsoQ A:DmcFz&T=(YTlQfXIEFS8mcaQ2KQXsgJ2,3DX<>JAlO[v|eI^b,ENCJFddSC[ZXM:Yr; 4AKr_]LgP;FKR8<:Q4dfRJg=Y;MW +-XM?97Ӥ!QcV_k1@R5pPPLLVs&L[Ap;?& :}PNdq:4} oECm_yrEn AdIiV,ZXƩFW^Q+f̣!eZ|RKClajQ}Y(msMIFK;NnݟN{c`~Li;9Uzc`$CRHdgtx?yw\K`Qcj1oXdaGvp>b_JW4FpH6TPzK-Z$ii?[`ec`hch_dflfY]h]cdcdef]`^m_cpfifcabn^^hjjjj`egnege`cnUdm_cYeb_gZdXe`g]cd]bfkdd^b__]effi]b_hh_bchccmieg``gaiffcXdghkffac`[]bgibaWjg]Thchfafe`kec`Og^bebd^_dcgbdhah]cgihic_\\ibb`^[_]kjjblUZpaggceg`b`_iadla]edbabcZji_`ZYeb`bl__cafn^ae_^i`ff_\eedq__]bccfgffb[f`flcegafdjVkd]Ym]^h_defdZfd]dnlRfeb`bhdk`Ynbbsa`mlgclimdjihXei[bf^Vo^^W\jd_mo]iZde`^f]aki\hlhekbfdod`]o^d[f``WcDfb`V\k_bl^^oc\\nT[da[jctcch`q^[ch5_cgkidmbej\l]bd`fabecd[cb_ce^bi^ahggf]mbcp`a_accZk``a[jp\cafmb^mb`baej`cgWcp_ld`cdfcgc]ibhik\aq]g`\bil_e`cTc`dahaYac]gfcpZdbcab^gn`^^ehfdoidaa__ke]df[chjadae_e\ch\bdi`Qe_c]`[aam^ib]^^coh]g]d]ea\be`V^ie^bdf_i\\fffae[l`efjdnecd`c]\degYZai^^qg`gc^`dbd_X^b_haw_`ci^a\c_cXacifd\]c`dbeihl]fcd_lckj[c`mej]bcdfe]bm_blYedj`jgdbfkh_iae]fZaj]Ydgnelc[`ddeckdafj^cbjajfgcm`caf`ccehgmdijbahddj^`b_]eh]baei_g]^_^bqfc\ab]hf\ifcoi[jgj^Wipc^`\rgZbigggbaeifj[Xich[]\n`e\`d\gbfjnbej[cgbdc[oc`jhhlTeg]^lgebdbd^ahbf_f`d]c]f[ehcnb[`aRU_efj^ghiZbcf]_Zha]g[]dccfecj[bjeadf`ajcaObc\ld^]d^cfbiZU[gcfd_odaf^c`dRb`jZcha[a`ea^[kg`^]e`bbem_aecbb`b]hg^eabd`befZhcb^hgcbb\bY^de`bd]gcadcbeb[bjheda_cddbbccf`cffdhcgefj^aiifg`\_fb\_d`cjif^gkjehai]kkbndhcainV`YeebXigen^had`jefhbcecb\]h_jTjgck^ajgiehf^j^afbdegldoagdc`dfbh\\`aifkdg_cach`acgehggb]a[_a][\fbe]ji^`abdi^\abbah_bb_hcdacnfedaf^dakhg_bf`g`hh^jie^dng\gjafa]l_c]f^Zk\fd\[bb^_afie`\_kVia_`gr\heb\i]`icdk\^plia\gcZbhdd\abt^d]m^h__bfZpcd`abgdla\fcf_^aj^baefbdmae\`ceh`acYednkbd\][``iY[^e`hq_Zhcjeecea]da_]hqham_]fge_ee\\bZbbrcc_ZfZc[beg]^lcch`e`apdm[e^aZa^g\gabami`e^g^_che_`di\_do`ab`hcb_i_]sbhe_`geafj_c^_`add\hb``aj]d\fg]`^hbifk_`gccgcbb\hcfd_eddbf`^bdlej_ghdcea_f^d\`dd^_ac[dbeab_d`bcfbghmbdeef`ec_`bcjgb[bbfaj`bceb_`ihfeb\^cbf^ia`b^d`i_e_gaec\hbihcgYca]_`Wc_bc^bqe_f_ebdh_idhdhggc`c\`kgibedb^bbckeh\]b_``aa`ccdgecdackdcl_e_fehfkc^fg_^f_afe_dcb`aZ\cbbcecfacgg_f\hbd_bbbb_]_dibihg\b[gYa_b`]aic]egdedhjb^``cdcf`hg^ab`af`fda\bkkgXiica`[dajhakdadc`fg^ah[adbgddf`hlaaj^ade`becbddmtdbM[jdpbeb[__jcdhf_gn^]gkg`_^g`fcad_ab]\`ec^dbagedcc_c`hbe`dica_df_^^f]`\cf`d`iab_]deWficbcbigfcc`g`_]^h`bgc`a_hgdZ_b``iia`f_`deoacag]jdflgcfkiihabgZUilkho_dd\^beaih\bk`xkcbZkf^\f_[f\dd_\eafae\glfYihafZIf]ghbkmaf^pfc[diZZfc\f_hbbgi\``eii`^f`Yf`ga[^lgo^cc``ccaa\cedniYbalacc^_a``Ye]^ebdbb]kZdej\_ca_Yj[fa`fa`jd_cgkjcfa[gfbfa`ebc^i\ldadi]`bjdbj`ffbc^ii\`jbdg_cdedie`cdg`a_fejhgdf\cjNjaf\ehfeaachb^i_\_eeedjdfcbj]fige`e_bao\k``ce]hdf[h_e`^e]engabeZ]cb_bba`cfhfYdc^_ddedeaajaidabagd]icZga^d`c`df]iic`aih^idbe]_ideddhbckiZ_fa]dhcd_e_acfl]gd\gbcbdecdkdoje[eiacaa`ob`gfcgc_`Z]ca_d^ai_cngfb_eelfkbbdhgbcg^lp\acaaZde]kZ``gc[`j`_faebb^ee_cicdfbak_jk^Wecb`iZbjafj`e`icg``aeade`c^b^f^_ecff^afbeffd`bec_`bceceeccc`heehdfdccccgf``aelbc\cfgdk`bcbaf_daccadfeedf_daffdd`adfacaaafdgbdeb_cef`dbdcc_bddecbfb_^f^c^bceegcbecafdbk]bd`dcdd^ccbeebebc_cbe]ca`fgbebfeee`cdbh__cg`babfdaafehbgfccabfedababicb^d^ccgeaaadba__bccbbbcfceg`f_c]cebeacicZ^ebhi_dgg^e`dbhfc\ba_gbpcd^ceja`gfe^_eldhikdidjh`id^b^^b\f]nac]degagigfnfa_`]fabZ`gb]bYab[aichb\]_ca``djab_heee]__l`ejX`]h_cicf`fdajfcehcahbaXfbf]jh_acbl`c]gfi_b]f]dg_d_bn`]a_de``h^]jZfgd`f[ab`]ed[jd`c`\a^ceglgc`efed^defg_e[^fdleZceiea^hca]ddicbeahj`a`iddl_`ddggdidc`eh`jgeib\beedcejmd^d_`[^je`fb_[kg`^a]^k]cccbnmdgm`[a^cc_e[b_cXae_fcbd\`ecej_bbmjb]_gbbj^ch`acmb_mgjkjcddgjane`_ghf^c\_hib]_gofahci_ebcfdeSaegdbbi`d_ceb^edcjgadeg`ab[ek\pdcc_abffjcec]gaWbc]a^fV_g_b^_mg\hdqbfa^Zhkja\cl[]Yba_d_aa^fgi]\\]dpakagfcdddddcddcddccccdcdcddadcedcdcccdccccddccdccdcdcbecdecccdcddcdcdbcddddddddddbdcdddcccdddcdccdcdddccddedddcdddddccdcecdbdddcdddcccccdcccdccdccccddccddddedcbcdccdceddcdcddddccccdcdccdcdcdddfedddcddcecceddcdbdcdccdcdcddeddcddccccddddcdccccddddddddbdddcddcdddbdbdddebcbcbcacabdfcbbddc`bbbdadedfdbbddbccbccd_bcbccbbeccaccdbcbbfccbbc`ddccedabdbddacbaceb`cccecbcaadcdebfbcddbddbcccb`dccbdbabfebbdbaacebddccbcadbbcacacfccfbcccdbaccbabd`bccadaebbccedbbbcbbccdacdabfedcdebccbbcebbcecaccedcd`babfcbcaaaddbbbcdedacbcabcacaaabhd]j]ece\bagfedlqgf`i^eee`_cddfg`bje^b`fqbc]^ihi`ja]`lWX_^b]\akl\^^iiddbeg^gacZ_g`kccinh]jg`bZ\dfb^l_fecamaa^b_cd_lhafdafcfnchZk[e`j`a^nc_gfW`hdge]ea_cnh`lfd]hff_]cicjcXdcjjmancah[e_`c^_UelbjbheX^dhd^acieefd_h[ideedcpic^dbcf]ff_Xfgb`^bbeihc[^fXZ]bYh^lficdccdcffccbdcdbdecdcccbdbcddcbdcbddddcdfecddbcccccddcdcbbabdcbcccccdcbcecddcbcecbdedcfcceedecbdcefbbcccdcccdecdbdcccccdbcdddcddbcbeeceedccccddbeddcecddccdecddeacccccdcbbebcaecbcccdcddcddbccddbdccdcccbcdccdcbbceddbfdcddccdcdcdeddcdecbddcbdccdcbcbcbcceecccbedbd^cdfccccffa_bcaeeda_`e_^g_dcbcfhdf`cbcbgdfgffd_^cfee_jh`b]_bc`d_`d`ai^agda]bfhcfafe^ecc`gbdecehiaecacdaebccgcgcehdega]fjdbb`cZfdggfd^ga`ffcffh][ed^cdelZh^[deabbdceabYaffcebab[dcb_ibedgha[gced_bajl`fga^cgedega\idde^gb^f_dcdek^dac`_`^`_adb__cc`gecfecef]c`hcbbbcabbccbeebdcedbcbccaaccbccbcdbd`dddbbdcbccdb`cddedcacddc`cbaccdaaadbebeacdcbddecabbbcbbcccbcdacddabcbbbcccdaeecdbddbddeecbbbedabcdcddcbcebbcdbcaacadccdcecbceaccdbcbacccebbbbdccebaebacbcdcebbcadecbcccadebcdcdcdcdbddccbbddcecacdddbcebc`cccdbcaccdecddbbcbcb`b[Zf`ef^e]jamaafjfeZebgoagcd`^i`eYbXhak^egiTiciXgl]^jhidbn^_daeedc`ekia\icYc^e[d[cc^ddgh[cfoefa]^o]_cb[gdltfZvdhchcgdigb]cefc`f_]mfa`eccbh]ge\ikelefd`_ch`f]hedak`e`^^lhefd_niYnc^befc`fdX`\ilahied_`l\cg`e`bfcfiYf_dj`b\ie[f\gagW^^abhdldhee^bee\se_edfdeg[^`d^b`iil_cbaccb_ec``dagcc_`_i_k_bccebdgggbeg`bcY`ec\ijiVjfce^^^b^hgcf`_acaaadg\^]d`ccgec_bc]hch]cefh_`_fbgca`YagUb\^^aaYie^i\e[`ga`ebeaa\^Zcbfh_gem[a]b__n\hfdf^``igie\chkgc`\d_`a]idfff[bidig___ij^eadb_becbibiagpb`fc`ac`j_]c_haf\cg`]biccbdecchag_ea^d^a`lbhegccccccccccccbccccccccccccdbccccccccdccccccdccdcccccdcdcbcccbdccccccccccccccccccddcccccdbcccccbccccccccccccccbccccbcbccccccdcbccccccccccccbccbccbbccccccccdccccccbcbcccccbcccdcccccccbccccccccccdcbbcccccdcbcccccccdccccbcccdccccccccccccbccccccccccccccccbcccccccdcdccbcdddddcccbdbddccbcccccdbbdccccdcccccccdcbccccdccdcbdcccccccdcdccddcccdccdcbdbdcccbdcdcdcddddccccdddbcddecdcbccdddbcccccbdcbccceddcdccdcddcacbbcccbbcccdcccdcccbccceccbcdcccdbdcebcbccdccddbdebdcccddcbbbcccdccedcbbccebbcbcbcccbdcccbccccdbdcddccccbcdccc`befa`[eag]iYddiWdcd\c`jbgd^eih]j^_Ze`hgbefacd[bgijX^hd_ckZ`]hheidZakabgk^lihjg]fdgl^bdgdbd\`\_jfn`cchld`_fiqcdR`zjl]bb[aUZ`_db^\cblghdncahcgefggO\fb_dbX]edaa[lYba^gdelbXagd`ki`ih_dbekebbgccY\dfc`bed^cdd]bj[biabf^`cf^g^fnic^X[dbal`kf_jchedlga_pefbf\`cobe]bba`i]af^beh\clSdZh]d_mff`^lh`e_f\fhbeh_c`_a`Yd]^gga`ff]hbae[^`\iqhcaaZafe^gcjf_[g_iebccVcaddjlfad`\g_ga_kdac_df[c`fZghZc[]f``cdi\hafcbae_ei]]g_gax^djhgdda^adf]`][]onmi]gbj]ei[_gdcc^jh_dahmbih\bcYg]i`^h_\\c^ibjlbdehT^_dbU^`cxae\geea_me_`gibajhaeYYb\aagfbf_hhcilcbfg_hcfcdejd^fj`ecbcck\fbeqm^_gl\ec`^h\gZif``eZddakhi^oihapd\accj_\`kifge`_gfaccfcnbed`a\`abeeWghkdZ\fijc_geljnfdacjfh_chcgcZ_W\l_kg[fe``cb]]kdbbnbO[be\h_j``_X\gXeWfbfekben`^]g`dnocbZeb\edcegcbb^hb_fea]dcfaffe_caq^ciZe[g^eecimdWZi^f_ij^^gi_`[bcdj[ciac^`ch[_d_bd`g^ngb[g^jdje^begdap_biZe`f_ajebWdj]dbff^chimbbg`c_aghjZ`ecdidh]gjYc\Za^_g`hadbc^gfkioc_ejef]c[jkkf`Ydbmeocbc^b`eifkdd`cZc`eabhbddY_degheggkgeafhiib]i[_db_cbfcchbcfbnb`_ed_d]b^bTb]bei\Rj`ekba`]a_b`dkm^fdcdefcgdhaedbYadebc[a[d`dl`ih[ci_`dg[bgf^]^f]^b`mp^h^afT^gi]bf`lj_abb\Ycbf_^cagbhehfg_ibcdaig[jg^ejfdeecded\gfbacgheecm\e`^fcheijcd_cdc`je[]dh`\dfcde`ab^hane`c_lde_ibkcdge_jcYfjX^`_a]]af]fdff[``]ag`dlsbaadeg]dmjZee]f_ldbdhhi]c`d\jfY^dnmeemXgZenh]eibdagcmeeg`f`ajdb`ebdcbabd[le_dfggcdaekdd\g\d`[`^bcaVccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccafcbd]be^`fdcbmbef^j[```aadcd`ecbag`_`dbhj[l_ab`fbecfafdd_`dc_gef`ebfbc_d`_\biebcgcddefcfgdgdkifjdhed__gea`cadf`bf_hi]gdbdabc_iae^_bgbde`af_egd`i`mbbifec_hca`ddledajbaecegh_egbcjcc`ceadiiabcbb^ifecgh`beae\eb_i^aY_`cd_aedhge^\_`ga\`eb`fja[daab\lag^b^_`cb_^gfe`cifddje`gd_agab`a^f_baZYggmfbh[[d_jcj]elhehab^c`fgdjjgc_cdla]^`_e^^ZaeZ`agbd`mdfgb`_gd[ii`^bbfdh]^bheaZkhg^cVjefY`jaebbbhg`]aUW`cjeagXadcflg\gGh^`_abdcg`bf]b`ch\\]Yf`f]ff\cgfdbgidgjggac^[]d^bd]dX_[ghe^ehna_f`f_`ia`fgbg`afiZ_\idgl_W_dhg_^m_a^cf]`i`\^clc`_\h_jc^b^`gdh^gbkldeeYd\fbh`d_g[a]ljk_aghadeeddfcbf\[kga`Zbed_^ehjkagc^bgcifdhf\aib]hdfgaedc`[]gg`]cf\id`f_d`bcgcabieje]]_]`ag`\aZbacacflc`]_\bfegcbiac`^abf^bdd`eZ_gddadd`[dfegemciZd_`jcdm^idjfa^^^dc`cgi_\cfcg`nba\`b_hbi\debedgg_`bm_hfaj^bgf^nf^b]g[f`b^ac\nkfaahYjmd_leX^df`i\`dkd_d_f[^rdbh`f]feiZfhgdghhcihacgf\`gg^mo^e_aZc`k]bekhabg_feedd]hXndXg_Zd_W]f`a^bah_^fchbbl]dcd_ffheaYhafghfi`_djroa]copafgaKf][\fhcbfcecaj`bi_U__a`igheaabeZ_^dcafk_gaf^^Td_kec^chf`cchf`fYcbg_hgbdcjggd`cikdd`icf]f`Y]cbg^k`cZbg`n_jZg_ebcbccbcdcdcccccdcbcbbcbbdcdcdeccccdccbccccceaedaddddcccecccdcbccbccdcdcdcbbddddecdccbedcdcddbbbebdbdccccbbcccdccccedcdccddccdacbcdddccbeabcbcecdcbbdcbccceebdedddcccdccccdcccdccccbcddcdceccbdcbdcbbcdbeccddbcdcdcccddedccccdccddeccbcddcaccccdcddcccaecbccdbdccadeccccdccccbdcbbccdaccbccbdcccbddcdbcdcdcbcbbcbccdddcdbdcbccbccccaddcccccdccbddcdcccbcdbbdccddccbcccbcccdcdbdcdddcccbdccccdcccccdddcdeccbdcccccdcdcdddccbccccccdbdcdcccdcddbccccccdbbdcdbbcddddbccbdcdcccdccccdbdbcccdbbcddddbcacdbcdccdcdcdddcddccccecbdcbccddbf[c`ccd\g^\[aihYadafil]cgl_i`fbdccdeVdkdf\]_beg`[eejZ[cVgjc[Zgbdcbbamtndi[f[X_\[]im_hg_f[\`cqabY\bndbZZdf]cajc}ehbfhVXbc]lfcag`lbaug\qQebgbV_i_qzdh\je]YfcbdihdTYfmK]Z^kdmiWceaie\eebiVPdb=nleZebjcge`vXYclbUcqaUh`aieai`backbhka\df]e`gr[bb_]o`d`bnge`dhec_[bfccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccdcdccdccccccddcccccbccdcbccccddbcccdccdcccdcbcdccccdccdcccccccccccddccccccccccdccccccbccccccccccdcdccccdccccbdccccccdccddccccccccccccccccbcccccccccccdccdccccccccccccccccbcccccccccccccccdcdcccdccccccccccccdcccdccccdccccdbccbcccccccccccccdcddccbcccccdcdcccbcccdceccddbcddcddbcddcddccddcddccbcccbbccdccccccccdccbccdccccddcdcccdcdccccdbcccccccbddccbbddccbcccddccbcddcccddcecdcccdccdccbccbccbdcdccbcccbbbdccdccdcdbdbddddddddeddccdccddcdcccbdbbccbbcdddddcccdcdccdcdcccbcccdcdcccbddbccdccdccbdcbcdcccdccdccdcdcccedcddccdcbbddbccbdbdbeccccdccdcdcecacdcbddcbdcdddbcbcdbcdccbbbcbbcddccabcbddcbdddbbdbcedbbaadccecccccccbcbcdbcbcabbddcaabdcddcecdcccc`dcccccdbcdabbccfcccabccbbbcdeecbdcdbdddbccbdcbbbdbbcbccddbccdcbcbcbcdbccbbbcccccbcbdddbddccbbedbbcddacdaebcdccecccbc`acbabebdddccbaaccabaddbcc`bcebbccaacbcbcgcacdcaccbcbcdccacbccbbbgdbccebcabaabbbcabbacddcbbcbcdabdacccabacccbdcc`bccbccbcf_dddbdccbc_cacdbcdbccddbbdbcccdacaacbcdccdadecbbbbadcacbacccdcdde`ccbcdbdccbacbcbdddbabbbbbbdccadbdabcccbccbbbcbbdbaaccbccbbcccbbcbdbadcbcdbcbabidbc_gcdbccbe[c`fcbabfgddca``e_cfdadfaadcceedebfdceeaaem`affeejacebbfcabbe_bfc``ead]ac_bdfded`a_cace^efeccbaahaacacfbfbc``k`cb]ccbgbeb`e_deeaga_``bb`de`b_jbddadc`ec`a]ed]bdadbec`cehbdbabgdbddae_bccdacbeddhbcedeab`be_c_d`e`d`cadfabechcac^adcf`d`bddegg_cle^hcccccdcccbccccdcccbcccccccbbcccdcccbbddbbccccccbccddcccccccccdcbccccccccbcdcccccdccdccccccccccccccbccdccdcccccbcccccccccccddccccbdbcdcccccbdcccccbcccbccdcdcdcccccbccccdbdcdccccbcccccccbccccccccccccccccccccccdcccdccdcccccccccdccdccccccccdcccccdcccccccccccccbeebe_ceeccbdfdebjac_f\dedbfeca`ebbebdedfeceffggdccecd`dbbedbecfiabedccccagbb`eebcddbcdehaedagdiecebdeffebbcbegccbc_iefadebdcca`acbfjddgbfbaecddecedgeac_gacadecgfded`ddda_bffebfefd`ceaafg_ccffcbcd_cebecgbfchbf^dgafgcbbdbefeaeegeffcdb]_ecccbc`ce^`_`abfdeafcZdam_ac_h`b^fbh]a`gedgc]_f]agpf]`\bYTbccccfaaffg`]\jdeh`Wdce`gibb^afeg^`gccco^c^d^chf^f]ggdcebb[_edj``\Y_hncmgg^`iebe\abdafe`_haahel_egd\ajhhnfa_Wfibgd_]]dfhh_^hgafai`Y_hhgejilhc`_kgk``fdZgcddf]_fe^d^]bfc^g[ggad`ait`fep^ka_dc`fachh\bZkgdi_ei^ccii_db^gh`_gpZibY`gdj_iagn`]gcTib_aaa`djbdc`gaccdofb^^j\efldUjedaghSd`giWf^_[elc`e`agfb^dg_aqicbbo^fdbc_dc_hg`cln]ac^fb_fnggkdfda]b`^\ihhcgifbkshef`mfmdffcg[[[a]gaab]he^_Vc_ifcae^fcg`^kj\_Y`_Yedin^bZTmccg^\Uddab^eba]kef]``fgXf`S_d\h]dkckagheg]d_f_e_Wca[d`\fbifmkh`eia_cccccccccccccdcccccccccccdcccccccccddcccccdcccccccccdcdcccccccccccccccccddccdccccdccccccccccccccccdccccccccccccbccccccccccdccccccccccccccdcccccccccccccccdcccccdccccccccccccccdccccdcdccccdccccccccbccccccccccccccccccccccccccdccbcccccccccccccccccccccdccccccccek\Z`]g^_i^`ibba_[ff_^jhfgk^d`_nid[^o[iagab_hc`aj_g^YZ[edmc_g`jiefidaf\j_bYb\_bedd\b_^jgh\^bhahcadboegacac_msh_hcb]kd^`e^cie^ib`dmicbifllg\a_gcef`_gfmn[\cfY_b[agbYadaf]b__d`^hma`Zbcm`ehUYnb_efa`egcac^[`]gc\Wicmf]f_See\\Ue^ccZXhcch]_kwelhde^^f_ch^dlh`fdeh]\ccccccccccccbccbbcccccdbcccccccccccccccccbbbcbcccbbccccccccbcccbcccbcbbbcbcccccbcbcccbcccccccccccccbbbccccdcccccccbcbbccccccccccccbccccccccdbdcccccbcbccccdcdcccccccbdcccbcccccbccbcccccccccccccccbcbccdcccccccccbccccccccccccccccccccbbcbccccccccccdccccccccccdcbccddcdcddacbccccbccdbccdebdcdcccdadcbcdedcdeddccdececbecccdccccdccdddcdfccbdbdcbcdddcbcdddfcecdcedcdcdadcceddddcefdcccebfceebcdccccccbdccdcbebbddebbcccdbebbdbddcdcdcdecccdcddadeedcdedbbcccddcccbcddccddddcceccdfeccedcddebcbdbcddbecddeccceccdccbdbdcbbdcddbldae]je]ch]b_a^k]aadaddcfcfVc`eggldebhcbb`ebag`dggedbef^ggacaddbeida_ccefhbbceeh`cgdbcha]^bi`hjafbfgd`da`cbcicfcidage_cd\cjbbdbd_cgdebc_^dfead^cfcbcfaf`hbcdZbhaadf`[caagd``_addd^eaaedfbefa`hbf^bce^f]eb\^hh^ecbec]afcgjc^ffdj_b\bfdebcggeca`dfdb`^`ffbe_c]bbc\cbdcdccccccceccdbccdcccccdccdcddddccbcddcccddbdcdccbccdeccddccdccdccdcbccbccdcbccbddeddcbddccccccddccbcdccceddddcdbedbdbcbccdccccbccdcddbccdccdddddcccccccccccddccbcbcccdccccbdddccbbdcdccbcbcbcccccededcdbccbcccecbccceccecccdcccdcccccddccbccddcbdcddccddcdcccchfgdU[iceb`bgeefdcg]g^g`ghb`bc^__oab]i_daa^k`rZg]adcjijf`emh_Zcd]kg^ide]afg`dj`kf[dia`efjbfeY_je]aijed^`cdcafgfchcchg`badciidf]heide`aiej_fW_\Xie_c`]_b`fajgcXdakZZgi]hha_^gieghk`aic]h_c]b__boYb``d_^ejhdfhh`de`df`c^ebgejegc`hbg`eOhc_if]jae^h\`le\dbcad]che]dceebbadcaccabddbccbadbcaddbe`addagabdebccbbcabacaba`debbcbfbbacdbbacbbca`cccbdbdbbcgcfbbbbcddacdcadadb`adbdcdcddfdcacbdddbdbbd`bdaddadddbbccadada`fbaba_cdaccdd``aacdbadbaedcedcebdbd`abcc_acehbbbacccfccc`abfadcdddabbbc`e`_cacdca``dbcccaebacbcceebb_dccbdbab]bc_]md^dXejebjlcbd_i_Y]_c`Sc^]e^gfnkefifb`c]_i[d`ak^dqo_e_gadefgmc`dgifdeZhjZ[`d[d`jitf`\bbd_fkjj]jaTc`hdegYcclg_`gZ\aaccZjac]acbjemei_blac\ajijb\icZa`iclhbekXccd]Ui`b^hagf^fijmhfhgdeZdlZfi^j_aaZdf_fd\dgcXhd]gh_g`]i`kfkWgeb_`_jh]ajdl]a_]ec`\e_bcb][hb`cbZ^a`eqfpdeebbia\hc`ic\]gccbg_e^^`dfkhd^madc`_aab`h_agggdn_af`addea\f`f]faeeb`e]md_ebdke\^ii_i`\chechhf`bg`bfldc_[\hd^[[eldji_hcae]ch\dchd`h`cp_imbdY`ca_bhh_gdl]iea\gab_afaheac[bb_ap`c^bc^icWg]`^lf``]dhgefbd[hbe`Vbncdm`ob`o\fcdaaZ^hd^^aZfb_cebc[dgge^cfdfdbkgfb`^_h[hfccfame_e_cc`gbbhakgjf]\eejacidcc`dg`g\e`bcjcbc[hacadg`facifa]chdaffaaddh^__ceb^dbbe_cbfbfedd`bdcbf_afh`wa\f]afbea_nd`i[h`addajdc`_c`agia^j`bfh__gkbbhdccabfc_ah[cad_fca\_cgeaipbaigej`c]cghahdei^gfcg_feicn^gebcia_cbcjeeadbfgdlbhie[adaefbcdladei__ha``cccdcbddcdccccccccccdcdddccdcdcccccbccccccdccbdcccdcccdccccccdcccccccccccccccdcccccccdcccccdcccbcccccccdcccccccdccccccdcdcccdccccccbccccdccccccccccccccdbccccccdcccddccdcbccbccdccccdcccdccccccccccccccccccccccdcbccccdcccccdcccdccccdccdcccccdccccdccccdcbccccdcccccccdcccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccdccdccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccdcccc]\_kq^fd]e[hfYZeedfYa`\dacsfY[i_e`\hkck[d\cgRsda\chg]bdb_fgfbc`][e`X`ehcga[Vi]ibe``dej^j^gdqdadhc_lgced`h]acfgpfZfklcah_agbcca`kc`k^f]aZd`fb__``zh`Zc_a`cZ\]hi`_h]kfe^bjcadeh_\_gc`\ce``ebedbdZb^gfleadgbmlgZmi\_l_`hdeg`gfdajkchfd^cf`ea_ge\ejaldd`jf\j\i\bdl\b`bc_be__bbc_aab`ccfbeeaadbfbhgkab_aYcad]`fcc]ded`ababbd^_e_a`ebbcacedc^_\ebga_ba\icbdaa_affc`c`d^ddb`baacecdebh`dfcba_bfccb[a`c_`fdadeb__dagcge`ccdjd`cafbdbecacbce_ecbdcabd_]_db`_bjb__ae^decbc^_cadj__daacb`eahaefccaf_gbdbdifaaadfe^dh]e_dcbf`fabf[`fe`ecb^_beccbdcedcdddceccdeddeadccdcbbddcfcddccdcdbcbdcabdeccecbbedcbccdedbbbddeccccdcdbbbcdbccefceccebbbecdcbcaccccbccbeebedbecccbeccbeecedeeedfcdecaecccdcdcbbabdbcbdacbdbbcdeecefcbccbddccccbbccacdddcccccccbbcccbbceccbddeccddbccdbdcbbbecbdcebcbbcdddbeebbbcdcbddcddccbbebebbdcde`cbccdadedaaba`bagbedb`d`bbbbb_ddbccdaebfecdbcdcdacbeccbdcagbc`ecbfdeb`ccfgbbdbe`accdcecccecd`bcbdbaecccedbchcccccebacddabbfdecbfbaeccdaaedbfdfbdcdcbbeadebecbbf`bb`ebacdcbecddb`abcdaeb_babbdeedebcdedeeaeddcdedacdeegfdcdabcccbddcbdabcdcbdcdcddececccdccabdecdcbedbbbcdddbcddeabedcaddcecddccccdddbbcccdacccccfcdccbddcccddfddaccbdecbdabcbbddaddbbebcbdccfdcceeedebcdede`ebdcccbeecddcdddeccdbbcccdccdddbdcdeccdccdcadccbbfbdddbdcdbdbcdcccebbbccbdddcbcdccccbdbccbdbeddcccbdbcdca`cccbbcdeebcdcabadddbbfaaeeb`dbYibfYiX`^dc^c`bc^ih]bef`]g_ZgbZbabcabklZ_`^ach\Y^jZiYgmgaiZa`^_m\iZ`dfg_dZR]ggi[koafjaed_ghdjdj`dd`egdbdadW[\kS_e`gbgfg]kiavcf_cb`ejkkd][ebdbdah`befYe^akW^gOib[Ye[p^b`ebd\dfahe_`jc^kfhaeT[shebg`fYWbc]eih`agbcl]ff[eifZb^`figeeivfwjWdhagf_g_c_bc^a\Z]f[ogiccddbcccdcdcbbdcccdcccccdccbddcceccbbddbcdbdcdbbcdcccbbbdcbbcbcbbcbdccebcccdbdbdbcddccccdedbcddddcccbbccedbcdcaccbccccdceccccbcacdddccbaccccddccdddcdcbcbcdcddcccbbcbbcddccacccccccbcbecdbcadcddcccdbbddccbcbdbcbbcbcbdccbcbcbcbcbcbcbbcbbccdddcccbbcccbcbcbeccc\a_`id`V^abuZcgh^ab^X_YffncZfaobeY^h]fd^id]mh_[^_hUYkPcbef`ca`eebb\l`[bfbhggb`e]eX`rihkgg_^ceem_mi_hZ^fmdWidYo`]h^ie_db[df\fis`_aVcgdf_jg[\diapiddahh^ij_`gdfe_]f`c`dbfekkc`^cei_maZ\g]f]le\ddY\qgia`Ogh]Zla_agaifeaUa_jc[\Zli]V_\gaobafj[ef_eZ`f`gZfhfbe`e^ifZcdcddcddcdccccddccdccccdcddccdccccbcbbddddcdcbcdcecbcdcdcecdccdecdbdecdccbbddccddccdbcdccdccccccbbdccccdcdddccdcdcccbbccdcdcccdcdccccdcccdecccddcdccdcccbbccddcdcddddbcdccccdbcccccbcddcccdddccddccbccdcbdcccdbdccdcccdcccdccddbccccddcccccdbddcdcccccbdccbcbbccbfhc```aadged[djeb_laeZ`cecba^bcccadcafcddeamdbafe_befl`bff_ddZc^age^eac_hb`_feagecblaha^d^eacfhddbdcfbfceeffec`ddfghd^gbcheh]f^id`d`dfhfbb`d]c\gbbe]_c^h`cg_chde`hZfe``fjced^gf`hhae`ddcaafhbcfbbY`\hbgdabgedZbc_b_iecbfd_chbdbj`e^b\gc`i^aabdffdbeeh_ebai^_g^_cccccccccccccccccbcccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccbdcccccccccccccccccccccccbcccccccccccccccccccccccccccccccccbccccccdccccccdcccccdccccccccccccccccccdccccccccccccccccccccccccccccccccccccbdbdccccccccccccccccccccccccccccccccccccddcdddccccdddccddccdcbccccdcccccccccddccdccbdccdcdccccccccccccdcddcdccccccddcccddccccccdcdcdcccdddcccccdddbcdbdcccdccdcdcccdcccdbddccccccccddccbddcccbcdcddcdcdcdccccddccccccccddccdccdcdccccdddcdccccccccdcbccdcdddcdcdddbcbcccccdccdddcbccdbccdccdccdccccccbabbccbbbcdddcbcbbcbccbccccccbdbbdbbccdccdbccabcdbbbdcbcacabcccccccccbbcdbccbcccbccccbbbccbbbcbbbbcccbbcccbdccccbccbcbccbbbccbbdccdbccccbccbcccbcbdccbdccbccbcccdbcccbbbcdccbbccbdbbccbdbcdbcccccccbccbbcbbbcbcccccccdbccbccbcbbdcbbbcbcccbbccbbccdcdcccbddbacccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbdccddcdcccccbcccbcbbcbcccdadccccbbccccbbcccbcbcbdbccdbcccccbdccccbbdccccbdcccccccccccdccccbcccbbcbdbcccccccddddcccbdcccbbccbbcccdbcbcddcdccccbcdcdcddccccccbbccbcaecbcddbcccccccccdcdcccbcbccdccdcbccccdbcbccccbcddcccdbccacccbbccbccbbbbcccbccccddccdccdcbcccccbcccccccccccccdcdccccdccccccccccccccbcbccccccccccccccccdcccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccdcccccccccccccccccccccccccbcccccccccccccccccccccccdccccbccccccccccccccccccccccccddcbcddcedcbdcccccccccccdcddcdcdcdccdcddcddccdccdddcecbcbccdcccccddccddcdccbcdbccdcbcdcccdddccddcccdcdccdcdcddcdcccccccdbcccdcbccecccccdcbcccdccceccdcccdcbbdccddedcccdccccccbbbcdcbcddccddeecccccdcdcddbddcbcbccddccdccbddbcccdcbdeccdcdecbcccdcedcccccddddcbcbcc`]_g_cdch^gdag^]cge[_megdehf]ie_egWfVac_`dgdgkcUVcnXceYdfcdef`]admeeb\gcg^c`bdkW_da^cfngfdUekabp^dajpgdk`eda_\ac^ccccaik^l`ceid__gc[Zba^bbjglacdeadbafce]kh\edbfeZZ^cbpb`_fagcdj_d\hXbj`ecbjdcakk`\h\gddfab^hdadeeakdedgg]`_gbc`[g_d]b[[g`fgVcaahceimd\hdbdl`cccbcccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccbcccddcccccccccccccccccccdccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccdccccccccceccccdcbccccccccbccbcccccccbbcccccccccdccccccdccdcccccdccbbcccdccccccdccccdcccbcbcccdcddcbccccedccccdccccbdbcccccccdccccdccccddceccdcccbccbcdcccccdbbcdcddbdccccccccddcbdcdccccdcdccdccccddcccccbcbcccbcddccdccccccccccccbddcccccbcdccccccccccdcccdccccccccccdccddcccdcccccccddccccccccdccccccccccdccddcdcccdcccbcccccdccccccccccdccccccccccdbcccccccccccdcdccbccbccdccccccccccccccdcccdccdcddccccccccdcccbdcccccccbccccddccccccccccccccccbccdcdcccdcccccccccccccccccdcccddccccdccbccbccbccccccccccdccccdccdcccbdaagj`ef_aaedd]\dd][__a^f]]^le\dbj`fi_gbaece\ca`ebeib^lf\chmegZacbe_eebbagafhciabbfdfg]fekbi]\_[Yai]`ceada_db_maaca_daebachfe__ibdh_ea_Xjb`ai]gfgdfe_e]c]ldkd]hbdca]fad[igbdcbdceaWhakbWgaficbac_dfle_fmmi`edcgdcbhYgdaeibace^b_db\ecffkeae\feghfj[fh`ffd`^aaeh]^[]mdej__bZ`i^]c`^j]hjYdfifffce^`[hfcbafd]]`Yl`_ja]j`7^magiY^k[`af^cdc_c^ddg\Yefa[eabfdg_b]fYl`_f_lffdg\^\\bmcoc^\ifg\a]a_bcd`^idgi`eck]`_`\edhfz]fcd`aedcb[\hh_lYbm`tcaZZd`gPdga[hendd^gZagece_lijed`bfgmcZhdheefjgSdfib\hkdfVh_jbe_aluhbg^beeh`]dab_mdgfih]cdeecccdcdbccdccccccbccbdccccccdcddcdddcdcbcdbcdccccdccdccbcdcdcccdcccdcccbdccccdcccccccccccddccdcccdcccdccccdcbccccbddddccbdddcccdcdcdcdccddccddcbccddcedccbdddddccbcddbcccbdcdcbdccccddcdccdcbdccdcccdcdddcbdccdcccdcdddedcbccdbccbcdcbcdcdcdccdcdcedbcccdcdddccccbdbbcdeebcccbdbbdbbbdbdebbbbccdbbcccadbebcdeabcdcddbeebbdfcccbdcedcdcceeabccddccbaccadeeddcedbcabcbbdbddbcddfcadbccbcfcacdbbcccddabdcbbccccacbbccddcdcdbaccdbceedccccbccccccb`cdacdddccbddcddaccdcaccddcbdcdebdccdcccbaebbdbcccedcccddddabdcdcdebcbebbddddbcbcccccdcdcccccbcbccdccdbccddcccbccbcbccdbdccdcbcccddcccccccddccccbcccbcccccccbeccccccccdddccccddbcbcccdccddccdccdcdcdcccccbcccdcccccdcccdccccccccccccccbcdcbbdccdcdcccdbdcdbccdcdcdccbcccccdccdddcbccccbddccdbbccccccccdbccccccdcdcddcdcccdddcdccccccbccccccbdccd`bc`bdb`ebfagcbbcdadbccbbcdbbacacccbbfaedaecdccchaadfacgb`deccefe^eadbccbbbebddbbfcdedcdfcb`bdea`fbaeccdgbcbd_aeahccc`gcaabad`ccbc``edbadcbfb`ccdcdcacbdeb`bgbcbcaacdbbecgfddecdecgcdbdddccfbbbcbfbdbf`cdaded`cbdadcdic`dddgb`d_ecabdcdgaaeffebaca]facabbcdcaehedcccccccdccbcccccccccccdccccccdccccccccccccccccbccccccbcccccccccdccccccdccccdcccccccccccccccccccccccccccccbcdccedcccccccccccccccdcccdcccccdccbdccdccccccccccccccccbccccccccdccccccccdcccccccbccccccdcccccccccccccdccccccccdccccccccccbccdcccdcccccccccccccccccdcdcccdcccccdcccbcccdcccbdcccccccccccccccdccdcccccbcdccccccccdcccccbccccccccccccdcccbccccccccddcdcccdcdccdccccdccdddcdccbdddcccccccccdbddccccbccdccccdcccccccccccccccccccdccdccbdcccccdcccccdcccccccdcccccdcdcccccccccccdcccccdcccdcccccccdccccdddccccccccdcccccccccccbcdcccccccccdccccccdcccccdccbcccccdccccccbccccdccbbedcdddccccccccccccccbcccdccccbccccccccbcdbccccccccccdcccfccccbccccccdccccdbcdccccbcccccccbdbcccccccbdcdccddddbcccbcccdccccbdbccdcbcccdcccccccdcccccdcbccccccbccbbcccccdcdcdcccdccccbccccccccccccccddcccccccdqe`iafdbhJ^j]_mcfYnchfk\V_p^Yig^\YbiVi^df\m[_ccga[_}f^dc\egngfd`eodid]\bad]hh`[ibf^g`gbc_\kicae]bbdc^dfic_edTlmdQa`i_ghgbbkcbccalpZb\]dfkjchc`Wa_op_gm\]`gcf_bdlcZlc_]g^e_e`db_cadhZgW^iNfcerd\k]e`abefaaea]jdp^rg\s`aXbcdhdcUcaggr^Zf^iefnf^hbc]ebadb[^djf`dcecdeccddddaebdeccdfddbcccdcedcdcdcddabdcebdcbecdccbeebbddedcdfcdcbadccccabb`cbccceddddedcddbccbccddebccdcdcdcegbcccdcdbcdcbcccddcdcaebdccddccdebdcccdebcbbcdcdbddbeccbcddbcdcccccccdcdbddceddcbcddbcbdbdddbccddbcbdcdbccdeebbdcddcddccbcebeadecbcccbbaccfdcddddccccccccddcdcccccccccdccccccccccccccdccccccccccccdcccccccccccccccbccccccccccdbccccccbcccdcccccbcccccccccccccdcccdccdccccccccccccdcccdccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccdccccccccccddcddccbddcbcadaaacbbedecabc`bdadbebcdccdccbbcbaaecbccddeccddcbbbbcadcadbcacddaacddbddcbeccbbceddbdcdddccdcbdbbddddccbcacbbcbbbcbddcb`cbcccbcaedcdcbebccdcbgcgbcbcbcddgcebcddacbcbaccccbaccfbacbccbcaab`dddcdcbccdcccbdebdcdacccbadcdcacbbbccbecbbdcbfcabacdfcbaeccccccccccccccccccccccccccccccccccccccccdccccdcccccccccccccbccccccccccccddccccccccccccccccccccccccccccdccccccccbccdcccccccccccccccccccccccccdcccccccccdcdccdccccccccccccccccccccccccccccbccccccccdcccccccccccccccccccccdcccccdccccccccdccccccccccccccccccccccccc[bcedckha_hdbabac_eadge_d`ebd^d_camee^dleb``abea`^e`_bcZfg^gehbgfb]bYijdia`bgei``e_fe\cih]edafb]eZ^daedic^g_c^_Z^cgbcheheh[ijbae_c`fbfffdgfbcabbhefbaca`ekcfejeec`^fbecca`g_fjac`l_feb_gajbheh`efc^dcbg^iaf]e`ecedcceicefc_gh_ibgdecfcfefggdgifec_d`b`f_e]daadb`dccccccccccccdbccccccccccccccccccccccccdccdcddccccdccccccbcdccccccccdcccccccdcccbccbdcccccdcccdccccbcccccccccccccddcddccccbccccccccccccdcccccbccccccdcccbcbdcdcccccccccccccbdcccddcccccdccccccbcccccddccccccddccccccccccdccccccccddcccccccccccccccdcbccccccccdcbeieage`bic[ei`ca\hb]cdeb`^Zichcaigebd_a^fkchmcfahh__hef]\ff^\ghodbdi\bbbbbedZlbc^d`b`b`fdba]bjif^_c_ccfcdfbc\ca^abd_[ffjed_bgYegce`ef_a`gh`de__dbamaddcihbgbl_^hgdheg\`bcefaabfdd`kgl]Vhafe[dbejbia]`g[fde`cec`ebfaidd_geag^[akeg_g_ae_agaechbhegd[da^bcab^hdefcbbfcbebageeahbbebd`bc__b`dbdd^^fbcdadeje`d_gdbabagfbf][lca`cc`c_ababbbbcedbddd^iaab]\cd`acaaf[afgccbba`dhf_cdcbffbcdbfbhhdd^_hY``\ghjae`_fd_cbgdaa^facdbccbbbfb`debi`a\bbj`cebfdg`adb`jcceaejbgf\bc`e^deckf`c`decbeded_e\dicdg^eedcadedca]daae`bddbdei_fb`__g_ca\c\h\_hXc`l`pgjc`f`qeCbZeTageiaWjX\^j[^kbgour]adegoTdlixhm`bmflP^gq\dV^dilfeijaZUebVchagYgn_a_Yon^fbdijfee`fcod_bf]bd[__dU\OZf_g_\`_[gdeqa_^Vodeeceb_`balXg`Yeh^e\db`ealdgkdZb\\_dgamZ_ioaXcle[ak]]emqkW`e^\dVcpbaiaicWpebbdeYcdvWbUbfce_bhb]`ad_^gady[_^tXsct_eccccccccdcccccdcccccccccdccccccccbccccccccbcbbcccccbccccdccccccccccccccbcccccccbcccdcdcccbcccccdccccccccccccdccccccccccccccccccccccccccbcccdcccccccccccccbcccccccccccccccccdcccccccbccccccccccbccdccccccccccbccccbcccbcccccdcccccccccbcccbcccdcccccdccccccccccccbddcccdcbdbdaddbbcdcbbddcecddeacddcbccabacbdcddccc`dd`acbddbbdeebfbbdbccbcdbecaafbddcdcdbbccdcdccebdcacdaddcbdabcccdbcbdbeecbfbedcecbbabcbdcddcccaddedcdbbcbcccccdddbfbeccdecacba`acdccabcccdbbbccdcbcbbbgccbdcccdbdcdcbccd`bccc`bcdcfbbgbccbbcdecdcddcbfdadcbceahdb^Xf[_]^e^]iekehbccbphgd\\eb`^cc`c]deidg\d`[def\_e[df]ibck\c`d]^ake[n`]Tg]b_edlYgdheab]bi^fkTakhgfkf\`Yf``_`aga^cb`icdmfgqbmgfdc_h`hfnZ\d]g^ed^id\b`^dc_fbd__ff_dXj^lacfibhjck^cedadefg`a`afg`gc]l`c_dcd\d`haihbi_fiecdha[c`_c_bdfoei`ddbgchdcaf\iZddckdhdhlec``b`eaebcdhdeddddcdcbcbebdadff^ceadae`c`c`ccdffeed`fecehddb`edcca`cabhdcccfa_hcbdedbcadcebhhbabeacecaeebdbbcbb`debaa^gbecidaggdb`dcedaacafcbec`gedbcbdchddbbbcd_bad`cbecbab``debcebc`ba`bd`cccbgd`dagb`ddbcf`cacddaabecdfcdddebdbdcddcccc`dg`fee`bbcddcbe_cabdcccffcbcmf\`ayh`YY_gj_fpdWa]ujbgmY^a[__bjb_dd^RmWmXa\chj{bRqechjhj\e]kgWXb]Z_zc``dil`ef[^\^\iehdUdWjco[bdffTh`owke^[diX_de\^^_^`ljKggd_elX`f`ggbiZbdZmhm_U\k^Zr^`^neecYUa^hfjdi]]el\\glg^yerchbbeifali_mWbc^]]f[]wfcL_~XUVbv_jache\ei`cbXdfcfY`gZ^bYdg[b[^]iRX]^idcdbcccccdccccccbccdcddcccdcbcdcdcdccccccbcddcccdbcccdcccbccdcdddcdccccccceccccccccccccbcdccccccdcccccdccdcccccdbbdcbcccccbcdccdcccdccccbcccdccbcdcddcccccddcbcdccccbccdbcddddcccdbcccdcbcccdccccccccccdccccdcddcccccccccccccccccdcdccdcccdccccccdddccdccddccccccccccdcccdccccdcccdccccccccccddcccccccdcccccddcccccbcdbbcccccccccdbbccccccdccccdccdcccccccdcccdcccbcccccbccccccdccdcccbddcccccbccccccccccccbccccccccccccddcdcccccccccccddcccdbcccccccccccdccccccccccccccccbcccccccccccccccbbccccdddccddcbccccdccccdcbcccccdccccbbcbccdccccbbbccbccbcddbccdcccbcdccddcccdccdbdccbbccddcdcccccddcccccbccccccccdcdcdccddccdcccbcccccdccbbbdccccbcdccccbccbcbccddccbdccbbbccdbccccbbccccbbcccddccbdccccccbccccccdbdcccbdcdbbbbdccbccccdccbbdccccccdccccdccccbcccccccddcccccedcbdbbdcdbddccccdccccbcbccddebbcccbbeccccddcacccdcccdbdbbdecacdacdcbdccagbcdccbecccccaacdbacbdcbcccddbcdccbdecccccbbcbcbbaccddcccbadcbcecbcbccdedabceaddbbcddcccbccfcaabbcbbccbbcbaccdccabcccbccbbcecfcbcccbcbchcdbccbccacdcdcccdbbcccccdfdbcdbccccccbceebcccbcbedcacdddcbbbcaccbacbabedbdccccbcccbcccccccccdcdcccccccccccbccbdcccbcccccccccbcbccccccbcbbccccccbccdccbccbccbcbcccccccbcbccbccccbbccbbdbccbcdbcccccbccccccccccccccacccbccbcbcccccdbbcbcbccccbdcccbbcdccccccbccbcdccccbccccccccccbcccbcbcbccbbbcbdcccbcdccccccbcccccdbccccccbbcccccdccccbcdeafaebeeccecgcba`ccedbcfehdbfcbbc`cgacebcbaddfbdd_bafbaccdccbedcccbdedecbcbcceecddaeba`fdddfdcfa`af`ecb`ed_bcccbacd`bfcccag`bced_dcdeaabefcbbccbgccdcdc_bcdeeccbbedddecb`ec`caabbdeccde``ffafedddcebeecbgbefaccdddd`bbfdcaedddecdbdegaeeddb_ddbcagfbabacf_fccacccccccdddcdcdcccccddccccccccdcddcccccddccccdccccccdcccccdccdcdcdccdcccdddcdccccddcccccddccdceccdddccdccdcccecccdcccdccdcdcdccdcccbccddccdcccccdcdcdccccccbccbccccdcccbcddccbccddcccbcdcccccccdccccccccdcdcccccccbcccccccccddcbcccdccccccccccddcccebccccbddcccdcbdcccccebcddcdcecdccebdecdcebbbcccdcbbbdccbddcccbdbdbcdedbcbbccbcebdcbdbdbdbccdfccdbcdcdcbbdcccbabbccdccccddccdcacbccdcdbddbcdcbdcbcaccbcecbdcdcdcbcbcbccdceccccccccbccbbcdeccdbccdccdcdbccdccdcddc`ccddccbdccdcddedbdcdcbccbbbdccccccbccbbbbccccccebebbccdbcdcbddccccdcccccbcdbccccdccccccccbcccccdbbcccccbccbccdcccccbccccdcccccbcbccccbbcccccbccccbcccdccdbcccccbcddccccccbccecbbcdbccbbcdcccccccccdbcbdcccbcccdcccccccbccbbbcccccdcdcbddcbdcccccbcccccccccccccdccccccbbccccccccccbcbccdcccccbccbcccbccbbbcccdccbccccbcdbccdcccdccdccccccccccccccdcccccccdccbcdcbcccccccccdccccdccdccccccbcccdcccddddccccccdbdccccccbccccbcbddcdccccccdccdcdccbcbccdccccccdbccdcccdcbccdccbcccbbbcccbcdcbbbccdcccccbcdcccbccbcdbdccccdccddcccccccbdccdbcccccccdcdccccccccdcbcddcddbdccbccccccccccdbcccccdcbccbfebZa]j`_gbj__^g]\fe\^cbicagmgjja_`ecceg\fXkagbf]VVf^_ihfbed`djdY`dhk_g^^gdne_[_`jckjff[\eeha\abk\h_d`\]Xkgrkdedbkledd[cbgeaVhjdbdaeWgcYW^g\ecej_eeedp`i\g[defhadb^e\dg`bfe_c^]jic`jdbhcff]fec\]dbd]dal]^ikddhfaeag^[ak^h^ebindd]heZ_ahe`oig^eafcdbfbleZk_eee\c^g`ica_af^^bcbhgeja[eggeZ]V^a[Ze[sg[b`^e[e`QbYeh_hgredehSbm_eY`YmdhXjWem__addabhfeka^\aah_eY[kxd^geeba]b\b]gghfY^b`b^hgdoijboh[fd`^ZZmbffj\_lqcfXgbjrajpgndj_dgfflfhSiZ[[ahd`dbjjY`Zkg\ccbdb\cbihimZacghg_ic_]abQaib]pdfna`X^cecee^bcaScgbnminedhbfb`dZ`daec`dYVaeddccacdbccddbccdbcccecddcdbcdcccccdddcdcccdcccddccbcccdcbbcbcddbddcccdcbccddcccadeccbccbbcbadcbcbceccdecccebbdbdcbbbcdcddddddbccbcdcbccceccccccdbcdedcdccdcdcccccecdccbcbbccacdbdccddddccdcdccecccdccdbdbccbecddbcdcccdcccecccbacdcccbcccdbbadccbdaccddbdccedcccdccebdbdbccbcdcfbdbcacceddbdddabdedfeddddcdefccacccbcabcdcabbbdaeccdddbdddaccdbdecbfecddddcbbbecebdadccabcdceccdbcbddeccdccdccbedeecbceeecebcbcbdfcdccfcdbccecdbcbeccdbd`ceccbbbeedecbdbdcabbcecdecdbbddcacbbcdccdfccdddececccddbccdbbgbcfcd`cdbceacccebcccbcfao]dcp_YZcfgbShZn__P`cV[rk_i`eTgXnekeUcl]ddeceg_^bmjgX`edjk`]c_\\]ghbf_kchpifZbj\]eQcebdZ]keXl]foe^b]]lk]ccdYe`W^`hf\kfX`XZc^gmhbUv\iehf`j[][c]hbabX_N[_dqh^de[bg\ZYa^cfga]_Y^a[h`_lgbMiaVoWg[g[][g`lchbmbcfgmdmoe_]lePnqabMcbdbfgkecbaerbkc`kjddcfgl]kjch]jqmfjXhe`a_g`jV`lm`nj\\__p]df`bYYhbe_fc]ldb_fj\Xbafaa]cXaf^ijvbddnea]Sagj^[cgdacfabZd^Zeg\dbe]Yi]jjh[de^cgghdZgc_m`fbeojccha^ae_]ebgcZid`c]g\d]gh_Wabbiofc]p]ag`geinbg^[\Y_nfaiaag]akgdkbeiZ^jjlbWd^fcm[Tcbcd\jadgc`fdjqd__coljc_jdb^am]_Yc]a`ia`ahdddhbmchngccY_Wdedbccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccdcccccccccbccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccdccccccccdcccddcdcdccccccdccccdcccccccdcddccccccccccccdccdcccccccdddccccccccddccdcccccccddddcdccccddcdccccccdcdccccdcccccccddccccccdcccccccdccddcdcccccdccccdccdcbcccdcccdcbcdceccddccdccbccdcdcccccccccccccccdcccccccccdccbcdccccccddccccddcdcccccccccddccdddcccccccccdccbcbccccccccbcccddbdcaccddbccbcccccdcddccccdccccbccbcfcbcceccccccccdccccccbdcdbccbbccccdcccccbccbcdbbccddcccccccdcdcdcccdbccccbcccccccccdcdcdbccdccbbcccbcbcddddcccbbcdddbcdbdccdccddcbcddbcbcedcccbcdbbcdccdcddadccccccdcdbccccdcbcbbcbbccdbdccbcbccbcbccccbbc\df]\j`oj]`eafebjchgff`dm]ipfd^eW]becdhc\f__`aiib][_ee_^d^c_^beec_]fiegeefa`dXb[`bgd\bcfcbaaa[_gdidah[k`dceg^hagdda^^]cehd]^]eee_akiceg^fgbda\hbehigh\c_ffg`acb\h]bgd\k_a\Z^d_`fhcgfaebeadadcddifge_Zdk]agcndcaf`abjglf[adfecj`edeb^kfcggfa]dfbacbediedca\cf_fgcdccbcdcdedbacbcddccbddcccgcfccadcccabdbccdaccbbcbebddccddacdbbbfcbbdcccccacadcbdebcdcccccdcaccccccddbdbdbcdcebaadcbfccbdcddfdcbbcbcdbaeddadcbccdddbdcccbadbdbccdcdedcbbcccccfbbdebcddafccdcbdcdcbcbdbcceacbb`dccbbccdcdcbbdbcdcecfebbcdbbccccccdcbccbdccccdbcbcd`fcfd`bfbace`fdaadgi`a^beacgf```bffbeadebb`hhaed`dccceebc`fbbbef`cgadae`dbdfbgf`defbecadkfaacegjfaaef_eefb_b`hefbga`caiebcb`bbebe`dagc^bcbbfgbda_^hagbfeb_bahfabacaddda_ecdc`fbcbaibb`cfcbf`bbcbhfacbadbicdfc`abebedceadbbfjcbbbebabdbag^adb_bacdaefcebcaa`a`abbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddcccccccdccccccccccdcccccccccccccccccbccccccccccccccccccccccccccccccccccdccccdcccccccccccbccdcccccccdcccccccccccdccccccccccccccccccccccccccccccbdcccccccccccccccccccccccdcccccccccccccccccccccdccccccccccccccccbdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccdcccccccccccccccccccccccccccccccdcccccdccccccccccccdccccccccccccccccccccccdcccccdcccccccdccccccccccccccccccccccccccccccccccccdccccccccccccdcccccccdcccccccccccccccccccccccccccccccccdcccccccccccdccccccccccccccccccccdcdccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbdccbdccdcbdcccccbccccdcccccbcccccdbcccccccbccbcccdcbcccbcdbdbdcbcccccccccccdbcccccccdccccbcccccccbccdddcccccddccdcccccccbcdccccdbcccccccbcdbccddcccccccccddcdccdddbbcbcddcdccddcccccccbdcbdcccbccdbcddcccccccccccdcdcccdcdccceccccccccccbcccccccccccccccddccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccbbcdceedbccccdcdcddccdfcedbbebcdbbdbdbcbbddcddcc`bcedcbadcdecbecbbdddccbdbdcdeccccddbcbeeecceeddfdeebecdcdccdbdcecbdecbddeddbdceaccecdcdc`dcdedbdbdfccdcbbcbeceecccededbeeedcdddbcdcbecedccbddddeecbcdccccde`cacbbcbdddbfbcaebedccadadabdddedceececdbdbedbcdcdddccdcdccddcddbcddddcccdbcddcddddcdcdccdcccdcdccccbddcdcdbccddcccdccddddcdcccccdcdedccddcddcdcdeecddccccddddcdcdcbdccddccdcdcdccdcdcccdcddcccccddccccccdcccccbccdccddcdccdddddccbccdccdcdbdcecdddcdddccddcdecdcdccdbdcdccbccddccdcdccdcccdcccddcccddcccdcccdccdccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccbccccdcccdccbcccccccccccdcccdcccccccccdccddcccccccdccccccccccccccccccccccccdccccccccccccccccccccdccccccbbcccccccdcccbcccbdcccdccdccdcccbcccccccccccccdccccccccccccccccccccccccccdcdcbcccccbccccccccccccccccccccccccccdcccdcccccccccccccbccccccccccccdcccccefgfeaa[difa[bbj[d^acghf`g`]edebiilaeeegk]dbc`gaiedcb^jcd]bcddonf^`dlgfa`ehb^def^`bfefcbj^g^\fib\bebefdj[de`be``ibfbgfdec_]kihVcdg_f_bd`ZdchefeaZc^fgfec_[bf\Xbgfih`]`^gbac\d]c\fhadhhc``eqgbddeW`ci_behgbdcni\dg`dffabd^_bcbci`]hj`bcdcbfhbYjf_^aYb`]hcdhb]ikgdccccccccccccccccccbcccccccccccccccccccccccdcccbccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccbbccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccdcccccccccccdc]`fdi[_caaei^ed_ceag]hccglfdaem\bija_le]cbgie^dfglb_a[]obafbcahaiegejbbhceijZdfjg_[higi[j``cd`fcaacgicbaef^bc]bf]cge_ec_d[^f]ge`eddje^dd`b`fb]`j]cfbodceda[h`^bc`eacjmggg^ajaeg`]bab^agd]_df`ce^fc`cnjajfbaeggcc`klZca`fc_abid^_\dah\fhcblc^dhacbacf_b_afhccdbecccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccbdcccccccccccccccccccccbcccccccccccccccccccccdbccddccccccccccccccccccdcccdccdcccccccccccccdccccccccccccccccccccdccccccccccdccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcdccccbdcccdcccccccccccdcccccccccccccccccdcccccccbcdcccccccccccccccccccccccccccccccccccccbccdccbccccbccccdcccccccccccccccccccccccccccdcdcccccbcccbccccccccbcbdccccccdcccccccdcccccccccccccccccccbcccccccccdcccccdcccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddcdccccccccddcdddccccccdddccdcddccccccdcdcdcccdcccdccccccdccccdcccddcdcccccccddcbccdccccccccccccdddcdccccdcdcccccdddccccccdcccccccccddccdcccccdccccdccccdccccdccdcdccddccdccccccccdcdccdddcccccddcccccccccccccccdccccdcccccddccccdcdcccdccccccdccddccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccbdcccccccdccdcccccdccccccbccccccccccccccccccecccccccccdccccccccccddccccdccccccccccccccccccccccccccdccbcccccccccbccccccccccccccccccccccdccccccccccbdccccdcccccddcccbcccccccccccdcccccccccccccccccccccccccccccccccccccccccccdcccccdcccccccccdcccccccccccdcdccccccccdccccecccccccdcccdccdddcccccdcdccccddccccdccccccbccddcdddccccdccbcdcdccdcdddcccccddccccddccdcddcccdddccccccdcccccccccdddddcdcdcccccccdccdcccdcccccdcccccddcddccccdccbdccccdcbcccdcccccddcddcbdcdcccddccccccdcccccdccdcbdccccdeccccdcdccccccccdcddccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcdcdcccccccccddcdccdcdcccccdcdccdccccdccdccbcdcccccdccdcbdcccdccdcddccddcdcdccdcdccdccccdccccccdcddccccdcdcdddbdcccccccccccddcddccdddcccccccccdcccccbccccddccccccdcddccdcccdccdcdcccdccdcccdcccccdcccdddcccdddddcccdddcccdcccccdccbcddccdcdddcdcddccddccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccdccccccccccdccccccccccccccccccccccdcccccccbccccdccccccccccdccccccbcccccccccddcccccccccccccccccccccccccccccccccccbcccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccdcccccccccbcccdccccbcbdbccccccccccccbcccccccccccccccccbccbbccccbbcccccccccccccccccdccccccbcdcccccccccccccccccccdcccccccccccccccccbcccccccccccbccccccccdcbcbcccccccccccccccccccccccccccccccccccdcccccccccccccccccccbcccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccdcdcccdcccdccdccccddcdddccdcccdccccccccccccccccccccccdcccccddccccccdcdddcdccdccdccddccdcccccccdccdccccccdcccdccccccdcccccdccccccccdccccdcccccccccccdcdccccdcddccccccccccccccbccccdcdccddcccccccddcccccccccdccdccccdccccccccccccccccdcddcccdcccccccdcccccccccbccceacdcbcdcccaddccdceccddcdcccdddcdbecdcdccdcbbbdccbdcdbdcdcddcdcdbdbbdccddcccbccdcdcccccccbfdccccddccacdddeccdcccddcdcddccccccbcdccdbddcdedecdcdcceceddcccccdcdcdccbbcddcddedbcbcbcddccccbddbdcccdbddecbddcccddcbcdecccbcdcddcdccccccccdcbcdcdcddcdccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccdccccbccccccccccccccccccccccccbcccccccccccdcccccccbcccccccccccccccccccbcccccccccccccccccccccccccdcccccccccccccccccccccccccccccdcccccccccdccccccccccdcccdcccccccccccccccccdccccdcdccccccccccccccccccccbcccdcccccccdcccccccccccdccccccccccdccdcccccccccccccdcbcccccccdccccccccccccccccccddccdccbcdccccccccccdcccbcccccbcbcccccccccccccccccccdcccdbcdccccccdccccccccbccccccccccccbccdbccccdcccdcdddcccdccccdcccccccbccccccccbccccccccccdccdcccdcdccccccccdcccdccccccdccdddccdccccccccbcddcccccbccccdccccccdcccccccccccbcdccdbccccccccccccdccccccccccccccccccccbcccccccccccccccccccccccccccccccdcccccccccccccccccccdcccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccdcccccccbccccccccdcccccccccccccccccccccccbcccccccccccccccccccccccbccccccccccccccccccccccccbccccccccccccccccccccccccccdccbccccccccccccccccccccbcccccdcccccccccccccccccccccbcccccddccccccccccccccccccccccccccccccccccdccccbcccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccbcccccccbccccccccbccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccbccccbcccccccccccbcccbccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccceZcchbgdbib`a]abcb_^gjblb^`ma\ao\__f_b_[bjccbaca]UchXgga_ifamdanf]el]efcbc]^cZdfd^``b\]phcchbcf`fbe\fae^dkjmcXaf^kgaiga`hh\bc`j`Whaeecd^ghbdeecY^bhe\i[c`nca\]bdd^gncgeblgbee]_be_jgfk^fb^Za\\df^a^aiadce`[igkbj\gidaga[dbb`kgbclek_p]ddchZh]ice\ade`dglgYfeRgi_ecdceecccddecdbdebbcbdbcedeecdddcbcddeccbdbccddecdbcddcdcedddccccbdeecccabcbccbdbdcdddccbddcdcccdcdccdccccddbbddeccccebebdfcceedcdcbbdcacbdcaddceecbbccdccbbbcdcdcddaceccccccdbccdccdccddddbbdccfdccbdcddddeccbddbcfcbddgccbcddeecbccdbecbfcccdbeedccdcbdccccecdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccddcccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccdccccdccccccccccddcddcdcdbcccdcdccccccccccccdcccccccccccccdccccdccbcccdccccdddcccccdcdddccccccccdccdcccdcccdccccccdcccccccbccccdcccddccccbcbddddccccccdcccbcbcdcccccdccccdccdccdccccccccccccccccccccdbccccccccbcccdcccccdcddcdcccccccccccccccccccdccccccccdccccdcccccccdcccdcccccccdcccccccccccbcdccdcccccccccdcbdcdccddcccccdcccccccccccddcdcdcbccbccdcccccccccccccccdccccccccdcccdccccccbccdccccdccccbcccccccdccdccccccccccdccdcccccccccccccdcdcdbcccdcccccdcdbcccccccccccccccdccccbcbccdccbcccccbdccccccccdbdbdcbddcdccbdbccbdccccdccccccddccdcccccccddccccddcdccccccccdcddccbcdcccccbccccbcbcceccddcdcccddcdccdcccddccddccddccdcccccccdcccbcccdcddcdcccccccdccdddccaccbcccccdccccdccdcccccdcccccdcccccbdcccdccbcdcdccbdbccdcbcdddcdcccbcccddcdcdccccccdcbccdcccdcccccccdccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccbdcccccccccccccdccccbccccdccccccccbccdcccccccccdcccdcccccdcccccdcdccccccccccdcccccccccccdccdccccccccddccccdcccccccccccccccccccccccccccdccccccccccbcccccdccccccccccccccccccdcccccccccccccccccccccccccccccbcccccddcccdcccccccccdddccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcdcccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccdccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccdccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccbcccccbbbcccccccbdcccccccccdccccbccccccccccccccccccccccccccccccccccccbccccccccccdcccccbcccccccccccbccccccccccccccccccccccbcccccdccccccccccccccccccccccccbccccccccccccccccccccbccccccccccccccccccccccccccccccccccdccdccccccddccddcdcedddbedddcdccccbedcbbddccecdbdcdcccddececddddccbcdbcdbceaedecdecdcbbeadbccccecddcccccddbccdddedcdcbbddccdaedfbdccbdedcbcbccbceddbbacdcddcdcdccccabbbcdddecccccdcdddbcebadcbeccbbcdedefcbddcdcdecdcbbebccbcbbcbccbccccdbeccdcbcecddbddddcdcecdbcedcbebddccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccdcdcddcccdccdcccccdcccdddccccdbcccdccccdccdccddddddcdddccccccdcdccccdcccdcdcccdcdcdcdcdcbccdcccccbdccccdcccccdcccccbddddcccccccccccdcccccdccdccccccccdccdccbccccdccccdcdccdcbcccccddcccdcdccccccccdcdddccccccccdcccccdcccdcccdcccccdccddcccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccdcccccccccbccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccdcccccbcccccbcccccccdbccdcccccccdcdccccdccdcbccdcccdcdccccccbccccccccccbcbbccdcccccdcccddccdbccdcdccccccccddccccdccdcccccccccccdddccddccbccdedccccccbcdcbccdcdcdcccdcccdbbcbcdbcdccdcdccdcccccccdcccbccddcccbbbccccdcdcbccdcdccccccccdccccbccccbccccdccdcdccccbccdcccccccccccdccccccccccccccccccccccdcccccccccccccdcbcdbccccccccccccccccccccccccccccccccccccccccccdcccccccccccbccdcccdcccccddccccccccccccccccccccdccccbdcccdccccccccccccbcccccdccccccccccccdcccdcccccccccddccccccccdcbcbcdcccbccccccccbdccccdccccccccccccccccccccfbccdcccbbcccccdcbcccbcccccccccccccccbdccccbccccccccbccccccbccbcccdcccccdccccdccccbcbcbcbcbcccbbccbcccccccbcdccbcbccccddcbccccccdbcccccccccccccbccbecccccccccccbcbdcdcbcbdcccdccccbbdccddccccccccbccceccccdcbcbcccccccccccbcccccdcccccbccccccccbccccccbdccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccbdcddcccccccccdccccccccccccccdccccccccdcccccddcbbccccccccddcccccccddccdccccccccccccbdcdddcccccccbccccbdccccccdccccccccccccbccccccccccccdcccdcccdccccccbcccbcbcccccbccccccccccccdcdcccccccccdcccccccccccccccccccccccccccccccccccccccccbcdccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccdcbdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccdcdcccccccccccccccccccccccccccccccdccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccdccccccccccdcccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccdcccccdcccdcccdccbcccccccccccccccdccccccbccccccdccccdcccdcddccccdcbccccccccccccccccccdccccccdcccdcccccccccdccccccccccccccccccccccdcdcdcccdcccccccccdccccccdccccccccccccccccccccdcccccccccbccccccccccccccccccccccdcccccdccccccccccccccccccccccdccccccccccccccccdcccccccccbdcdbcceccbcdcbdcdccbccccccdccbcbccbccdeccdcddccccccccecccccccdcccbdccebcbcddcdccbbddccbcccdccccccccbccdcbcdccccccdcccccbcdccdbdddccbccccdccccdcdccdccccecdccccccccecccccccbcdccccdccbdcbccdcdccdcbcccdccccccdccccccdccbcdcdcccbbdcdccccbdbdccddccccddbd]ekmg\``]_]_cY\^d^^mfe]cgjk\_ng]`d^b`ckgidghf__dki`lhhgdcfap^fdaPe[ad[jfWbedid`mijegb`_Y`dg^dYa^ffbi_cdbZid]e^fceeo_^hc_fWahde\baiadbhYjc`ii_gaZaa^le`dij_bj`d_a^nd\d]_ia`dae]beef\l^debbh`befjgeimhf]f__ggdcgf`eb]fcface`bk^agadYefd\`fdpcecc^becafk`aXibZ_c`cdddcccdccccccccbdcdcddccccdccceccdccccdcdbcccdccccddddbccdccdbccbccbcdccccccccccccccccdcdcccddcccccccdcddccccccccccccdddcbcccccbcbcccccdbdccbccdccccccbdcccccdccccdcddcddcbcbbdcdcccdcccdcccceccdcddbcdcddcdcccccccdccdcdcdcccbdcccccccccdcdcccdcdcdcbcddccccccccccccccccdcccccccccccccdcccccdccdcccccccccccccccdcccccccccccccdccccdcccccccccccdccccccccccccdcccccdcccccccccccccdcdcdccccccccccccccccdcccccccdccccccccccccccccccccccccdccccccccccccccccccccccccccccccdcccccbdccccccccdccccccccccccccccccdccccdcccccbcccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbceebadce`dbfdbdbdbcbdbcfeefeccdddbbbcdfbdccebccddbddfbbbdcedcedccfddbcdccbdbcededbdhccedbfbcbbccbeceabdcdadfddhcbecddcfbddbdedbdabfadccbcebdbdbdfbdcbddec`dbcdeebbecececdcadbcfcccabcccdddddddbcdddcddbdbdddf`facbfddeaccd_ddgeedccccdcafecbdegcccd^cbeeddecde`cccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdddbccdedcccccdccdceccbdddcecdebccddbccddccdcdcccccccdbabcdeedddcbdcddccdbccddcdbcdcdccceccdccccdcdcddcebdcdcdcbdcedecddddcddccefbdddeccdcdcccdceededddcbdbdccecdccccbedccdccbddceceddccbddcccddcdccbcdbbccccddccbddcccbddccdddcddbcddddcccbccdcccccbdaddcdccccaccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccdccccccccccccccccccdcccccccccccccccccccccccccccccccccccbcddcdccccccccdccccccccccccccccccccccccccccccccddccccdbcccccccccccccbccccccccccccdcbccccccccbcccdcdccccccccccccccccccccccccccccbcccccccccbcdccccbdcccccccccccccccccccccdccbcccccccccccccccccdccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbdcddcbcdccbccccccccccddccccdddcddccddccccccdcdccdddcbccdccccccccbccccbcbccccbccccccdcbddcddcccdbcccccdbdcdbccbdddbbccdcccccdccccccccddccccccbccccccdcccccbbccdccbdcddcdcccccbcbccbcccccccbcdcccccccccddddcccccdcdcccccdcdbcdcdccccdbcdcdcdccccccccccbdccccdcdbdbZa]b^ed`^jef`d\c[`i[^bai^aVmZWbgXc_]fi`ig`nc[cdjsWp^ZdbbnmicdXb`i^e]hgacf^\dbdaaXXYigbd`_aZfoic]ke`ahbgc\cblagacdfUd^fi^eg]g]_`ccicbhdhdgZ_aafcbhjhjd\adae]`djniaiabajtffck\^lkOebhcb`hbf\b]cni\cjYibc\pk`jabehgi_ggeckf\]kf_dbic_[he`bb`fecdedkafed^caghgj`[bccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccheacch`ed_[jhbad``fa`b_gdceb`ccaidbdfhedlcad^bg[fdgc`fdcdZdddcaiecgif__eceeddf_b_bjacd_d^ccad_ifdf^`d_f`_fg^b^\jh[cacafggccc_c_hg_ej^da^_bgba^cggn\dl]ia`jicZbd^dia`cc_e^^dcf`dfkhccb`a]ffcbdncbea`g_^`beddabageifbgf]dcgdg^fmde^\ccbhe_jab\dfdfgdecb`fggodel_ddccccccccccdcccccccccdccccdcdccccdccdccccdcdccccccdccccccccccccccccccddcdccdccccccccdcccccccdccccccccccccccbddcccccccdcccccccddcccdccccccccccccccccdcccccccccccccddccccdcdcdccccccccccdccccccccdcccccbdccdccccccccccccccccccccdcccccdddccccccccccdccccccccccddccccccbccccdcccccdccbccccccccccdccccccdcccbcccccdccbcccccbcccccccbccccccccccdccccbcbccccccccccdccccccbcbcccccbdcccdcccdccccbcbccccccdbcccdcccccbcccbcdcccccdccdccccccccccccddcbcccccccdcccbccbcccccccccccdccccccccccccdcccbcdccbcccccccccccccccbcbcccccccddccccbccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcdccccccccccccddccdcccccccccccccccccdccccdccccccccccccccccccccccccccccccccccddcccccccccccdddccccccdccdcccdccccdcccccccdcccccccccccccdccdccccddcccccccccccccccccdcdcccdccdccccccccdcccdcccccccccccccccccccdcccdddcccdccccdccccccdcdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddbdacbdcccddccedcdcbcbdbc`dbdccccaeddcbcedbbfbbbddcddecabdcbccccfddbdddddccdcdcbbeccbdbbccdccdbeedcbccdbbcdcdcebcdbbcccbeecdbcabdcccbdccccceeccabcccddbeebecdcddccdbbccdcccacacecdecddccbbbcddccccddbcdcdbcddfcccddbcccbdbbcddddbbbdccdde`dcaddcddcacdfecccdccbbfe^_bbkad_kch_mifbadg]dZh\^`f^]c_ageedbe]f`cj^ead]hiahe`_f]bh[cch]fdf]cjeditfe[dke^`^cfig`bdhhamol_cflha`c^`dcW^ada_fa[jeag`X_bb^c^_d]ne`iYw_`_`Oabgec[fi[gafdjgcliqYj`^iaagblcg^`l^fi^l]hbabddbe]afhagcnfd`mk`bdhdfehgchi_arfhcgicgadecc^i_b_clac\[cfk`a_gabd^bdZ_de^dcbg[ckb_dedg^bfbmf[jagbfdagaalb`ah]aa`ebe[agb[h[b]eheZlhd[j^nY^d\^`fZ[_f`aigei\begeagfjcbg^`hddccmfdeahf[hbbedf__bgZ^becm_`bcY`\daj_^_bd_oq_ef_fec_a[db`i_c`gglag]_e`cZaakcaW\cadhbZdabaghjhd`hb`ei`__c`had\^`e[g`g]_Zhkacejigb^j\Zd_ljaeadehfbbgd_elcak\hb__\iababZigd`ZefffYjlb\hcbijZb`diQ^\agZcamhc]g_bd^aphhcpb_abWaaf\dh_``f_e]fo[]acdfYnd\ahcaabbd\anhfbii`X^gf`WeVf`hdbdf[febghh`a^gahfljkdapb]mfeWcbk`dajddht_fdZbn`hWbm]lab]ei]gXji`boa^XUf^fcdgcd`e]gfj^_djdd\[b]bh\bdmnblh_lnbc`ecc^``ciffcdb^g]akfhccf`cieb_c_egonQodcZdk_Zafak\ec]beabe_ef^hcYflbZegah_me[pjcdje_g_ffba]kjkcjg_`ebehee^c\^ee_eh^fYcbhg^gh`_``doj^c^bi^^__^fTe`ee]ka_hghacnY\_e\dmfc^bab[^bljcgolldc[jfac`^iek_gfaZbgfcai^Y_iaieW[edjd^cib_]`Wiaggbbf[f`ab_^eV]^e]gZbjWkcjrhZadagd]i^jeboZhjebbg]dbbf]aajcio_^modaa[hhuaddak\acdihj_ehXe_dcbdia[kZf^TodbeYk`mdrWfVdmZ^hkabnXbbgfa`^fnmjag^V\^ja[]aYbcg_iegkUi^[[g_lgh^f_c`V\^gf^`le\Wfe`Yhmfha`bhX]\Zpkacgkrh\ig_oa]cccgabiV[e_hgfaX_a\d[dl\a`^g`mgZd`oak_^n]e_`eb[\`d^ag\ThahZ[bj[ee^qg`b\UbfcenejdXdUSicjhbmc^djc`ccegadfece`faedbcbc`dehdedc^beddefbfeedb`ffdbbegeegg`geb`g^fagcab`i``fgbab]bbd_ahkaccd^ccbbecafachb_gfcfaecebeeddfcabf`fgbgebfae`bceeacb`ab_gdffced_``cccd__e^cebaefacfadgbhdge`cci`gdbee`fa^ebecgfdbcb`gcabbecfdbf_cdddc^d_cflaic`bfabaafib`ce]a_d_ddeaahc_chbagbchcagcddcbccdbdcbedbcdbcecdcccbddcbcdbeddccddeccddbcdbbccdbbcbccccbccccddcbcdcbecccccbdcdddddabbdcdcbbbccbedecbcddedfdcdecbdbccabbaddddcbdcbddcccbcbcceccbbbabecddcdcbcbdcbcdecccebececedbdbdaccecbbbcccbddccccacdceebdcbbcbbdeccbbddbdacccdbccadcacdcdbbdccdccddccdbe^bdhldiV_fg\gnpnkfe\wbbcicZccZieVbch`dWih``]fWea[\fgRfpeSZkg`c[idfb_kee_\_ecjgi\e`c^_]jikggbdfbhb_]fac`iZe\b_l^oaceekn`afS`ghh^bZUZlbR_gcmhclgi`bd^knhef[dihc[ejegWkgghfo\[]ip`_gi`UofaidjV^dmnch`Xch\il`ceddi\`ccbf_h_caj]Recc^dbgeg_KgCa]cdaWfiddffem`_]]lfYZskmehb`h^cfe`X_cqfaiaddgehfce]cd_lfhee^ggZ_ajgckV`g`akjWcZejfl^_c]k^ac_j^Yaeecef`elgaf`d`dge^aaZ_ckZe]he_i^]_bddg]jffd_hdgXf`legcah\]dfdgdiZed_kg`acdcaeWg]c]dgibcZd\gfb__\agcccjlRfaZccnki_^d`kefdabbdhbXjenmkbd]gdbbaciee^dhfjdqfi`lcbWUe_fVba^fo\aid]h^bZqbfYfddbaaabb`afacdec``de``accfde`e_fe`feabdcdeaebbgeeedahe_haeecd_bbe`dbdecbfcfadecaf`dccaa^afdacbafbddacbdac^ccccac`bcdd`fbc^ccdde`eca^bcafadbbacedddcbacbfdefdbbdhbdacccdbab`e_bedbadeaccdebeadceabbbedbecacaeecadedabddjdgbace`aedhaceceadf``dcdaddecaidbadb`bcb\^f`hb_U`_dgiaidXg][hWf^^fZep`dZfbXhj]hcegkcec^ghjj\fb_\_dV]\]ffedfcneci`aeigf\b^eacbiaZ\b`afWdghbi`]cghdfapea\ag_f^gg]bddg[a]_gc`eji_d^^\c]Zkcd]a`e`gg]j^`lclff^WeW_`Zkdehebf]_c\gbfXaf]]henghYbecgh\ijboi_g[a^a`^nddmk`e^\]fi\gb_gajb_pc`gjadnagggdcljb[`i]]Yf`dbbcYd[h^]cN]hdgadh`nWfdvbfk]bg_bU_\ej^_\Z[mmbedfghh\bW^oj[ehedl`WfbdehjcY_^fhkeh_kZchegXb^Yjh[S_fhdf`Xd[f]l[`ggc_cebcuocakjqi_k_bda^pdd^balZ`cgYga`o^dhjhca]e_jc_e\kbfe\`ic`Zc[]hbbXaahaj_gfpg[ofhdbYbcbYpdd\maacj`daknVWYko_hl`o_^r_bac[fneadjecfd`ibf[h`V^nbbejf_gdpb``cl``_]f^cmhde`cmfgibejfa\a_hh_egi]_dgld^hccjdabcadge`ahada`dbiag`g]]a^eaddbde^__cff^d^deh^gg[kfcdee`ljeffafbec\baeaabbdgdja_ecbfgedhba_ddfb``^\be_ke_fcdeech_i`blcbbd[bf[jqicddgdgb`Zcdaaddcdfd^^d_^cllaahlk`cafcje`gbbdcefg_bkfdfaccfhbacbaeccc`da^eeeccc`dccbaeabbabdbdfcdcddebde`bcgdcfbcedcdbb`cdceddcdafbbddabbccecdcaea`dbacc_dcadadda`abade`ecbcde`bcdccbdac`eedbccceeedccccceaagbdcacdebdbecefdbecbd`_bdf`gcf_bcdcabac^bcdbedebbceebcebbcbbcfcbdecddfbcb`bddbdfcbae`adeccbcdbbcdbddcededcaaeeeab_cabcbccbeabcXj`bc]i]e`]jhY\[`aq]_lhddmihgfajahbdf_o]hle]]\ed^baa\X\[`[babcbpaiY]X^facboca`]gYc^_^i^qkYh`^`cdbe[mfjbhckbch]`k^`li[ddg`nW\enggeia[`edlkfda]lZkcff_npdkib]leY]^`ed_egra^[jea`cla]adUmWahb`qj]\d]mpekhdahSaac\fj]gii^_hpffTZb[j^ZZhe]sf`eaj\bgj^`en[]Xgcjkdh`cc`ccbcbbced_dedefbdfbaccabdcccdedaeecdcfdbbcacbcdagceecbbcdcbdcc`cfdcbacedeedcdaeccdecdbddb`dccabeadcbhbdbdcdddabbfdaedbeddcedcebbfaddfabdeddccbdccaadc`bddecdebceeebabbdebceeeedfcfdcbbgdbcddecbbbcdecdcebcbb`bacfedbbddcbebceddbebcdcccfcebbdcdddb_ebbeeccecbdcd[cgZpa\ie^ebekak_bb^cgob^dckefcR]`lgZk\dbh`jabc]]cXdjdhjac]cdflej^`_cgcd_fe\fdikrddmfdemhefadb`c^_]]egek`dZb`\cjhWcZdge`bc_cgajef]]ifa`dchd][]ecfrc`bb\fhejedc^`\ccil^bajdhZelb`]e^d`ccfUjfg\a_Z_lc_egX`cafhcdkWaeWk\f]c]l`gYbc[\ecfab`ehe\`ngahegYeh`acn`fk_ffhbbcccbbcccccbcbccccbcccccbccbcdbbdcdcbdccccbddccccccbcbccccbcccbccccbccdddbcdccccccddbbcccbccbcbcdcccccbcbccbcbccccbdccccbdcdcccbcdcccccdcccbccbcbdccbbbeccccbcccbbcbdcbcccbcccbcbcddbcdccccbdcccccccccbcccbccccccccbccccccbcbccdcbcccdcddcccdccbcdbccdcccdbcccb_WkNi[Tbdda^gm`gdb[d`Vbghc^obWa\m_ciVdiWbhZ[]MkdagehkNjfXhZi_SVke[Zbgbdcgmh^_if\`pV]^kRYUadjqojp_h]]f`e`kf_bhe]_T^`gheZgSbZUj[mdaiNnYnkhg^X\eb`\hrjpPekinghdieYk\\q\ida^gu]kX^mig\obcFf^ckfnk`dRZvejl]kegdocXgfR]f^]a[etZo]dYrjUl[hr`da[j`]ijebh_lhecauwbncncYegdcdaeabfcdc`fa_ddcadb`cebcfgbdeeefc_^bbbfbd^b`abbfehbdbehbbfgcaabcbd`baaceb``cfdddbd`cacd`dga`abh`bbeaaee^aadabbc_`cebbebcbafbcbede_bbdedfdc_cdceha`eefeebcadba_abcbeadddcec_bcafcd^ccabecbiccbbag`addc`dcbceadadb^b^gdifbb`cdcdcfdadcccdaecbfc`cbadbcdcbabcaffcccbccddbbccccccbcccdbcddcbcbcbcbccccbcccbadbcbdbcccccbbcbcddccccccccbcccbcbccbdccdbbcccccbcccbbbcbbccbcccbcccbcdcbdbdcdbcdccccccbbcccccccdbcccbccccbbccbacccbcbcbccbaaacddcbccecdbccbcddccbdcbdccccddbbbddccdccbdcdabcccccbcbcdccdcccdcccbbcccccccbbcdbccabcbccccdcdccccccccccdccecdddeccddcbdcccccccdcdccacbccbcdbcbccbcbdcccdcadcccdbcdbccdbadbcbbccccbccbcccbbcbccbcccdcccccbdbbcccedddbbcecdecddddccdcbecbcdccccdccbcbbbcdcaedccbbdbbcdccbbdbdbcdbdccddbdbcccccdbccccdccbbcbcbcbcccdbcdcddcabcdccdbbccdcbbccbcbbebbbcbcccccdeg\^e]`jY[kkmgim`^fo_gb_[YqSe`Zkshk`kY`jcji^cbbSgfjcZjhjhcZhbb^_ggh]gjeo]bbj\hf[b[ee\hcdddd^ddjf]rbgghjiiTfinamj[ldrcbj[[Z[banh^ipYea_[egehaacoj^k]]befgJcddjY_k]^^Xoekjg`al\dbf\epXdemee[_bYe^iZadjckjblbg\dgS^djZidi]cdaikoYk_U][\bNcikbaecjdf^^fwb]_`h^iiri[mlhggiadfkbk^l^```ie_eabg^bja]_c`_bf\bb]ghanf^ndabhic`jeh`Zgcegeedeg][c`fi]babibgca_de`aa`eahdeaXhe[cdigdhaa`cgb\f[ee_dgcaak^d_ce`b]aedaefcjdbcfickcbgfjfae^aceai_dcekbd^fgm`bgcdjlgcchcaededckhfi^_ddab_eb`[i`e^lcceeb`Zc`^[e^ao`ebeddf`b[laegae`ee^c`[ddb^dee^g`^hkbb_`hdb`ujmcnbn]b_hZZY_dcjjWajfep\pblhe[]`ifjWi]edfn_a\_c_dm`^adefZfed`hif^ed]na_g]o[g^]a]]vcjb\bdpkVdfeg`Z`e_ada`fflfSXdUjhk^lhib^bi_efh^d]`Vlddap^^_icSb`\ebf_[aVhVddooaf\\i^^mfcffjh^q[Z_fh`fnbn[]ga[e`]c`g^bgeeZejoedZ[Wl`ecca_h^bgmWdck_W^hd_]aav^tWgcggcejddgei``ik_ef^_bddeiaaci^aahkcacgp`bgid[ia_g^a]^dge^ebeafa]ahbkmi`g^e_c[YleXbc_d`alZj[Vd^_Zgmc`ij^gcf]eVn`[_omWZb^[ebmf`gae`^gWqdb[fahj]dReieZsZendh^_\_bYd^elj^i]W\_f^^`q`icWa^\icZejhakf[]obffce]eZ\`b`a_bWbiibhgX`ehd[gd_gec_g\][`gtl`_g[]^_\\a[WZjbddafd]Yd[a]fia^`hbadea\ccppc`bfg_fe[g\b]fgi`dgg`eflYg_aaac_a_nl[medhgbfc`dd`^j__djg]fi]a`\offgk\bkeabgc`]hgeba]haecefjbaddcgldkgZcdgcfd`hhe`^ife^ba_[gagb]a_`c[d[f\d`]df`f\a^bhd_akcng]eiccdgaa^fghgjf\\fh_a^fg`icf^dea_beei^]ef^h\]cedec^]eaX]e]``fbddf^^d\eZ`bl_`^g^cdccddccccdcdccccbddccbcccdcdccbddcccccdccdcccdccdcbcdcccdcccccccbcccdccdccccddccddcdcccccdccdccccccdcccbcdccccbcdcccbcdddccccdcccccbccccccbcdccccccddccccbcccdcccccddcdcddcccccccccdcdccdccdddcdcccccdcdccccdccddbbdcccdcccdcddeccdcccccccbccddccddcccccccccccceb`mcafs\falrfk_ka]cbhm\^bYgdXdhbdacuaZU\nZkGhg[omk[feil\`dk`fnnhjcdSmei^TcZlgqoep[]`^cq]cXaY|dV^gddqa_c{d`\^ccek^dafVmcfe`mhhqm`\U[gifdeaekq^kW\dp]}p`boh`ccjbhcsoSrS[kc^]LYg\bbaWdX\^Yabl^nkoTjemd_chX^j\nc`cYbe`RfuT`XX_Y^edb[]^pcZbf^_d]fe_ZdfYjmZdkOb\bm]Tf]l]c`jecfe`mfhdb\ci]bafbebb]fmdWcaWghh_mcghadpad^eY]_gfeaa]W[cif`p`g^c[bid]hkf_cc`bigad`_hgab_jchcfgfki`fdddgb`Vfdd^_i`]jbldbc^i]gi^kdba`jiYbf^eaMbbebbfdeafgeckg`a_^bac_fgeedj\dcaff`d_l`feegf\k`Yi`eh[cfg`c]_deb\rd^gaf[b]ieai`V__bidbhmfdadbaj`l\k_egk``fck`fb_dbjl_afdfcpeX_m^acdaj^\Uc]f`e_bjefihdiddee^dc\k_]daffeVg[b]^gkjhiZb^`bfchbj`Yaedl]beel^ee^ceZmgjb_eekblbf_\^[ad]f[dgbYb`k^Z`eff]h_bbegi^gWdhee]ackr]dbflcgVgiVbdae`iid_c_egh_ede`i]gd]d_as\i^af_^jia`bfgd^a]dghoh_jabb_ba_`]ejYgaei]ghfeeaa`eh]hf`[fel]l\eglfdaekZc`c]ijd`_[beVgddbemeafahd[ydgibbX^gc`a]ahie`fd\dgiqccdoWaffdc[`cbha^fgeeb`gkdfcbilaac]fcid^[bcjcd`Za\e[_icjldbYcrbci`f]jceclhc^_`foff`XaoeihfZb_Yg`__```bag_e]cdOgbddhgb`f^]a]_akaffi_dYeagX[dkge_g`ad`dekcg]c^ddfagfZm\fb`[hcc`_d`ddici_]dg[gda[ej\j`fcZ_d`eaceajhZbai^dfb`bbcif`Zaajbhea^accbgh_ka`e_ah\Zb_`j\ag_^f]ecf`a__becccef[`fgf_ajdgc^cccef``e]_iiegad_`b\akgbalifachbfgabhiZdaacd^hcfb`Zfebb^abc]]bfgdd[a]i\f`[cfgchih_gdc`e`m\bddcgkbdgbfccsd_^gaZ^[fdagi^^]`\ff^adgef`^cg\a^a_egc^bcihh[`ee`_eg`]e`Zbc_cdfj^dg\ccdccddcacdbdbdceccbdccccbbcdbbbcbbcccdccdcccccbbcccbacccaacbdaccbcccccccdcbbecbcdcbdcdcccbbccbccbdbcbccccbdecdddcddddcdddbccbbbcdccdcccdcbbecddddccbdcdaeccaddcdecdabbccbdbebccddcdccbcdccadcdcccbbbadccddcedcccdccdcbcabcebcccecebbcdccbccebddbecbaccdbbccbbcaafdc\ea`he^c]cmdb]cebb]fga]cbefddacaabcddb__af_a`a`eb`jeggb]ffabbcbegdelafcf^cebddddaabdc_beeeaf^cfg[gbfbgegdc\_c`dff_bfceleidebfh\eec`caedbbffcfdegbh`cj_hfddbac_ce`__bff`h_cddaee`da_c\_bbc`icecfcddee`e]`^aae`bhe_eededgeffcaec`ai_eca`^]ceehfdbdfbefahha__deccccbbcccccccdcccccbcccccccccccccccccccccccccbcbbccccccccccccccccccccccccccccdccccccbcccbccccccccccccccccccccccccccbcccccccccccccccccbcccccccccccccccbccdcccbdcccccccccccccdccdcccccdccccccccccbcccccccccccccccccccccccccccdcccccccccccdccccccccccccccccccccccccgdmgf\jodhbd_Wdeddebcjbbjbg^bfaefei]cdX^Zddg^ehgfagc]ndMk^Xiba`f`]gjbagc[eib^egVdbggecbdfeaiddcYf[a^bbge`cja]d`_c\cefebecgek`hafaiiS^`dee[`ibXaahhde`agaicg^m_ckahcZpklda^ebgfbfeiSbdj_a^\ac_ldom`cZZef]^ff`^c_]lZbfddgbgbekbkbbafega\ghaar_e`cboYg^`_f]_caii`^cbccbcccccbdccbccbcbccbdbcbcdbcdccacdcdbcbbccbccdcbccbddcccdccbcbdbdcbbbccbbcbcdcdcbbdccbdacccbcccbdcdbbdcdbccccdccccccccdcccdbcbccdbccdcbbbbbbdcccdcdccbdcbdcbccdccccbcdbddcccccccbcbdcbccbbddccccccbcdcccdccbcccaccbdccbcddccccccbcccdcbcdedccbcbcbbcccdbccccdccccccccccccccccccccccccccdccccccccccccccccccddccbcccccdbcccccccccccccccdcccccccccccddcccdccccccdccccbcccccccccccccbccccccccccccbccccccdccccbccccccccccccdcccdccccccccccccccdccccccccccccccccccdcccccdccddcccbdcccccdcbcccccccccccbcccdccccccccccccccccccdcccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccdccccccccbccccccccccccccccdbcccccccccccccccccccdcccdcccccccccccccccccccccccccccccccccccccccdcccccdccccccccccccccccccccccccccccdcccdcccccdeebbedebbccdbde`cgdbbbedbbdbadececbdab`bcdcdccddcbbcbcbcdaecbdbcccddbgceabcbdcbcacacdecbccecbadbacbccbebddgdeaebcbcddcbddcadbecbdbdbcabeabcccebca`dcdbebdacccdbddcbdbdccadcbcddbbdbecddccebcbacedacaefddbeddbbddbccbdcddfcdcbcbdddddbbacbdaddbdbceaacdcbaccccdcccdccccccdcccccdcccdccdcdddcdccddcccdccccdcccdcccccccccccccccdccccdccccccbccddccdcbcccccccccccccccccccdccbcccccdcdccccccccccccccccdccbccccccccccddccbccccccccccccdccccccbcccccccccccccccccccccccccdccccdcccccdcbdccccdcdcdccccdcccccbcdcddccccccdccccccccc\Yj`teb][`ihj\uQTsajl^\hm>aoT^oheYN_R`O\]gXWAeNqUccUshAZU]HayUpXav`gelZ8K_Y\fZi^XqrP]wcTR_Kv`WKcL_eV`me`i>]jLcf:]gWwb\`UmaeiV\_lvPdZooTzVtjXKKfMkhYobKz3tiZ`_hqNls]wdlkuMuYWFViGwWgvffjjan\ZlooM[UkXZtbe=fU?eVipp[j]ylGnYghBPtWe4cqrk`}Med_\Vr}]PNZW@jc]Zycccddccccccccdcccdddccdcdddddddccdccdccddcccccdcccccdcccccccccccccccccdcdcccccbcddcdccccccdcdddcdcccdcccccccccdcccdcdcccdcccddcccbcddccdccccccdccdccdcccccccbccccdcdcdddcccbcccccdcccccdcdcdcddccccccccbddcdddcddcbbdcccdccbcdccbcddcdcccddcddcccdcccdbbccccccdcid^feebdYZeo_X^gee_`cedb`_f`h[Xmeb^ca_a^bed`icc[`ccmceg[kebf^aa\ac``Y^ab^cZahkle_maci_c[]ab`iakXm[n_abd`pb]jjbbeeddgfeahdgkagel]^eg[`_cabqe`eggcig^b[gc_ed[hchcdcaYdgbf_ba`ackbeacjg^d_dli\oadgl^ia\bcdff`_afigfgWeibd]ggdXdif\feb`[dbeh`ddfebc[`ia`Xfh_jW`Y\`_\bdbdbdcbcccccceccdccccacdbcbbccccedcdbcdccccdddbdeddbddbcccdcdbccdbccccecebccdccdcdbcdcbbdccccabcdacdcccbcccccdcbbccdcddcbccacbcdeccedcbbccdbbccdfcbbdbdebceecdccbccbdcdccdeadcbcddcccdccccbbcbccccdcbebccdbbcddcccebbbcdddecccacbbbbbcccbbdcbccdcceddbbbcbdbccdqibghfahcSZ`j`\ea`je^jbebeecZbidmnocl[e_jee_VibZcUgaZ]jfg^`di]csedm_\c\kd_ahUl_eWblkXcZcg`cege`kc_cnlhlf^bbcja^`bd`eddcdgee^ec[amg`fce\ebdfa\^chdjYf_fg``h^hf_be_e\`af^afdaceloaak_ebbZdafgj`egjaZ``jagee\`\dbig]\c\W\d[k]l]e\af[jkcb^_^i^f_\occ]e`geUbdipkckdab`cbcccccdbec`haebfbeegacedbfdd`_cbdfeefccdfbc]d_bafc_f_ha`a`fceeeabadf`fh_dejbeabbdefbb`dfa`eacibcbdbddbdecb`haabgcb`ebdgfeafcd`g]degcdddedaaddbcaea`b]fcdedcbdcdaicebccbcebbabdeidd`cebbcc_dddgdcciddb`e_aaabcbcdcdc_cddfcd_dfeaa``ciccfb``acd`gc`dbbacdedceac_bcbccccccbcccbcbcbdccdcbdccdbcccccbcddccbccccdcccccdbccacccdbcccbbdcdccbccdccbbbcccccccccdccdcdccdcccbdcbddcccccccddcddbccccbcdccdccccbccbccdcccccccdccdccccdcccccccccdbdccdcdcccccdbccccccbcccdcccccccddddccccbbbddccdccccddccbcbdcccdcccdcdcdcccdcccbbdccdecbcc`]h]qcf`X_]afdbhgdcace_bcjgc`ahahn`i_echbej`cfdf`\gd`qhh^`Yfc`cdgdfY__]ff_hhdbcddfghcjd\hdefe^mf^ddjfb`dh\]d]_^eqbo`bfckb^a\hbUcc_iedfbddc_k`ef_\chc`\`geaidnhdkgelaoemfddkbfhbckheagbffZd]lhhkee_Zcbieg^^egejk^`fbmegjb`ck`hcZfgka`\_^Y]bg\aceeacjbgcd^lc\d^a`[jan`Zhdgha_kbfckYiqd_W\e`k_\cb[\dgni`efmegeg^]_[``___bhag_Xg^b[d[f`aZ_lfd__jcfb^iY^\fjhgh]aaobhf_emkigfee[_ckj`fh^i]beebi_`jj`akob`jc^]fd[i]`\dh]ajdmbbuk^fqpicbd`fha]elhbjbgdaiXcf_dVclbghh`fqbe\b_b`__ZaabZgk\ae^joadcSec]Ybbgjkiceb]cida^gmb]dfbiUih]plddnbgp\n\sW^c_qdZ_jih`jad^t`m]iggh[__eWp[S`lbf[c^zfiZ_fhacfalZ]ahc[`g]ej`he^^glh^[egckWYdnWZjvliafX`yhj[`Yja^`dc]UjfgebaZof^^^felmZjY\bdrf_fmp^e\e]]LlcY_cWa^febffVR^coXUb`_jka^dp[h^\nhcffemUeVd`^`oPb]YZgVuml^oiph^hcUla\[bZlcfdkcgmc`\bW]r^d]fl[]`hh^ieddaie^Uhul]b`aadod``dabd^l^`e_jca`fddfieab^]c`_bd_da^eagabd_ae\^eg_c`ca`beclbcc`cbj`bdf^\da^cfid`bid[e_\f[]ffae_egbafbcg\d\gacffd`bja``hf[gbdeeaeecia`]b_^e_facc__ajaifb]_abb^d\jbecdcof`g\]ddcabchebb_be``dYb_fdcfkeei__`k\fblgcf`e^_`af]bhbgbace^ccdZ^ecedhchde`^gdc`bkik\Rcmas`^baZnefkseTYbr^jib\\Ted^dbjike^bhniahf]jfhgej\hoicg]efpqo\bZSdfjihkahp^Nda^bYen_gf_bcl^jkag`dfimfcfjpYmZkecekPWlcbdijmq[f]dsgfknbpeUmSfd`j[[fdNcU`PnfkegYb\f_Wlb^X^_fe`etjggdniahY`gVmh\sdegYehY_VRabLS]nQmdgcg]ecn_i\idedW_icZhnipdYWWh^_Zk\`\]_Wjlc^p\bjceabecld[`m_fcjd_baa`_gb_^cdb__odacYZadh`_eck]d]mgeadlbfe_^_l^aa][cbcjbmacih[iefdkekc_lcahbhf_`coh^`afg\eb__g]\da]Y_]eann_eefcc]ghd]biam]ghgffibRjaffdlmkc^fYfig`l]ecdk_]cfbah_iYdd]UbcjbdXckcfd^aac^fjefabdnhe^d]fiedjhg`c^lcabaf__i[c`]ebchhbc][ccch^cc`^^iadbc`[``heb_eff]ddgcca_]\`c[\ki\dbd``dcaa`_c^^cc^j`g]becidm_ee]ccacchgf`efb``ndeae_jccdffb\bd]cfbd_hfde_hb^fefbaa`f_i_cabd`ecb`fdecgha^bc`fa_bi`fhdkhmYd`eufadc`cdecbfba^cagb`kc]i``eieZhc_dcgd]idccacf]cgbheid`edd^jie\dj`gecai_i`ik\`cdfa]ebcdde_be`\gggchcidde`dccccccccbdcccddcdcdcccbdcccccddccbcdcbbbbccbdccbbbddccecdcbdcdcccccccbcbcdcbcbcdcdcbdbddccccccccdcbccccbcccbbbccdccccccdcecdccbdbdbcdddbcccbcdbbccbbccccccccbccbbcccdddccddcccbbbdcbbcbcbbdbdcccbdcccbbcdccccbcbcbdbcdcdbccbbbdccacccccbccccccccccccdbcccbcbccdccccbcccccccccccccccccbccccccccccccdccccccccccccccccccccbcccccccccccdccccccccddccccccccbccccbcccccccccccccccccccccdccccccccccccccccccccccccbcccccccccccccccdcccccccccbcccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccbcccddcccdccccccdcbccdccccbccbdccccedccdcdcdcddccdcdcdbcdddccedddddccdddcdccccdcdddecccdccccddcccccccdddcccdcccddccdddcdcccccdccdccdddcdccdcdccccddccdddccdccdcdcdddccddccccddcccdccccdccdccdccccecccdddcccbccdcdcccdccccddcddcdccccdccccccdcdccdddcdddcdcdddddcccdcccccbdccddcccccccdddcdcccdicc_bqcfkkdWkaZabfajd_giiXgkhbcg_g_TgebgcckcaVgmd`geecX]a_h]ncf_[hj_c[fde^^TUh[icdg]ZdcVddgmlj\cj]X[bfbdjigbj`glibeifd\j\^`eaTb^i``g[j]]^[ccZhc]h{ged]`]]_dY^[dbgeahkhi^i^d]ed_Xihj_[md\bmenmaiccb^Waab\j`abbcockc`W\\[_fZ^`f^ajefhgchc\jYbbddahdqhefkadfb\a]`cedbcdcddbcdcc`cbdcdeccddecdecbdbcbcccdedcccceccbdbdcccccbcdccbdecbedddcccccccdebcccddbcdbcdddcccbccccadccccecbedbccaccebcdbfddbdbbdcbacbbdbdacdccbddcccccabccbbddccbddddcdbcacacbccdbcdcccbcdccddeccbdcddccccbdbdcbcdcacdcbdbceeccbbedebcddccccbdcdebccbcfcacecccccde`ecccbdcdcdabccddebdedccdcccbdbbdbcecddcdbbcbcdccc_cbecbbdecfcabccbcccdcbceddcbbcddcccdbdccccbecbbcdcbbacdcddbbebdcdbcbcadcdcceeddececdcddcbbddcccccaaeabddbebbcbcccddbcbccbacdaedcbdccbcdccddccdddbccdcbbddcddbcbacecaaddcdaaacdebededccbddedbdceb`ddcbedcdZc`aab_pc_de\kjhiac]edcbce[^``^[j]bnafd]ca^b]abbbk^ed_j]^a`baf^_ggabZdfck`gblgl[fo^fbhdbdaaW_keefqj^bcjk_dl`e^bX]^[h\_d\ac`fd_f`amYX^^h_eUbhlb_c`\e^Y^cgnp__iZ_pfctbsblg]`cjhgbgkWei\Sj]g^h^`b`\kadjecfs`dfa`og`[c\ei]fpfWYoajgb^goic`]ac]dn`a_fcehkabgfhegche_egg_df^haeefbbc_bech`^bcgdccedfcaadgbafdbeeafaebdfehihd_badeacceaiccdadg_accbbfhebdceigchdbdiaha`ciafgdbc_cfb]cek``h\bcfe_hZfe^bdaddcebhbbcdi`af`fhfccbbjgafahZac`dgfebaecae`bh_`b`acaca`bhbc_cdbbeeacc`ggggejefada`Y`dac`f_c^`e^efaca`d`ddafgbcabd`cb`ccaegdaefhXaf]o[]WdY[eZdbefXd^khd[dhcfiY^daRVhagcWltQ[cefci[SZnWkZ^ma]fcdhXYeb`Vf]jca\ZS\clc[snagm_cbfnoklbj[hiighj`ZnhKW_c^agbjbjerdrm\uhl_WhZkriib^^k]`Veani`ge_]bgdWfdUr[UYd^oaa`mfg_kfjgbbgjYjkdbYa[VkpjbnSf]Yabeogf`[eY]fXil\if`YZYaedchh^v`l`_jkefegg^_bhh_j]]ilUrghccbbbbbc`ccdcc`acdcdccfbbddccccccbdcdbdbdbdcdcbbbccbccaccccac`acec`cbbcacbccccbccdcbccfcdbdccccbcabbfdc`bcdabbbdcddcbbabecabbdcddaceeddddbbbcbccaecbcbbbacadacbbbddbccdddcaecfdbbdad`bbcbbbdddbbccabcbdccdddcacccdcbdcabcb`_ccadcdddbedbcdddbdcbdbaecbbbbcbdaadcZ^jflgbc]`VoVdjbUh[\`hZWcxdabcl^hWakZ`e_ib\mia]b`f]YpVWfa_il[`_b_a^`j[YWgckk`bgfXeXesbhgdd`]e^gefa`bgY_`ljSbfYe^ZbiiagfecaS[eqi[\eXkkehkdjbdb[Xqk]edjiZi_a`ghce_ctb\aadc_ofcoadpcYehdTcejdonfcj_[nkf^fXcfebn_ab]b\dcdTgif`ac^h][Y_jnKwcKWhd\glc_gfbd[d]]dpijqhd]ccbcbdccbdbcccbbbbdddccdcdcbccbcdccccccddbdccdccbcddcedaccdbdcccbbccbcddddccbbcbcbcbcbbbcdcccdcbcdbcccbbbbccbccccbcbdcbcccdccccdbcccacccdbcbcddbcbdcdddccdbdcddbccbbcddbdccbbbcdcbccdccccccbddcddbdccbcbccdbdcdbbdcedcdcccbcdcd`ccbbcccdddebdbcbddcadcccdbccccca``hb^gecgcecjdbbc_agfacedfcidbe[abacfcc`ab`bc_`bdbbee`bbadddebidd`dgjedf``kedbeaab\eddc_effibccbefcbhe`chececdbj`fbh`dgc``_jecfaea\daffec_ge`adddfggddb^c``_`edebedad`ejeai`ddcgaccccbgdechbgc`aea_c^ecgbbdb`dcab^dZfgd_cabbfcfaac_iag`ccae``f`fgf^cdhac`acabfafbc`ccbdbdddcdacdcbccca`bbcdddccacdcdddccbcccdddccbcccdd`cbcbecbbbcccdcbcbdab`bdcbccceccbcabcbdcbbbbbdcbbacdbbbcebadacccdddcdcbbcdbcccaacbbccdcacchccccccccbccbcbbbcbccbccbcccebcbbbcdccdbccbbdddccbcbcbacdccdbdccddcbcccdccdbbdcdcbcbbcd`ddbcbcecbccdccdcccddbdbccdccdbdcccddcbdceddccdccccbccccddcccbccddccddcccdccdccdccccccdccdcccdddcdcccdbdccddccccccdbbcdccddcccdccccdccddddcccdccdcccccdedcccccccdccdcccccccdcccccbccdbdcccdbcdcddccdcbccddddccdbcccccbdcccdddcbecccccccccdddcbcccccdcecbcccdcdccdccbcbcdcccbccdcddccccdbcdcdccccdccccccccccbcccccccccccdcccccccccdccccccccccccdcdcccccccccccccccccccccccdcccccdcbccbcdcdccdcccccdccccccdccccdcccccbcccddcccccdcccccdcdcbcccccccccccccbccbccccbcccccccccccccccccccccddbbcccdbcdccccccccccdcdcccccccccccccccccdccdcccccccccccdccdcccccccccdcdcedbccdcebdccdccbbecbccdbcceddccccdcccdccbdcbccbddcdcccdddbcccbbddcdcbccdccbdccbecdccdceccdeddcccbcdcddccccdbbbbcdccddccccddddddcbcccccccbcdedbbdddcdfbcceddcccddbdbcdddcbcdccccbccccddcccccccddcdccedcccccccdcedcccedcdbcdbbcbccccdbbccbcdddcdccdcdbcddbecddccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccecfebcedeabbhe_dc_`cdddab^a`aacjdcdbea^daabe^aedff_cbh[gefeeece__dd_aaabc`bbfc^eebc`bac``bbecaf^]`dec`bbeafbbdaee^daccbfa_fbcd_cbchdfbd^`ffcccehb`cddae_accaahcaaddgbb^^aa_beeaccabagegdgiafccc^cecedaha`gcad_addea_cm`b`dkdcd`gfbcce`dahecc]``aaaeaccabacdaefbadccdcbcdcdcdcccccccccdcccdccccccdccdccccccbccccccccccbdbbcccbccdcccccccdccbbccccccccccdcbcbdcdcdbccccccdccccdcccccccccccccbccbdccccdccccccdccccccdcccccbbdbcccbccccccbccccccdccddcdccccccdcbccccccdccdbdccccdcccbcdccccccccdcccccdcccbdcbcccbbccccbbdcccccdcdcccccccbcccccbcccccdcccccddcccdcccbccdccccddccccccccbcccdcbccdbbddbcbccccccccdbcccccccccccccccbbcccdcbdcddcccbcccccccccccccccbccccddcbdcccccccccdcbdddcccccdbdcbccbccccbccccccccccccccccdccccccccccccccdccdccdbcddccccccccddcccccdccccccccbcccdcbccccccdccccccccccdhehh`k`gac`[hf\hb_d^gV]ckY]cgghei_gcd^\ffZkjbbqcf`Y`fejb^[`cdf\_`bfc_ae`aa^faee_cjedbe[iUcf`]`kdd`m^fmhdahfbg_^cda_ahh\lgelbhX\gbbhc]]Xh`c`^efdg_a_f`\abhmg__]ejhced_g\cZdcejajdjikdm_ggde]^]bdlkb\mcUfeaYb]dgbngcegjg_de_^egX`gmg_\^Zea]\_^eae`efafbhgg`cddckn`cccccccccdccbccccccbccdccbcccccccccccdccccccbcccdccccccccdccccccccccccdcccccccbccccccdcccccccccccccccccccccccccccbbccccccccccccccccccccccccccccccccccccccbdbcccccccccccccccdbccccccbccccccccccccccdcccdccccccccccccccccccccbccccccccccccccccccccccccccccccbcdccdcccccdccccccbcccccccbcdcccdcccdcbbdcccccccdcccccbccccccccccccccccccccccccccccccdcccccccbdccbccccbbccccccccccccccccccccbcccdccbccccccbccbccccccccccdccbcbccbccdccdccccccccdcccdcccccccdccccdcccccccccccccccdbccccccccccccccdcccccccbccccccbcccccccccbccccccccccccXgkWf]`_degdbec`efeiYx^ZcUbf^b`iViheeec^\iaef]akdenfldTigdhag[cla`\W[aj`jadk_`ihXa^\[j]fi_f[mZhl^aomgceee]`dmhbb]eh`fiaeYfWljebYlcYkejgkihhgabf[fvnf^sra^dajc`fjZ_ijai`b_jd^b`cXf^Yfj\cY^a`ljbnc]Y^\njV`ljabgWdeZ^kdQgZej_gg_g_mVefWq_h]cgTf_nYgem^^][qk\rf]\j_\dcccccbccdcbccdcccccbcccccccbccccccbccbdccbbccdccbbbccbcccccccccccdccccbccccbbcccbddccbbccdcdccbccccccccccdccbbebaccccdbcccccbccbdccccccbccccdcbcdccccbccccccbbbccbddcdcccbbccccdcccccbcbccdcbccccccccccbcbcddcccccbcbcbcccccccccddccccbccccbccbccccbccccccbbcccZb`ctiff`dafYdgZf]jg^saXeil^aakmWi\cmh^Xfe^UZ]mZhq_Uai)cZ_feh```hclbYc_e``^ic\\km]Zi_dlgiV\_i`lW^f[rkabik^\[bhie^``fffe`Xdbkfad`cmp_ekjm^b]nRfheev[hig^gfdgebXma`lX^khse`TVe[iTagVXegkgf]MX\vmcaYfkdp`]beimlU`^ibfehjJ_r]ajapicXacoaZc`ndbfecebwdXf[b\omdjkq^gccbccccdbbccccccccccccdcdcbccbbccccbcdbcccbcbbdbdccccccbcccdbccccbccccbcbbccbbcccccccccddcccbcbbbcccccdccbdccccbbbcbccdbcccccdcbcbdccdcdcccdcbbccdccccccdbcbcccccccccdccccbdcddcbbcbcccccccccbbccccccccbdcdcccccbcbccccccccccccbcccbccbcccdcccccdbccdbbbdcbdcccd^icm]fd`dgn>nnf__q`fefaecng]dfXb`le_cc[doV_b]hi`fg_Zcfchgkogbab\sYofeh_m^`chigwbn_icl[hb`k\gfqad^eWmj\``mh\Wekhgn\hfpl^ZgijYa]hieZ]`nd`incl`lin^kfagibX_XeUbgdbam]gZo[b_oa^ckf^g`r[]gkofeZXeaiipbbeeidcfhcdagn_`af]YofIfS`f[e^h^obcjcVk[Zabo]Z[f_`hadfXi]`i_l]idccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccb_ffbg^ff_be\me]d^ece_]bc_[hdb_ak``i]c_dee_jdgbijji`^ekdk]dg[b]kdh[j`_gbbe[d_fieblacXcddaff`h`bddc_dfj`abh`e_`gjm[j_c`fhaa\e`j\d^d\edibebekcee^b\dbf_jZeb`Zcbedai]aabp]Ye_gccale\ck`]eibageaj_ffdha^c`efZccaagfZheabWdjX[Y]l[bXhaieZhbW``d`db`i`c]W\jb`S`\e\`af`occcccdccddccdccccccccccccccdcccbccbcbcccbcbcccbccccbdccccccccccccccccccccccbccdccccbcccccccdccccbccdccccccccdccccccccdccccbcccccccccccccddccccdcccccdccccccccccccccccccdcccccbccccccccccccccccdcccccccccccbcccbcccdccccdccbbcccdccccccccccdccdcdccccccccccccccccccccdccbbcddbccccccccccdcdccccccdcdcccccccccdcccdccccdcccccccccccddcdcccccbdccccccccdccdcccccccdccdccccccdcccccdcccbbcbcbcbccdcddcccbcccccccdccccccccccccccccccccccccdccccccccddccccccdbcccbccccdcccdccccdcccccccdddccccdccccccccccdccccdcccccccccdcccccccccccccdddddcccccccecbbcdccdcdcdcdbcdcdcbcbcccdcccccbdcccccbdbbddcbcbdcccddccccdcbcdcccccdcccdcccccdccbccddccccdccccdddccdcccdcdbbccccbccddcdddcdccccccbbbbdcccccccbedccdddcbccdccccbcbcccbcccccdcdcccdcccdcddbddccccbcccccddcccbdbccccdbccccdcdedccccbcccccccceccdcddblkcmdgsc^i`iI[aeaghm[x_\`ajAWr_zskfcch``fabkTu__gffcYhfje\\^iYrame`kigfbS^]k`Ygf]ZfauVohsa[ggnnfcfaredY`hgi\ZceVkif]hehYdfogdiZ]Zva`lV\S]fhbgbcfm_^bisfjo_^a|Thcbf`b\pcW_e[g[fYdf^[`\nXeU]i`]iiwcWi_^dfha_`a][^gWk[l`Ri\c^n_cncbF\fjf[cQasudYo_YaZlV_RXejjgbcQgccccccddcccddccccccccdccccdccccdccccccccccdcbdcccccccccdccccccccccccdcccdcccccbdccccccdcbcccccccdcdccccddddcccdcdcccccbcccccccccccdcbdcccdccccdccccdccccccccccccddcdcccdcccccbcccccccdcccdcccccdcccbcccccccccccccbccdcccccccccccccccccccccccdcccccccccccccbddccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccbcedccbccbcbdbccccccdccdcddcbcccbcbcbcccbddcccccbdbbbccbdcccccbbccbbcccccbcbcbbcccbbccbccccbcbbdcbbbccccbccbcccbccccbcbccccdccdcccccdcccccccbaccbcccccecccbcccccccbbccdcdcdbcccdcbcbecccbddccccccccbdccccccbcbcdccbacbccccbbccbbcbccdccbdbbcbdcbecccdcdccccccccccccccccccccccccccccccccccccccccdccccdccccccccccccccccccdcccccccccdcccdcccccccccccccccccccccccccccccccccccccbccccccccccdcccccccccccccccccccccdccdccccbcccccccccccccdcccccccccdccccccccdcccccccccdcccccccccccccccccccbcdccccccccccccdcccccccccccccbcccccccccccfhgmemjgdbdgnXcVh\fibe[^m\bbW\ee`kgfd`im\aeS^Xfjchq_]dXaeidejaTk]h\aEda[ho[ehhb]]fWa]WjicSe]^f`eePfhabib]UeadfZijia\bicmk_Ysefa[mjnectnstc\na[dUoi[e[`b[cbfgacjfbfSbcpik\X_dmZjdgg[fi]bf^dcrvk[h`^[[eccc_ZbchTjm^^kmgm^kki^dfibcq\i[dadqaq\dhbgij^fZc]mjdo]bVkl\ccccccccdccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccdcdcccccccccccccdccdccccccccccccccdccccccccccccccccccccdcccccccccccccccccccdcccccccccccccccccdcdccccccccccccccccccccccccccccdccccccccccdccdccccccccccccccccddccccccccccccccccccccccccchmk\a^SigUWldV[^`elXas`a\[[wfdilLhsd_haeSec]oioe^clrjm_bf\rVfkcucWdpLmfXdb]cOfb_NZhbQfiipXdg\YbhYTah[_lbaaa_X_W`dhddQ`ilnlfqe`^eedqnhfqblid]mV^i`bmh_]`ke``^oa_u_c^xS]\`gohfe`c\]dj_mVK_\`j`\egf_`Yd]ZYenlcjc^`l\]doXccUr]mm]oajnkZZaZ`hej[Zihige\^deYgXjne]m`jfdcdebccbcbbbdcbcdcbbecdbdcbcccbbbccdcdbdccdccbbddcccccbacbccbdcbbdccdcccccdbdbcccdccdcbbbbbccccacccccbbcccbccccddbccbcccccccbcbccbdbbbcccbbdbdddccccbccbadcbcdccdcdcccbbcbcbebdddcccccccdcccccccccddcdcccbcccccbcccbcdcdbecccdcbccdcccddccdccccccccabccbbbcccccbbekg``d`dfa\kb`fb]hih]ihdbgfgd`]`ceacbieaccak`bgibdckcdfcgcchbe^aefcgaeadge_dbe`afcdifb__dgjb`egdagc_ibbbdad_bekbcbe_faad`dZbhi`ce^c\fddi_`^]ea``eec_dfbk`dg_gdbdbjebgefa``ecb`bfce`l^bckgafcgaehcbcdfdd__bcgd^c]b_`edcjbcfbackab_egc_eagchbaief\chf`figbkagbgccccccccccccccdcccdccbccbcccccccccccccddcdccccccccccdddccdcccccccccdcccccccccccccccccccccccccccccdccccccccccbccccdcccccccdcccccccccccdcccccccccdcccdcdccdccccccccccccdcccbcccccccdcccccccccccccccccccdcccdccccccccccdccccccccccdcccdcdccccccccbccccccccccdccdccccccbccbafdbddcdeeacbfbdddbdcdcceceddcbdcbbbcbcagdccfcbdddbbddcceecdcefddddc`dcfcbbeaccbdedcbbccdeedhcfddcededccadcccdccdefeffacfegebecabbcbdbecfefcbfejgbi`dgbdaddeceedceedefbc^edbdeadecadbdbbcddfbbdebe_dfabbfbebefbccabcbc`efbaadcbabdcdeecbccdcbedfd_abbbcdcbej`X\X]raUX]]iQZ\i^jml]_zfFhU]_kcWXjdW\brsdjKWeT]hoaebWisfreeeScQbjac~j[v\^ErVonklrX]acjW^^df[ekJbdX`jljXrCii_cc``rbjc[aae_kdncccseiXc_i_i]`ZdmupkeejN_g]efcamn\PlfXe`bPhcdlchgphZ[kiakpemsboOach_hacqaqW^XhT]bgWmfc]Zbe`Scy^d`Zbn^cihgagd]dkfjba]aa]_Kh_ajmdnfr_dbdeddcbabddbccecd`d`dcbdedebdbgbeabd``cfecc`eaebbb`eccc`becddabfddcebcga`ccbccdccgdbdecbbcccdababbcacfbcffb`adcfdcbabdbbhecddbeadecd_dcbde_ccbcbdcddbcddcacfbcbgehgadadcdbccbaceccbedc_bbbdbch_eccaceadcdebddcddb]cddcbde`caddddeeddcdac`ccfdi`dfgbddc`cdb^bccdqhoi]d`fi\XjnkWX]`fdcWfj\p_y\bqk_dWUljk][g]^Wk\ckieiwn__effmVnbgV^m][faf[abk^nTagnnj`kt][]bcZ`g]dNcqdd``pn\dda]ee`d\fWsZhg]cZgb\hfTcOQfTbaZel[bppjcZeXfee\ca^b]bbw[hh_qj[r\hhieXb\ie^ffT^`^ffrZfhie[fmcVmh_[bgau[^cZ[eOhrbcfguf`r`ddgc[`iu`fYbkj[ajaqcgaj_^kaas_\^tWt^phhccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccjljcdTby^YfjccU`gcs\^o\X[UaggwndUVi[SfVg]ke`Se`feabbgeT]^_fcm`eYcYkajf^[\cZgcnbd`_bfdgp^bgVhdn_]^bcjdWX\dda]]og^^mbla`achcja`^uZd^lj_]cgeil_gYkj]xngh]ceQ_a`wjk`Zj`wlX_ZcgleYe_dj`__^b\S]hfa\^d\okcfWgcNgnn_idZZj^iihllJ^bodbe[eYf]fcVfd]_mdWm[aXSabg[^W_hcpqecegg`_\Xha^\`agXa\jcail_dmfRf\`egaY^e_Z`cqkejV]l_fdo``f]ka[p_]a]iX_fbaldaq\aPgZkjimc^cb`l^aXde[doWadVdkjdYkJcc\bc\ge`_]``]dgjkt]g\ngiZf`kidb_]]boflacjTYe_fcdbgiaZhc^c^]Wkcefcbdld][ddfijecf_bWadejh^glahXX[g^\cfaj`]d]fbaYdk^b_`eeaiehc_ic^bfjg_hh[``j`d_dhcbmkpcdccccdcdbdddecceddbdedcbbcbcccc`decdccdcccbcdeccdcccccbbbdcbbccbcebcccccddbcccddedddcbddcdbdccccdcccdcccbcccbbcbcbdcccdcddcccdddcbddddddebdbccdcccccdcccccbdbcdcccccdccddcdacbcccdcdccdbcccbcccdcdbdcdccbcccdcddccdbdbbedcdcddcbddcccccabccccdddbcccddcccdcccdcccjkibeeie^aaj]]\Ygpceo_]bbwchmg[\a[dfah`[ka]\o[kWXXhibW]Tn[^inilbhZchT]i]^Zxechkfl_d`Z_i_amhh\WgYjcpabcdeVcTqose_X\fWdhe_fgi[dplBlfeccrTyb^`fZeYc_Sobh\V]k`Kt_^bhclhNV_^efeakc_Zr[`ftg`kildjg_]ec^oiemPcg\[]d\`xjgGa|PMXbr`e_dgaaag_f]ehe\c]bcR^\UagUY\Z[eVY^cibdbc`acedcaaddecadccaeeebdacae`dbfbcccecddbbcaddbabadbdddgad`baaegbedbcaeedeecbagbhe^bdfafbacecc_cfdabcbeegcdaeadeddfbcbd`ebdbfad_edbb``bbdccddbddgaacccddgeffcdedffgcedcaeadb_ae_fccef]bccacaacbeaeb`bdddb`adedc`bdcgd_aaccddeebddeddddc`acfcced`ffdcbebbce``cdTgdmhtQ_f_emkhefea_`ifad]hi_flcp_ZQdsi[Zmc\c`ffhYYWfm\\b^p^ei_iiaYU`i^jldecbmj]a[e\WiibYfdjc]odpj`e^gkckv_fcbafe[idZbZaX]^lblan__h[^\gjjnghaYgdfkemcjf`sgg\`doajeW^nchgjdfcjbm\fg^t_^W]afhcnd\l[`\nn]diQc[dWc`f]ahiqYceZhjebd^X^\Y^al]f_b[c^^njN]daachbiddg^ckfgccbccccccccccbcbcccccccccccccccccccbcccccccbcccccccccdcccccccccccdccccccccccccccccccccccccccccbcccccccccccccbbbdccccbdcccbcdccbccccccccbccbcbcccccccccccccbccccbccbbccccccbccccccccccccccdccccccccccccccccccccccccccccccccccccccccdccccccddcbccbccccccccccccccccfddd`^cbl`c\_djkaib_bd\bddbYded[fb[`cai^i\gabcfcerh`hcca^bhaddf\e_Wcnihdf`^g\ccnhhbccYf]d`jfe_d\\c_ele`fkVh`bi\\eTe`ieafnhhfag^lcdacdeng`b`_kcbkca_bZea^aZifacXecabXadb]Yfcedeeb\^b[_`iibe^^dhaleededYfcbjaajbadh[ehbic_ffkYabchffjfdcacac_m`iaeccfbhd^adebibaliccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccbcccbccccccccccccccccccccccccbccccbccccccccccbccccccccccccccccccccccccccccccccdcccccccccccccbccccccccccccccccadccbcfcdcacbbdecdabadcdbe`cbddc`edb`ccddecbbc_e_bdcbbfcaadfbdeedbccbcbdba_bfeececddddebdece`dabbaeedeffccecadceccdbbfceeccdce`dbbcfacafhb_baeaabbbdccdcddadcbccbcfdcadddcbcbbcbeeceddcbedfccbccefaadebcgccdcdad_cbabed_dbfebcbcaedc`cbbe_adacca`cgc`ccbcbdbc_edcjomincffinangi^cfaZehafhc`b^`y^\foag_a^ji`dVc_c_aeXda[aReZahgir`]aaca``geme^g^`^`dcbmmWejgcfdi\g^`jk\djbgjb^gdmfhd^jgXg[Zah][Q]ag```m[aa^ak[gbeYmke[`Y\d]Z`dmb``ZgrbijXdb_jb`[bibTaiedWdfdiUa]ifXfmegi`h`e]eealkigVqch_K[]^k^Z^ZdSkc`dea]]_fdldcfciZ[i`aagk[qdccdbcddddccccccdccccdcccccdbccccdcccccdbccbdbcccbbcbbbbbccbbcdcccccccbbbcccdcccbccccccbddcccccdbccccdccdcdccdcedcbdcdccccbcbbccdbdccccdcccccccdcdddcbcbbccbbdcccbbccdcccdccccbccccccdbcccdcdccccdcdcdcbccccbccccccbcdccdddcdccdccbccbadddcccddccbddddbdbdccbbcc_h]e_pm^chfV^gf^hb[a]`f`ekfa^`\ba`bjk^_aclZc_\\^^]bZbjjogdki`Zeeifs`cddlS^bb[[beg_ao_dg`fidZdbf^c_dnfiXiZiWegcdilXcsha^h]ane^ndgelaf_ch`a_`dYh_hh~Yhai^aedhhd\gfai[ahfwb[ae[coYbbfcdc^^f]d^`_f]egVem\khg\\ej_`hicb`l`_ecjdb^a\cb`lbaZfe\gglco`fj^hkbdc`XoXgebb`ijib_ijbmghfeh_e^k]bnk_]ehebcbaeeUlfZbffciXi_kcebdjY]kY]aWakbffeUbfnejfWrfehedk]kYXX_bbjdgePc_dj_Zm[keheYrgef`lko_aib\[cdo`iek_jke[ef\Wfa__occba_aji^c_Zhgae_m_e_bf^aa]_^njgdgd[`a]dc_h`[adj_[blch^ddZ]_i`Wbaf_^dc]fbgebRmPlicb^h_fhigec_[jYUgd\^b```njXbjeaOzeemab^ea^fbdfcgcebi]ffcae_bdebegjjdda_`bjah]cffal^f\hadfdeXb`b\fag^bebfeaaf^gbdcggei`cdgccaibcbccfcjcgc`d_caf`medcdbge_kba`fehacbccadhcga_\Xcd`dg`abgc^he`hg`cfehhcfafo_`feedc_d``_]b`__idc^f^bd_cXdbc^e`a^ckgdhggef_e`_`g_i]g_ad_^\a^\fjga^f]d`b_caf^fej`chafddb`daSl\dW^kYfie`s`mr`Wn_kaZdVb`\Rfcoc[_Y_\SifRcTelbmkdca_`kcp\c]`YsjaSiX`qZgem_^ddXcmW\_db^Vj[[ltindim[k\hZ^Vhneg]\Tf^`mdco^^rhcanag]QVfbidqX\]v[f]ahjdbpvfkbj\abhke]mQqc^`Yfj_Ugcjb_[b[SkTac]abaicru^bbnmi_u`gac\R_d]_neaucc]aZsjZc^hjgT_^cfhdhjdmfdfhb^pn\han\T[bcbhadchdbc_aXbca][f^Vg\_cl^dddfflgc`\deZ^]\addkga[Vck_n]ahc\_`e_`bbgZcd^Z\dp`g`[ceZsmafeha^ffcch^ei\b`^hahcki^eahcefbfaiddfggXa]cgZ]ee_`h`^gggdabdjh[_adlZhekdhg\eaed^db]gccbie_ae`^dh[b``c`adgbdhcgd_`lcd`pdm`j[b]ib_jhpbYg_df`ij`b^icjfjb`nhejbffbgc``bdfe_ejhcbbccbbbcbcbcdcbddecbbcccbcccccccbccbcdcdcccbcbccbddcdbcbccbccbcdcbccccccccbccccbccbcccccccbcccccbbbcdcccbcbcbcccdccdbdcccaccbbccbcddcbcbcbecccbcbcccccddccdccbccbccbccccbcdcdcccdcdbcbdcccbbbccccbbbbbbccccccdccdccbcbbccbcdbcbcbbbbbccdbbdcccbcbccccbcccccabcci`d`ca^_dphXVc`e^[TagQ[lhge_a]b`pbclSgdc\bcfhk]a_mhhYZU`gilbb`ecWcd_e^fffbleaghhdlZdd_e[doaYjfimdhfZRcfhjkkYka\\]`i_hj]_TdbbfefeR}X]b]jcqU]]l`haf_h_VechjmZ[fSdcm]b^fZg_^_c`h_^fg[jgeSkc^bXiZ^dc`igpc\dubed[jfgia[ZniLmydbNefimcahqebcfkbhhikdcgfib_Ynphkdgdpff\h_[`_fanViaoeoo__^_h^n`dfeajYdZeh`ga\`ibaU\^j]ebgUdfYhkqZd^fkZQX`bceKaca`dgZ\^hZbdci_affcd`inh`ei_]gmm`W_[aida]ppeedf``dlmflfelTkd_bgb]ia\ghWb^[kqfabp[`da`dgc^lZ]\\`ncbl\[gfbpc_lXYh[df[laUfimkk]Vb`k\ded^k`ebcfaicTltls_`mkk``h\_[becib_Ydndfby_d`fo_egSaWhYg]ojgam^Zifcdfjkdi_aXe``]echad_dactj\ekZdg\bk`c_io^g\gdbgg_e[e^caacf_^`^[ekbcbZ_aceg]dbf\a^edhtk\j]eted``bgllcgdaedaccg^^jeglapeZ`bk_df^\c\\b^^abcgd[iWc^obid]]ebbfgbcgm__iahdae`aaY]ck_kgRie]i]eYgh]^``jfUfceceYecc[ligrcgbea_\`ca_gcifag^[[\]ddidjeedhbieba^]`cabccccbccccccbccccccdcccccddccccbccccccccccccdccccbcbcccccccdcdccccccdcdcdcccccdcdccbdccccdbccccbccccdbcccdcdcccccdddcccdccbccccccbcdcbcccccdcccccdddcccbcccdccdccddccccdccdccdccdcccccccccdcccccccccbccdddbcdccccdccccccccccccccccdccccccccccbcdccccccccccccccccXbiik`drdocX^hnbRgq\Qyelc^ape`aZ`pa`gh[]fQbag_j[[W]mQ[ajlf[kesk_dqjZi[\`a`ikY[a^Qead^hnjc_cb]VybgUV^^`Xqmlfp[cUj]`x]hi_hX=K]dr`fZ_`bhZdgerhlje^^dcdmjjiLbb^Zbf]k^dnp_]XYachjY^`]dg_di^ffX[neWd\c{eWxd_ufeZe`]ckWfZihUYkV\vkdgaifgTZpcaIUaDk_W_]`me_bddijteRbje^Ybbl]iXocWah_gVY_jagtqqkc\YykiajL\bc\bhmSd[`]d]dgVTk`jgnchgWfgqdd_Tnqjhef`mXmJ`a\Xof```k[]ad]XVk_cWWf]ebfed_Z[\cc_a^XXd`o`iYUngf^Xun^jaY`Zf`a]fabak_n_cfa`b`YnUU]^`hg_v[aV^\gcR_`bg_`jcla_]egc_Zmjjfb`fP\jgj[a[hfldtccqNblueqq^md]W^qoahf_aVjaghk^c`knd]XY`shheilfc_]h[g_]^ca_\g]_Z\c\\riegcdUk]dlbhc]hhjTf_uhhV\sbceapSbijehfUUaj_`ja^udc^^Okhc\gb\^jY^]be_aeeg_`hj[gdidZU]gjdtc`[dia^j]g}abqdeflbi^hhhelgU_fcqgoP_K[^b_he[bedbZcWgMXN^ulceb`]]b`j_cMkaYef^Sgl`V]egc^Xrha]_fcjdfffg__cg`^aieg\affddaiY^qjc_lZ`i^o_dfjl`jcjWkefYdcedfaaffd``dggccecbaf^_cbdebc\ldc`_`b_[_ec]`fdbic^e^dn_`eee`bdegXecdghde\ccbagehicdec_hdf`dfgbi]fgbl_beeecib_gabgadbcfgfbccjbibh^aejddabi`gdcg^c`fche`en`dbedec`ce^h[de_d``agfd`ld_ab`cigg^cbfleidbbaj]ag^hbe_`b_`^fj]`def`f\baiad`b^`j]`e]`jfgb_Yda]`b__``Xc]abcc_^daide_cka_a_cdZcjbdca^ajjWbbgeakchmo]\WT`i``mjfkkXbf^cbc^jZ_adbdbhglk_eb^d]bii\amdd^abdd\did_cqb[jb`__hiWVgebbh^eX^gl[aU`a]fahm^a`e^]ia_ki^Xkg^h\ka[cgcd\bbeliih^jYecbYafaamUbdebic\gcshck^_]iic_aaalkdd_dbcV_dfgebbaihkbha\hddfebcde`^cddb_k^ahfgbXhjia`m\ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccbccccccdcccccccccccccccccccccccccccccccccccccccccccccccbcccccdccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccdeeeddeccddccdcdbcdbddbcdddcfccdbdccddcccdbdddcddebdcdcdddfdddaeddcecdbccbccaccfceddedcdebddeedcdcddddeddbbccfeecddcccfeedcfbbbcdddddcdcbddcccbecdcccdcdcdbecebeecccbdddcdbebbcbdddbedddcccdeddccacddcceddgccdbdbdeecdcdcbddfddccdceebccdbccdcdcc`ecbdddcdccaW`]cYbja_W]\fhfZbecm^WjtgbXqfia`^an];kbddmble`abkUo]c_hc\a_i\^khbijhfehgafg\calcc]hdZTehY`fXLo]Sn^AJghf\fWgcjfhjggg][ae]n^ke`bucXZflbhmmm[gcm`T]dcjdib_hjdcio\f^cjjfqiicae_``^cloeefV[`aeh]cqX\Vbr_^jccd_klhfjgh^pWX`YbiWaecllbijc^jjrnbb^fcohehb^ial_caegbcieddfg\]Lmn`femcUNjZacejf`dgf^]jieTkQXaUfZrZ[][lhhbbiiiYdabb_ejlo`kjeb^WahnU]Zbadfhlmndedga^[hailj;ecle^Ze_hZc`enre]e`bc_iejghkgk^YqimVm_uX^]ddhmkX_hbj\iY[`bW[__hk]j`mYi`eii]t\`_fj]Xc``hdlg`bbdofYccUh[kf\kh]aqlkodcfbf`cjSbnscY_bfcfjddd^ff\e`mcm`dgemdZq^aUaTl]ccbccccccccccdccccccccccbbbcccbccccccccccccccccdccccccccccccbccccdccccccccccdcccdcccccccccccccccccccccccccdccccddcccccccccccccccccccccccccccbcdcccccccccccdccdccccddcccccccccccccbccccccccccdcccccccccdccccccccccccccccccdcdcccccccbccccccbdccccccdcccdcccbccbccjg\aab`r_Xqclcllpcqhgcge^b\iqcRie`QXd\hlh\Saj[thnlfY^fgkiijX^XZ_hXUdlbcfock]abXie^\do[fajf`okeigladmjcjdZOeiWod`igepbanl`oYZS\^cqbpnhpiXll_pii\q\jYWloQkkj`kfReOiq]gscjeZfckflhb`\ephdS_cl\\iWbnh`fh[ec^[_ggxfs\iegddghbQlj_adjb`hUmmahc^`\[q_[BUqibiefegftblW]i^biY\e\dccjk^dlchfd]vdijabbqk_][_Z`_vckaeho_gg]Z_Us^`ane_ogg\bfhgdn]f[mdbpaYqkbi\fh[eagZp[Yhaj]cijod\g\eXqtagndicfdjhdY]`i^p]Z`rg]>hmff^eeeWhZ_ie^dT_eiejc`^haa_cfTdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccdcccccccccccccdcbdccccccccccccccccccdcdcccccdccccccccdccccccdcccccccdccccccccccdcccdcccccdcccccccdccccccdcccccdcccccccdcccccccccddcccccccccccccccdcbccccdccdccccbcdcccccccccccdccccdcdccccccdccccddccccccccccdcccccdcccccccccdccccccdccddccccccccccdccccccEYe]gsecWg`W]obifj`e]g`Gg`Yffoe`\i^gjfYVgabXa[odab\gqc\mer^h^\U`k\eimorja`bkj\b`o_[\jp`a\m^geaSd[^lf`^j\fYnnhhgfcffgvch]QYaiamdabcYnjTicpoReq`cU[rrkg\[b^cgc[_d`\yYbWk]bkd`X]fi[glge\c]b_a\l\]k]Pddfgf_hkikiiidcZhl\nlaeahidm``et^]`t;hnbjhejffr^ac_dQZgQ_ch\ec]f^ombd[dYcRccifrZcafbh^qgpg\aoiUlchh[dn`nl`j]lW`aca_p:]]g^[ha[`R]_igffZ_Ye]bfj`kS_W_ojada^[h^Vaek_UUphhe`j_el__dk^hi_g`^_cPVhdjTd_adgjiddtnbilfiXeZfanXi`_djcf^\m]dadjcjajgbgafil`gaa]mgdkmgghhT^ppelb`cb[ebc_jib`bdbYlh^]gg]aj^i_]e[njXbXNd]g_^khad_e]feccbhmdaddebb\cecbede_`cgdbfhdbgbcecdacbdfddcdadbefbceccdeecafccabbcddbdc`dcdbahad`abg_ccebeeebdaccbdf``aecddefcdcdbefgcbgbdfead_cbaacagbdddbbdeccebafbccb_cbedebbedbeddbdc``geefggbcedeb_fccbfgcadceeddfbabdcdcbbeecdcbhdccedabebcgac``hbdccdbdeeechcfffcfcgeedfcadbecdccbcbccdcbdcccccccccbcccccdcccbcbccccccccccccbcccccccccccccccccccccbccccccdcccdccccccccccccccccccccccccdcccbcccdccccccccbcbcccccccccccbcdcccccccddcdcccccccccccdbdcccccdcccccccdcccccccbcccccccccccccccdcccccccccccccccccdcccccccddccbccccbbccdcccdccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccdccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccdcccccccccccccccccccccccbcccccccccbbccccccdcccccdcdcccccccccccddcccccccbdcccccccccccccdcccdcccccdccdccccccccccccccccccccccccccccccccccccccccdbcddccdcccbc`qmgaZbrd_heaefdi\bfamdZcb^d]hk]\`gfdZcbYfadaffajabcWdYhid]bbh`fa^hi^mTdbgg]i_bghc`]dYebagbmd_Aj_ddbhb_ee[bYkgcej`d_ndeV]mhj\id^cdkefof^n`qd\]e^ci[ebdbd_\bgd_hge`\^jgl_aU^h_d[h\gR\^]lbafaleln[b^gd]ejW^adfhV^`hg]ctejbhclmdgkjhebfcWd`jfafm^eedgh_cb`\khfghbdflhdepm`fX`]a^aZihaaVbgbZbah_o[i`hb_bjb[dcp`g^cdddiZffgZa]`^ih``^`_ib_aX[mcQ_abchhe_`gk`h[aeeekfc_baab_[igigheSZ_kgfh_acl[gb[b]ocdfk`aghcg\a__bdefr^d[[bghag_[]l`gjXcmjobe]cdfbdgjccfbegVdihlie\^ho_c[ddd_WddebaTgd^if\fmdah\\\c`mcgkefejf]s]gfal]dea^cb^cdcojhlccdcccddddccdddcccccdccbcdcdccdcbcdcddccccccdccdcdccccccccccdcdbccccccccccccdcdcccddccdddccddcdcdcdcdddcdccccccdccdcddcdbccbcccddccccccccdbcdcccddcdcdcccccbcccddcdccdcddccdccccccdccccccdcdcccdccccccddcdccdcccdcdcccdccbcccccdccbdcdccdcddccbccccccbcbccdcccccbcccccccccccccccccccbcccbcbcccccccccccccccccccbccccbcccbcccccccbccccccbccccccccccccccccdcccccccccccccccccccccdccbccccccccccbbccccccccccbcccccccccccccccccbcccccccccccccccbccccccccbccccccccccccccccbccccdcccccccccccccbcccccccccbcccccccccbccccccccdccccccccdccccQk\k_]hcm]\a]hk[khe_c]`[mlcWhmknacdda\eidWZ]`ohhje[d^gffd`f^dbkYbadchogdZg^k^VhbVj_hjdcXTj[Yhkdi\Ybhimflgb]]fYbiiaeeq\abbXZ`[iflgd^i__U^m^Zhu`fkan^lkdcnW`fefgbl^aWd_fbi]YZl[cdgjjhc]jWigVc_geruflg\d_[a^bddif`m`iqgl^fblcqaijoYneiak_febfelhodh_deh^Zbec^ghNYhTfajinUM`NMe`cWefhj]amhfnW^clrpfUw^oek^[lWgfhe^_ba_liY\\dka\ibjTNhbaoc`af\jhpY^kjYZ[alvZgV`_ktXScZOkq^op\^XT`YfQcldcikag\cocpcrZV`j[kiZnenb_cadecZbVhBebho\jefhn^_cV\Sncdkl^[\Wjibl]dhdghd\``[_a^rPehhiiV`ck_jb_dy]foofo_o\qb_diioapfgYbliafb_^gihcf[gledYlabosVbdcddbcddccbbcdbcdcccbcdccccdddcccdddddbdcccbccccddccdcdcbcccccdcceccccdcccdbeccbcdcccccccdcdcdccddccccbdbdcdcccbdbdcbdcddcecdcccddcdbccbccdbbdccdcceddccbdcdcdccdddcdbcdcbbadacdccccccdceddbcccddcbdccddcccccdbdcdccecccccdcbedcccddcbdccbcccbddddeb`dbdbddcbddafR]ckZd_W[a\l`dfd`]Rhg\gkqYrjk_[l^Wcd^jVjliToa`[c^mijhcZdY`gkg_ffdhbubhr^jXk^iiaqkdelq^dgc\naR_[b[fkfcec^hbl^keiSbamegcXUegU]df[gac]dKknbh`^[j_^dh^d]W^Wdgebi[X^jmTlpeciph\^i`jkkpjf`h_i_c[f\Y_e`^h\pjggldiZdgd[kms\flfh[acbjeaZb\`mZ\`ge`hiieekgcbaafileXkhceb]cccccccccccccccbbccccccccccccccccccccccccccccbccccccccbcccccccccccccccccccccccccccccccccccccccccbccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccbcccccccccbcccccccccdccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccYZ]jsogjYVfi`_Wbcg`hmdRgc`]lffaf`]adfddegacicljkk_`[fVihj]ihb`g_ldadeTYf[g\fgd[a]h^dqo`_gff\ginJghkcdd`gSkUmbeZeTfZkfTcghd`]jnec`eba^a_i[f`eaokig_dg`_baf^ge_l`g]^`]b`fcfdlhyfcqldm_g]daX_g]dagdlZga^]abgadnX]\jUieibba\T`V]igf^W^[i_fld\N^e^cacc_Sefg^bdh^^bfjghfmfjm]hajanW\e[jcbf_jc^^Y\mgV`bZa^j`em_f\g^cgXl\g`f`jlne^bilibohjjf_rdfg^hfcfa^h[gelcbjgilec_bpfd_NiX^lbni]^Vhf[gmfna^di\ig^cfdebdb]``[_ncbak`ZXdd^`oaY[gaggiYb_m^Vbc]_h\aUdfpklW^cV\bab\idedfZd\e`kRfa_jcab_c]igipb`fYchgajdYXfehgehmWke_ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccbccccccccbacdebbcdbbdbeadcefbdecacddccbdbcce_adcbdbccdedcbcbfbcdddcbccdcfccccbfacadcecedce_ccbcaegddbcaaccdebfc`cddecdfdddddbdbcddbcfaedafccabacdcbccdcceedcbc`dc`ebbcbebbcbfbbdbbcdbccccedeaebdeceacdcccdbbcdadddcccabbebbddbbbedaedcddbccdbdbecacacbddaccbbbccccdbcbcdccccbccccbccccdccbcccccdccccddccccccccccddccdcdcccccccbcccccdcccddccccccccccccdcccccccbbccccbcbcccbcccdcdccccbbcbcccccddcbcccccccccccdcccccdccccbcccbccadccccdcccbbbcccdcccccccdcbcdccccccbcccdcccccbcccdccdccccccccccccccccccccccccbcccccbcbcdcdcccccccbccccdccbbccdbccccdcdcbcccbcccbcbcbbcdcbcccccbcbccbcbccccbccdbdcccccccccccccccccbdccadcccccbcccccccdcdccdcccccdbcbbccccdccccccccbccccccccacccbcccbccdccdcbcccccdccccbbcccbcccccccccbcccbccccdbcbbccbdbcdcccbdcccbbcbbbcccbccccbccccccbcdbcccbddbccccdcccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc_bXQbjkhZcbda]hbihab`fW\YdcYo^Sfg^iseZhe_Vc7[^_ia_a_^V[\\[_gabeedkfZ_gid[]^j_Yc_\lb^\gdTVaffu`fbn[chebgf_gblgd]hkh[g_ddfd`Zg^_l^b]]gsU\Yga[ahmoi^awddgekabW]ej\meed\ak\^dd`Z]dYflcc]lgZkfgdpgf]rdoa[bp[ahe[mcfZfc`Xhkcbfi`b_\]d]kbjhfbij_i[cfhd]p_Zbk`ehjf_fX\ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc`c`deaccb`f`ddee_dcfacebc`afdccdb\_fa`fgbddcccea_`d^c`e`cfcdcdaadca`bh`ggbdcbbfccedbcbdbbaecdaabb`dddedc_c`edbabffeccebbdebccdheb_chddcedbfd`a`acddb]cb`bbced_`ddcacdaacaddk`hfcdcaecbaeafdcaddbaaaab_`bcagcbaef]dabdac_bh`dcddefacbbddbbcebbdbcaccgdcacbadeccgacdccccdccddccdcdccccbdccccdddcccdccbdcdcccccccdcbcccdcbcbccdcdcccdccbcccdbccddbdccdcdccccdcdddcdcdcccccccdccccddddcccccdddbccccccbdccdccddccbddcddbdbccdbbccccccccccddcdccdcccccdccccccbccccccdcbdccdcdcdddcccccccccdccbccdccdcddcdcccccccbccbdcdcdcccbccdcbcdccXYQ\ekgf^edffcacfiocc^egZeeb^^\`Y^[ax`cWSqakkfe[g^efocmg`dadbjc^aUrn`bffkccgc\\bccnjb^[^gfmgY[hhincaegbcZ_`lcZmajl^i__eX\fgogWqf`]gh`abh\cpgagVdfbm_eebdea_^c_hhibi`jc`dlifhedn\f]c\jjhll\]XgpcfaU]Wjd[j\_dabdabTdfkYih[ra`cZglhce]cbl^reba\niax_f`dcjfaibcd\\kcaUXOacd]b_bb`d^hdh`_pZkjdSbpich_lrbm^reZ]_mc^flgpglib]bkbcZc]e_lihcjdmma[bj_lsd]khfhfra]d\f\][ndhkaah`egd\`\ZheginkVehdfZ^k`a^]lmbZcc_c_ah;_db]dZeiiR\_`]hdfeck\hkm`[fd]kiTe``_e]ckcg`_ZXkegomb_ab_^oambjicdmidena]]dgWdcaaa_Y_jmb`_t[hoge`klYgiikgh^b[l^Xad`Xega`fbdfgfcddc_agdacfcb`fdcagddcb_aedb`_cdddcd]aab]]`__ea^fbacbef_aicdabadcdckg_bacdfjgd_a]fa_dfa^eedc^eff_cgcf`a`gfacbb`afa_b`gecfdfd_db^d\hccgdbdagc\b`bgefeg_dcdgdcbjeedaehcfebdbcdc_caceabafacgacad``cdegbbaad^bedebcaba^ecghbcagebce_dfi]agabdefbdca`dfbabcdfcccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccdccccccccccccccccccccccccccccccccccdccccccccccccccccccccccdccccccccccccccccccccccccccccccdccccccccccccccccccdcccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc[c[`]^jcc_ikhdf_`blga\ifkfdYf\Y]a^ccZ^[[qq`ml_dcfo_pbgb^]ucikgWbggbhXjh_cmcZgebVdS^cijdifdaYeqmihdc[`febg\bWmah`d^]Wg`gac]eabkeel^a`ccf_h_Wddd_g\pdbeebegadnYdnf`idcc]jwfj]j]addNien[^cfd\^aZ_hf_^cZj]dcmd]icleYjhcccqnj]]_eadcdcd`Xc`Vh_hXhdai`ncdide``kfikdYb^dcagYhl_ZdXaeXd_iffcjhnlbmre`ajdbo`Uid_bbhkQab`]lY_Xn^]_^g_jk^cgecdRfkcagg[gahYf^ga^oYYcdde`bUPhaaifhefZc_Whg^fd__ae^d`^cq^__WeYVaibgh^dZi]kRe_dgk_`Vc^eg\ga^kf]e]gj^lWm[haXaU_l`hdafcafgfwTgdj`lddf]`UnhaZckc^_`Ye]n\pf__bqick`a]apiiij__g^adia_sa]aieYd]^\ad^cdcbdccddcdcccdddccbccacccccccccccccbcbcccccccedbdcccdcccccdcdccdbdccccdcbcbbddcccccbcddbccccddbcdcccccdccccdddccccccdddcdccdccccccbbccccccbccccdcdcccddcccccbcccdcccccdcdcbcccddbccccbcccccccdddcddcccdccdcddcdcbcccdccccceccccdcdddcccbcccecdcccdebcccccbcdcccXbjY]jchmUdmjecgiba^nRgacti_\e^Nc[ajbZap_bm`j_YdUbgO[ai\d]r[`d\LdWhdvaahi^oqk`g^poYaV]a]fmdZfgOZ__hgWX_`Yae]bzje[^\c`g[\bncn`_^`gj^cdhgefd]g\d_nhjij__bZfcbo_Zh_an[j\hfjifnhcad`kVW_gfk[b_q\_nbddVgZZeeddnfbhleafelcjejk^fY^cZa__kegXggumbt[ns`i\brfgc]`kebeSYchdg]hShhb_fmb`cfZeelhc^bfk[sP\aii[ihhbb_cbZflic_iai^_in`bfknadlXk^njWci`_[b]^galYig_\caiicc`^[mgYbgbgd`__dg^gdhof]geem_je`]a^`cdiq_i\g\_g_bXg_ccig`jglgf]ij]ggg]bhg_abe_ljd`hh^gde]a_jmYc^QYZekoukk[ck_]add\`ddVnglcYikV]dd_mh^Sd]eZeami`be^hlcfma\faac`edbm^ZgfcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccbbccccccccbccbccccccccccdccccccccccccccccbbcccccbcccccccccccccccccccccccccbccccccccccccccbccccccccccccccbcccccbccccccccccccccccccccccccccccccccbccccccccccccccccbcccbccbcccccccccccccccccdbcccccccccbcccccccccccccbccccccccccdcccccccccbccccbcccccccdbcbcccccccccccccccdcccccccccccccccbdcccdcccccccccbcccccccccbccccccdbcccddcccccccccbccccccccccccccccccdccccccccdcccccccdccbcccccbcbcccccccccccccccccccccccdcdcbccdcccccccccccccbcccccdcccccccdccdcccccccdcbcdccbccdccbcccccccccbccccccccbbccccccdcccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccckcaYcYdo`gbTbbjjh\`ebbfnj^bam`eeb^ojX^dk`d_jemmedhYif[[]d\fbb^\jegdikocaai^Yco`bYf\`\c[chni]fd]mVfZZhd^a`anggVgbjdadfi`f\fQbbfX[idj[YdYU^Ze\cgjdZ^`bda]idfcgi\]\siZWmbmhh\]gc^gf_bfa^ckeeidcbZde\ofdYPdYcqjjdl`W`h[_uXe[[_miaejfoccjY_bgga_bji]d^jmibbbmf\dalgl]bacdbicjbdh_gdk`\`_k^``ahXmac_kfbe]Z]cW`^^\a]_el\Zbcaklb[gdahgjii`na\fe`bUg[Zbf[f_lmYbcdi_q]dj^`[ie`\_fejb^_gc`i_\bd^eedcefld^ca[hY`hab^`XW``dc_ee[gc\c`g[gYn[lbfgacclfobikdahea]h\_gh^c]`[bdca\bg_Z_[^gbjfi^k_n`^\bibjgj\blbaZ_`kcgla[[]aebcd`kZo_\n\\]qdY]eh]dccccccccccccccccccccbcccbbccccbccccccccccccccccccccccccccccccccccccccbccccbcccbccccccccdccbcccccccccccccccccdcdcccccccccccbbcccbccccccccccccccccccbcccccccbcccccccccccccccccccdccccccccccccbccbcccccccccccccccccccccccccbcccccbcccdcccccccccccbcccccccccdcccccccdb^e^hnk[\lrgbgrnc`n[YZvlF`gbc^dacdZe_kj[^oifb]cfjcgpeW_bdVamcggca``ekniZbV`]bZTYi_OQ_fgbjtiYal`w^eY^hnam@eojelS]l`^bWk_a^j``kLZ`[`VfcWf[Tpa]aZql_X_kjjkh\f\bfZlgx\]cehe^[^beeda_`q\i_hdekdkcdifXeXZc^d``ZlXi]_aimfgeheo\hnelh[UXZ\UgV_idUY]tpeflpigej`[mY__ktqfgij`TnbmdiYgbqdlm\ffheaelkekW}kYcnpjkggjYc[\ZdbkdT\\jTfg^g\b`aWX^Ygbdo_eX_gfk]hVcbnbYm]k]_]oeVXhkb`hadj`b[i_ia^SVlhYbe__`pecfpmidiVUbapeh\g_eo\a`V]e^oYocil]d_Mceg]cWbk`f^`]Yaajcc`hb]f_[Raeeg`ZgbfclqgVa[[\gg`c]_gaecohehgai[`ngdfrpVidc^Zbghlds]hX`hcjbn^bkg`]^]]`blib^cgdfhji_h^e_cge_Zeceadfgb]ee^ag_^_ec[ab`bfe]gbVfhgce_i`bfh^jbkbf_f`c_fc^W]ckdc_eZdahkbfef_ffd]dZc]llaegh\_cjdf]a`gdedhc_bYe^idfc_ddabf^dc`bdgidn^n^b^e_]_b`idfcbcj\aafb\febbmhheebd`]`_ic__`dlbecge^fbabccekafecgZa`bdfbd^ead]ej`fh`eekdcjalfage]a__e\hcdde\cabfd[lXcarhf[fgaZg^\hWdhiWbh^hj[_a`gjjdt`ehmfjlhiblgcWdn]cd^Y`gdecg^bewadebi_Zie_mf_beZ`mffggbffp_dfc_`XcHa`e`]ccake]ha_fiXae[ee_k^lg^nZ_d`=e^aa\]fjZcX^`emb^ikadc_^Xfmh`bkg_k^kecj]gkfecjeb^_ecc`cbd_hhkdXfc`i_deikYacmaibkc_egafXdage^a\cWUa[edoXife[e`]b[chjg``ib`abdb^eehqcfiflgk_bffd_cnaZ_jgfig^dcgic^egXd^hebfj`]eaf^g\]ab_dbjfXXce]`ghhd_^m\iif^_bgfYafghaYfeghcfkgdagk`da``hcbfdb_]kcgfd[kafd`]c[cficddc\XYga_ge`^_X\_mg_cdjk_kg[\debcabgf^ai^gc]gaf\oajkdcdea^`ecc^ga^gde\^deZaehegcbhbca^i\ddhe`kee_d^\ih_^dgbigddfc`bfgbcedabbd`b`dd_b`aacaeabbfagfaddbdc_afad`efceab_b_fdcea^_bddaacdbgfdcdgcbjaadbaa`^bffd_cccbdbfecafe_cb`jfaiab`eagc`cfea_cdhbdebchbcbf^bffgc_]caeciagfb]edefff_d_de`ejecddbcc_aeadh^jc`bdddbdghbbjfidicia_cdeaecfdkdbhieecjg`aegdb`cadfb`c^cgebddcdelebecadcbgjj[aee]eecdhfd[i_b[eb]ak]Zacja\r_jeea\l_`ajkbgfqe\kich`cbaeeedgdb]_ccbcd`bf_d__ddc]Ygbfddfkl`igZc_dgc`a`eadf`c^bhdfdbc^X]]baahce_ea]aed_j^`hiccbgd^g]lg`cd`fe`d[\haea\^ebbb_hgbhfehgid^hYcc`ba_bhd[bbdaa__cicfVbbdhfbgba`eei]abacecgaci_g^bciodijda^i]gf`f^bbfbjWgbefgc_hacaebmdhldacd[jbgfiaib_ceac[mgacehd_^i^`ggh_caaemhb\bebecacbehhdgc`aaeidfaf]`fj]b`b_h^kbegfghd`\k\_fcbhdc_b][d`d_jda]e^\]aceeZcZafcfeekid``h]iddcb[efhei_b^Zf`d`bfdj_fhjee`gdcafgcjgc`cahaffcakgd`j_]^cefccajc_^i_`_mb`g^c]Ygcbg\eb_^c_ba^`^^X_e`fcccccddccbcdbebcbdcdcceccaccccbdcddcedbcbcbcabdbcbbcbdbbcabdbbbcddcbbcebccbcdcbbacdccbbbcddccbbdbcbcdbbabceccccdcabccafcdcacdbcecccbccbbcccdbcccbcccdbbbdbcccbccccccbddccccccddcbeddbbbbdddcccdcbadcbaecddcbaccabdbcbdbdbccdcccccbcccdbcbccbccccacbabbccbdcbddcdcdgchkcc`ead\^^bccd`]gbi_aaeadek^ama_bafg\`ib`dbbe^h_^bmk`]bk`ekc_ceea^ajh_^_ebac`gaddc`ceebfb\ae[d^geeccbapl^mkbaeshdc_b_dgbh]dfbia]`cb_bg[jXgc\^a]jbbdYk^^^beYcdfjc`_aece^k_`^ce`_bema`ffc`^dea_akidfghgeaji`\``fba`^[`Zd_bb`[_kfc_`ieaga[aai`fe^ba_dcbdk``acfcccccccbcccdccbbccdccccccbcdcccdcccccdbcccccbccccdddccdccbccbcccbddcbcccccccdccccccdccccccccccbccccccccccccccccdcccdcccddccccccccbdcccccccccdbcccbcdccccdcdcccdcdcdcbcccccccccdccccccccdccccccccdcbcccccccccccdcdcdccccdccdbcdcccccbccbccbccbcdcccdbcccbcdccccccbeae`hd_dfe_aad_daibdc_befcaffad_cfdeccacdbbbhahbagcdf`beeibbegbd_dcebfefgda]afffcj`accedbgebafa^daffdacbb_afcbfad_fbbafce`cdbafg`ccachf``e\bh_cccfbehhb^`aa`bcdfbbecafbdababdc`cdbcebb_caeafebbc^imdcefd_bdcccbe`a`adaac_eeh^gcebbbed^bd^_cd_fccceb`eef`dbfdbb`cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccc`^[Ykzd`gc__efi`_`]dd_gccefgaa]`_ia[_jdldeg`hbhgd`igecb^__f^_`dch`ecZcbbf`h`Yef`a]lp_`jacZhaig\dcdck]e`di`h\fef^db^Xbaf``\Zig^c]^lXec`]hk]dbbh^[a]fa_\ccnSoWma`Xaeebbkakcdceala\_cfXijae^e`hldf[`b`[ccclkf`kdh^dabacd^ej`e^iZ__gfdbddr[`^bbajaeh`g`iib^^g`Z]bbmgcccccccccccccccccccbccccccccccccdccccdccccccdcccccccdcccccccccccccccccccccccccccccccccccccccccdcccccccccdccccccccccccccccdcccbccccccccccccccccccccccccccccccccccccccccccddccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccdccccccdcccccbcccccccccccccccccccbccccdcdccbccccdcdcccdcccccccccccccccdccccccccdccccddccccddcccccdcdcccccdccdcccccdcdccccddcdcccccccccddcccdccdcccccccccccccccdccccdccdcdcdcddccccccccccccdccccdcccbdccdccccddcccccccccbccccccccccccdcccccccccccdccccbcdcccccccbcbdccdccccbdddcdcccbbdccccddccdccbdcdccdaedccdcdcbcccddccddcccdecccdccddccedccdccddddddccddcdbcdccddcdcdbccdcdddcddcdcdddddddcdebbececcccdedcdcdddccccbdbcdccdccdccccbccddddecdcbdedddcdccdbccbdcddddcdddddccecccdcddcccddbdcbbdccdbddccddcdcdccbcccddddccdbccdaccccdcdcddacfegb\jdc]dngibjgajbccce^_jjcf^ifedbfcbmaiiafd]k_cbZ]heeaeaf_hgcagoabgceddZe\bg`[adc`]c`aZecgd[_iibdfbf\]^h^ebb`[hedcd\f]ea_ceh```bg[h_bab]^dc\bdef`]ai`e\lb_g\c__``_kbff_m^`begdgbheh^]e_``cdW^cb_ehf`Z`akb`_j^hZk^]afYkdh^f\ic^g^`lfafccbc_kec_`fgicbcbe\fiebe^eeedbc\b]dhahecded^ah\_aa]gch`]^kcfafcZa]b\`bba_hkkbab\cbchffc_bcccbcg[ccece^flgiiejg\ebccgfZd\ahcce``jZd`Wca_dh]eca\bbijYia]bkgZh_jhd`gb^bgjfa`bdi`adelfamd^ddheg_ag^bYbc^`^gb_h]biVh`ggchgfdeddhhkfe_dtcheec\hYe\Zf_k[kd_fgb^dbd^a]hh^bicf`fe_^aZbbgffbd`Tdjddecacabdbbccddedbbcdbbefccdccefecccacccdabc_bdecbgabcbbdfbfbbcdedccdbbeccbaeadbbebcdaddabbccdcdbabdcadcbaabbdbbdcecccbccbbbddcbcefbbbcdcccabddecbccbccbc`aeaf`caccbcaaefccbcaace`ad`deeccbbcdbbcedbeedcbccccbfcecbcccecaedcdedabebcdccbca`adedcaeceeddeacbbaeaedeigdfddakfb_hbfcgjd`egedfgacd\ik`da_a`ba_cg^hbcec_^f_c_ehaadic`jeka`bb[eaj[`d_^g^_dYf`b^Zf_djab^cajeZbab`ababbhlg^_^fcdjbacc_e`debi^hbe`e^h`bbcbb_]_`[db^bc``[dcih\g\`cW`Z_fe`fajfeb`kclbcaec]`g^`ebfg^bbhfcf[fj]f`_daach`hg_a_hfahg`cedgk`]`[afcmqZbgaadicba`d^`caS]g\d^f__keccfYjgg_`hbeeiald]eia`cdcchdad^^lbbecac_`jcd`][]]efq]iedkddeaaag`faghd[ae_]g^eaef[a\cecec\dYdgmc^hek`iaa`fcglde_^bmX`ga`f`acabahaachcobafb]cj^[ad`hcbc[[]anehd_`jbahabbej_`bhXmbjZabdhdZecdjdfc]`eheg^abbdcX`hiafcg_icm^e^ciabid\ibg\fe]]hgfcb_Wfgdgf_]eebabd`eic]fcgaf``edaaeada^_dbef`efedcaabhace`hb^efjc`d_edibc]a__ead^g\fe\a[idacgdbac_caddi`a^j`cjfh`\e[ldjg_^Y]eflagddg`bgj_gde_]big`egic``[ahcceal]d]\ffhj]gib]a`dh_f`ddd^gj]_j_hd`cbfbc]ebcegbacc\hcc_fbheh_kibhi\\m^eehbbd_gf]cmibef_fiefd[bbdbcg_daf^]cdcccbccbbccccbcdcccbcccbccccccbcccbccccdcdcdccccbbbccbbcccccccdcdccdbccddcccbcccccccccccdcccbccccccbcccdccdacccccccbccccccbcdccddccccccdcccbccbccdbcbccdcdcdbbbccccddcccccbccccdbddcdccccccccbcdccbbbcccbccccccccddccccccccbbcccdccbccccccccbbccdccbcccccbccdccccccccccccccdcccdccbdcccccbdcccdccdcddcdccccccccdccdddbdccdcccccccddcccdcccccccccccccddcccccdcddcdcdcccdcccdcdcdccccdccccdcdccddccdcccccccccccdccccccccccccccccccccdccccddcccbdcccdccdcccccdccccdccccccccdcccdcccdccccccccdccccdccccdcccccbdccccccccccccccccdcccgZfdabd`dgijdksbcijda`ae]``l`c\agkhehfbd\a_]]`]\pnre^[tcYqT_dbb\i`Xchhsi\^eQW_mcpcadf_deaXh_Xhkn^_YfzZ_Zce`QU\ZRknWmo_e]k]iea]_`gc_jf`\dY_`dahif_aS_ejgdoeg[ba`]YZt]heigcghfg[^\ek_[Wpi`ijbjcVXemd``fk`\iiaYekkafrXdpobbe`kbcaMe^a[fYVqPg_^a\mi_cRtkj_cOg_gch^odfecb`dcacdiagccchbceefcceeaceeb`gebf_ceeacccef`cfccedebabebbcc`cccfcdffcbbdcfefaddbdfcbaaabffdddbacddcbcebaccc]fcbabccdccecdfbf_eda`eccecadcbbbbaa_e`ccebbcfbfbdabcghgcceeb`bbabgbdbdcebdde_cdfdd^aedfafbddadbeeaebdccdcdb`gdcbc`dddecdecc^`eecdbfbfbcbbcafhc`c_c_i\hdfjcglbfjc[daa_gae[_gahgb_geac`gbc``_f\[fjcfa]agf[cgdd_eebd`egafbb_dc_`hddgd_f_aiee`l]_cjd_iedbccidccaie`eeiib_debfh`f`a^f^_\_fiaabc\b`dfdcY_ccfgcj`fgicegbbga_fekXfbdabjg_`bacdeedee`jadchd^f\ae`emdg^hcgi`aci\ea_kaddh[`bagaadgcb`bfff`e_adfdea_ffe`dd^c`acbfbcf``ageceddf_fece`cdmedefah]fgcbjcfblcdX^`_ddcg^ifc[`j\_aff[cecbgcbZnedj`a]`cecfg`iea`jdcekee`hg___ediecb_dmbkeba`a`^abg`d`c]cbhaffdaa]d`cgibgbjgaYbejacdbccj\dhdfcljgcf_cadga`cdgcfecdlbd_f_`dfk^gdca[a]ed`^ca`ff_f]d`]`e`bbd]eb_^Xb_cgabehffccbf_hb_ga_hdcgaddbbffiadd`ffa`acd^aceejfbcbhc_ab_ddgeh\hdcdc``fdc]adecec`fb`fcdafbac^eabbeg`d`edee\e_`dfe`addhb[`d_^ddbf^did_hceaabedaaeed`_de`bcb``ad`figecmecdccaaadddeaaeeabdeecfcdaeea`f`cbdiecde]bb``ahbd_iacdbeigibhgadechbgeiadcffejdhd_cdgbagjcachceijbdd`^fad`edc^ccbbcdceafcbbccbebbbebceecdbcbabdceebbcddccddddecdabcebch`efebbdbcccecccefcdcbfcbbdcecbcbeeadbcccdacbdcdaebddacecbfddbdcbd`bceccedccaddeeefbebbdchcfbcdcdd`fbadcccddcbbecdaadbdecccecdedbfbdcccdacbcfcdddadcedcbadddcbcbccbbcededfec`dfabcd`dfdbdfebacfeaeddbaebibbab]adcceddbefebec`c^be\a_a`jbffbdbecgfcd_ai`i_fcbbffgifcbb`agchdeebc`befcbbbejgfaehfa]]dbbbca_ga_a_ded_cghbc`bcdofabfbejgacdahfa`dcfa_c_edaeedidg`cef[acaagecebaaedaacacgea`e^e__aah^aa^d^c__hddbbbcbaefcdga_abcdbdd`dh`befa^dfcg^]gfcbbea^`bbf`dcmebe`ide_dedbehldbffaeh^baddg]ffif`cd\\m]oladdejaf]eeodhf`bhda\ic^fd]d``hfhcagchd]]^_cciaXcbbddca^egabc[\jba`j`afhhg[affgcU^a[Yaggga_Y[bhfc^b`_e_fja[]bgl^a`Ocdddhhhge^`[cljdbcel_`\dXefchc[difk\bnhghh^`[eZfaajdgcf_c]d^b\eo\`k_a^bcfd]Yakh[_fagWcgaf_f`d_[rbZna^ehc_hcmg_ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccae^]YdcamfabV`e_`^db^[ag`d\iflha`\`eYdbeQb`aidbdaWcb`dm[Zgn^bmeb``bbb`iafZibaVbaebpf]ddng`ng]d]cVebkZ]`d^i^ddfh_adc\alec`qgg\g[ebicibggg\^Whgq]ecWgadc__lchdhjid``]aPf\`afdb]cbad\_dlegee_Zag^ZVb^bjd_`\ck`eaogo\]hfbhr^hbjlfgfhg]_YhgajcddcgYfjae_]ml^fhcbb`dbccddecdbcccccccddddcccdccdbcdcdcceccddcccccbccdbdddbcdcecbcccbcccbbddbccbddbcdcdbddeccdccbcddccccceccdcccccccccccdccccbdccddddacbcbddccdcccbcdcdccdbdbccdecbdbcdcdccddccdddbbbbccedbddddbcbcdcccdbcccdcccdcbccccccaccddccbdcddcccdccddbdcacadddccdcbbaccebcdcbddacadbdecedbccdcccddbdeddcdbbdccbdccdddcbbcccccbdbeccccdddbddccbcddbcddccccccccbdcdcdececdbcbcbcddbdbcdcddccdcbccbbdcbccddbbbcdbddbcbcccccdccdccccccccecddddbbcbcccdcbbdddedceddbddbddcdcccddcccbcbcdcdccdcccbccecddcccbccdecdbcbddcbddccccbccdccddccdbcdcbdcccbbca\cgd^``_aj]fcYabb^egbnglgb]j^eh_cn`]_gebb^gg]c]f_bhcaggka_h^Zebca^gcfjjcedfa_ee_b^acla]c`c[kgg\ca^_di]`\e^gdddr]hljj]ahfd^a`giYld]ibXi\^d_db^^aa{_m^ghi\egcfgdhYanke]d`i^k\gdcfab]ga`iedia[cbedcfc^keegeYf\iebdoec`dabdb`^hbceedce_gcfZccjafmbhba[m\bfYeeef\bjbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbbbccccccdccccccccccccccbcccbcccccbccccccccccccccccbcccdcccccbcccdcccccbcdccdcccccccbcccccbbcccccdcccccccbcccccddcccbccbcbcccbccdbcccdbcbdccccbcbccccccccdcccdccccddccccccccccccdccdcdccccccdcccccccdcccbcccccdcccdbcccbccccccccccccdccccbcccccbcbccccbdccccbcbcccccccccddccbdcccccdbcbccccdccccbccdccccccbcdccccbccccccccdcccccccccccdbccdcccdcccccccccdcdccccccccddcccccbccccdddcddccccccccbbdcbcccccccccccbcbbccccccbccbdcdcdccccbccdcbcdcbdccccccccccccccddccccdccddcdccccccccccddccbdbcccdcccbccccccccdccccccccbccdccccbcdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccadiaebcb_dc_kd`ea\]c`afc^`_fddd_fcfhabaac_gahde]gb`hac`qaaca_ag_e`f]_babcbeece^d^bbaiaebeg_gbbbdcagebcbcecbdbfej`dcc`dbead`bibd_a_gddaedbh`_a`\chbcdd`ccba`cbdb`e^ddca__aecjaggbehdaa`bhbgdd]`_a^d^hdc`ebafeabadbgc[]c^cbfff_bieibdbc^addgb`__f`abadd`bcbfda_ece``ddecddcdae\caadhfebbeccgaccdddbc_c_eg_effcdcabacaeaababfcb`cb__dai`ce_fbcbe]b]b``e`bjb^d]b`cbbcaafdgc\dcdccfc^]abccbdfcd^fiagbbccb`bhda`aec`_adcadcbcfg_gaedchbffafeceghag`cadb_acfbcccca_bfbbdacde^^ceaaaded_e^efaZccabeedif`cbcfeaaaccbfig_bf_fbeai`ifbei_akbccccbcbbccbcbcbbccdbcccdbbbbccccbcccbbccbccbcccccbcbcccccbbacccdccbbbacccbcbbdccbcdcbcbcccbbbbcccbccbbcbcccdccbcbbeccccbcdcccbbccccccccbccbccccbbcbcbcbbccbbccbbcccdbcbbddccbcbccbbcdcbbbccccccbbbccbcbbbcbbcbcccbcccbccccdcdbbcccbccbccccbcbbbcccddcdcccbcccddccccccccdccccbcccccccccccdcccccccccccdcccdcccccccccccccbcccccccccbdccccccccccccccccdccdbcdccdddcccccccccddccdcccccccccccccccdcccccccccccccccdcdccccccccccccccccdcdccccccccccccccccccccccccccdcccccccccddddccccddccccccccccccccdcccdddccdcccccbcdccccccbcccccdcccfcdb^\^g^d`i_\_`bba`igfidgbcgrcmccicXecab`hdk_`\ei^hjf[hd]kf^ah[_deiZb^`Ycabjj_c_c^njZaYjec`hbcbiafe^a`UmegfbgeiXn_d_`^aY]mggaefccggZgd\daei\ed^`cab^jgg^`gbffWla]bg`g]bddlbagabfYladZbc\cahb\g]ckcbic_dchfgb]cfjgdf^_bclca^df_i^bd]fhbXhag]efc_e`eknfdbbgdfij_igd`e`db`bi``]^daeb_[diaecjefeeY\bh^fcg_`^_Zbdhea[jpef`hb]`ag^``a_cdheeg`bkdVafefeebcgbbddbdg`dc`cb]e_g\__cebckdij_fagcb_fmfce^_^`dh`ccfedbacepb^_ace`dcc_obc_a^balbd[[cfeec]f]baiiXhbbdY[bfef_jm`\hgcbeiamddgkh^bZ_cigd^_```ieaaibecc`habg`dd[_fc`a_c`hed_ideb\^cccbcccccbccdccdbbdcccbcccccdcccdcbccccccdcddccccccdddcccdcccccccdcccccccdddcbcccccdccccbcdcccccccdcccbccccddccdcdcccdccdcdcccdcbcccccdcbcccbcccdcdcaccccccdddccccbcccddcccdbbcbbccbcbcccccbdcbcdcdccbcdccbcbcbdcbbdcccdccccdcdccbcdcccccbbdccdcbccccddccdcccddcgc^g\h`blab`cc]`gZbfc_fdb`heb`ZaddZfeac_kgc_ehh`b`q^]bab_hhc^bhj`b`fedfgbdhc`ecc_ecg^`fhca^ddefbh`cebhiceYgepgb_]k`h`^e`afei^bb^c``agihiiid`bjhcd[hh`ek[Xbo^\aeca[bdb`bcg_i_`djgfjcdcb]`d\bb`bafcdejfbhffga`g\bhf\ddac`fidXej[^aa^f]bd__`d^bh`bb_l\il`dhdjagbd\hcccccccccccccccccccccccccbbccbccccdccccdccccccbcccdccccccbcccccccccccccccccccccbcccccccccccccdcdcccccccccccccccccccccccccdccccbccccdcccccccbccccccccccdcdcccccccccccbccbcccccccccccdccccdccbcccccccdccdccccccccccccccccccccccccccccccbccdcccdbccccccccdcccccccdccccbcccccbbcccccccccccccccccccbcccccccbcccbcbccdcbcccbcbcbccccbcdccccccccccdcccccccccccccccccbcbccccccccccbcccccccccccccccccccccccccdccccccdcbccccccccbcdcdcccccccbcbbcccccbccbcccbccccdcccccccccccccccbccccccccbbbcdcccbccccccccccbbbcccccccccccbcbcccccbccccccdfcebacbddcecebdadcdbdcdcdddbdecedcbcbbcbceeebebbccddbccbcdccddebbcb`ddbdbecbebecbbdaccddcbcdbcfbbecdccdbbccecdfcebfbdccbdbebcbdaaccddcdeceec`dcdcddebbccbbcbdccebcdccbgcddbcaddcacccdddccdddbbacdbddddcccddbcbddbdccbededccddcccbdedcbbccbbaeccebaebebdee`bddbcccccccccccccccccccccdccccccccccbcccdccccccccccccccccccddccccccccccccdcccccccddcccdcccccccccdccccccccdcccbcccccbccbcbcdcccccccccccccccccccccccccdccccccccccccccccccccbccdccccccccccccccdccccccccccdcccccbcccccccdcccccccccdcccdccccccccccccccccccccdcdcccccccbcccccccccccccccccccccccccccccccccccccdcccccccccccccdcddccccccdccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccbdccdccccdcdbcccccccdbcccddccdccddccccccdcdddccddcdcddcccccbccccbcddccccccdccccdccccbcccdbcccdcdcdccdcdcccddcccddcdcccddcccccccdddddcdcccdcccdcccddbdddcccbddcccccdcccdcddcdddcccccccdccdccccccdccccdcdcdcdccccccdccdccccdddccccccccccccccccdcdcbccccbbccccdcdcd`f`kcccedbc``debac_fibabe`]g]dlhjja`icfea`eaci`k^eac\^k\_behgehdag_bhaeeiacf_c_k]affgbcicaahcabbc`a]cfeb_ae^`jhe`]`ia^`calcged`fcfdd`g`_adeaeacbg_]bacbc^j^g^dcfd^ac^bcbcbcbb_abha_ijjgbcjec_\f__fcef_gbYgceb\gceacbab^_]cd_adacaakbe_gcbedbbfccb`d`^cbfa^cbgghcebd`gaebccedhbf`bbdb`adacad`caededbdb`edebdbd``afcbecbbdcbb`dbaab`acddgecce`cgbcag`efcf`bcacddbeedcbdcf`decdbchcchdfdbf`bccfbbdae`cbfadd`eafebcbebdcacbfebecbdfcbdeedbbcbcab`cebgaeccb`daafbbeaddcegccafdcbcgdcacecdcbfdebcgfccddcagegccdacchcebdabcehbebefcbbb_erVoTgYS]igqorWWl_idcodkdOal]`gigXH[[e\hbgekljbdpcccccbccccccccccccccbcbccbccccccccccccccccccccbdcccdcbcccccccccdccccccccccccccccdccccccccccccccccccccccbcccccccccdcccccbccdccccbccccdccccccccccccbccccccdcccccccccccccccccccccccccccccdcccccdccccccccccbcccccccbcccbccccbccccbccccccccccbcbdccccccbcbccdccccccccccccdccccdcccccccccccccccccdccdccdcccccccccccccccccccccccdcccccccccccccdcccbccccccccccccccccccccccdcdcccbcdccccccccdccccccdcccccccccccbcccccccccccccccccdccccccccccccccccccdcccccccccccccccccccccccdcccccccccccccccccccddccccccccccccccdcccccccccccdcccccccdbcccdccccccccccccbccbcccccccccccccccdddcccccccccddcccccdcddccccccccdcccccccccdccccbccccccccccccdcccccccccccccccccccbccccccccccccdcccccccccccdccccccbccccccccdcccdccccccccccccdccccdccccccccccccccccdcccccccdccccdcdccccccccdcccccccbcbccdccdccdccccdcccbcccccccccccc`]abekkh\`k`bb]`c_ggkghacgfpb^^jaeecmhhi`f`gbZh[Y]_]`eYWdcbei^id`hja_gbda]^Wbebb\ci\be_Zec^^df`ae`_mbfa_]i_bcl`gdYajl_`adeechb\emcafab]_bca`^Zjdae^_f_cbd\be`ebcb_efdd`j`ccfcd]fd_hhhaa`jajabcah^bbhbccfbce\_nc^^i`b``eifcabbfnbrilah]^`\e`_`ci[fdabbg```b^gadgccccccccccccdccccccccccccdccdbdbcdcccdccbdccccbbcccbccdccdccccbccdcccdcccddccccdccccccccbccdcccbddcccccccccccbccccccdccccccccdccccccccdccccbcdccccccccdcdcccccdccdccbcdcccccccbccccccccccccccccccccccdccccccbccdbcccdcddcccccccccbcccdcdcdccdcddccccccccccdccccbcccdcccdcccccbbcbacdccbcdcdccbdccbbcdbddbbdcbcbdbbcccdccdcccdcccaccdbccbdddcbcdcbcccddbbcbdddabbcccbccccacccdbbdcddcdcbbdbbcbecdbbbcbccccbcccccccdcbbccccdbdccccdcbbcdbbcccbcbccccbcdbbcdcccbcbbcccddbdadcdcebcdccbbbbdcdccccbdcdcdcbddcccdbcdbdccdbddcccdcbcdcbdedebc`bddddadeebcbb`acceceebbbcebcbecbccdbddbdbdcbcddeacebcdfbeb`cdbba`eaccbbacecfabcccccccicddacedd`ddbfgggcccccchbddddcbdccdddbadbeeccbbddbbcebfeedfebadabdeaccecbbebddeddbccaca`cbdcbabadcbddcccdbecdeccddacccdbcbddbcbdcebcdce`dcdcddcedecbdddcegbbcbbebdcbdccdddddccccccbdecccccccddcccdcddddccccdddbdddccdddddccdccccdcddccccbddcdccccccddcccdecccdcccddccccdcecccdcddccccccdcdcddcdddbdcddddddddbcccccdccdcccddcccbccdddccdddbdddbcbcccddddccddcccdddcccccbddcdcadbccdcdccddddcdccccdddccdcccccecedccccddccccdcdcccdcdccj`bcbh_]g^[ee`f\e``emhb`defde]W_ed]`jba`emWa][[jh\kdgbi`gfcch^]dajYec[ffcfc\bdc`]nec_ecba`[afimi\Y[dadiblbfmb_TgibcbUcbhhchdhbgimk`c_afnba_g[fa^c]hf\bm]`aed`eeahZc\eejhg^Z]ihoee^g``bdbda`\b]ajge`^bebfde`dbbbej\``hhfekcdd]^dgfggakjhdfafmcedbe`^`afdk_``dfk`^ccdccccdcccccccccdcbccccccccdccccdcccdcccccccccccdcccccbcccdccccccdcccccccccbcccdccccccccccccccccccccccdcccccdccccccccccccccdcccccccdccccccdccccdcccccccbcdccccccccccccccccdcccccccccccccccbccccccdccccccccccccccccccccccccbcccccccccccddcccdcccccccddcccccddccc^eegdheaccYefcjgae[bacechg^chabd`_abc`f\hddgdee]iaacbbaYabeachgfhZea]b^^efd[[edbgh_`h]biagdaa`cdb]aambbi]`^da`fef^_kcahcdcqjca`bab`hhbieb`fgb\fcbb`bga_i^``ec^efgn]]d^amaa_k_cbc`bdbbZckg`bh]ehdc`egee_bhb`f^_fabj^`dgbdd`dfhkd`a^diZee]cfe\k`e_dhZg_ad_cdb_`jigccccccccccccccccdcdcccccdcccccccccdcdcccccccdccccccccccccccccccdccccccccccccccccccdcccccccccccccccddccccccccccccccccccccdcdcccccdcdccccccccbcccccdccccccbccccccccccccccccccccccccccdcccccccdcccccccbcccccccccccdccdccdccccdccccdcdcdcccdccbccccccccccccdccccccccccccccccccccccccccccccdcdccccccccccccdccccccccccccccccccccccccccccccccdccccccccccccdcccccdccccdccbcccccccccdcccbcccccccccdcccccccdcccccccccccccccccccccccccbbcccccbccdcccccccccccccccccccccccdcccccbccccccccdcccccdccccccccccccdcccccbcccccccdcccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccdcdccccccccccccccdccccccdccdcddbccccccccbddcccccccccccccccddccbcccccccccccccdcccccbcccccbcccbccccbcdcccccddccccccbdccccdccdcbccdcdcccccccbcccccccccccbccdcccbccccdcccccccccdcccccddcccbcccdccccccccccccccdcccdcccbccccccccdccbccccccccbbcccccccbcdbdcccccdcbdccdcdceccddcbebccccccbccbccccdcdccccccbcfcbceccccdbd`cdcdcddcddcccdccbdcdcdcddcdcccccdceccdbcdccdcbcdcdcbbdcdddcdccdcbdbddcdcddbedcccdcceccebdddbcdcbcddebdccddbcdcbbcbddbbbccccddcddccccccddcdbbbdcbbdcdcdcdcbcddddbcddbcccccccdcdcccddcbdccbccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccabggaccfabchb`ceddaef`ddaacbbgccdg`cddcdecfb`cadjaecbcb`c``ceacac_ccbhebcc_abd_bbcbcadcc`cadfcbagbbej_e`ecdacec_efbfc`defaba`dacgdgchcbahbaeebce`_cgbeeaefeddcadgddb`jbdbcbcbdaadeabccdecccadf`cedcbddf`agbdcbbacccaffefcbfdgeaadbacfccd^`ca_acc_cf_hfbea`cfdg`acccccccccccdccdcccccccccccccdcccccccccccccccdcccccccccdcccccccccccccccccccccccccccccccccccccdcccccccccccccccccccddcccccccccccccccccccccccccccccccbccccccccccccccccccccccccddccccbccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccd]aaedYif`dekg`e_`gedhag]gjcfdjefedbdacab_fiea`b[dfdkabkq]bdgagcfdibg_fhg`b_a`eggdf_cgc`mccc`_^`a^_efhcgegdehaccec`bdc`jahb_fgeagf`ecg]b`lkeifcc_c^gbdafeef^cbjchdhcfcc\hiiefeefbcagadadiefd_beebcglebgbchlgeccabeebXajdc`Zedff`_bbbgfeaZ]j_dcj^ac\[dc^`f`f`cba_fa\a`bcdfdcgbd`^cbcbbhbcbefdbga]eb_bg_`c`_ebbbdbee\eid^cfc`ce`cea_`df`bbac`dbfeg`agaabbebchcfdbbbfcdbbahgfddccebbebeccbfbbak_a`ddfbc^`c^`ccadkbdc`aeb``cbaecaaebfigdce_ddce`aeb_habecaef`debafa^_iehacdfabggddeed`acdfbddacheebikbcedg]ac`aaieafa_bf_`ebaa_bdeccbccdcdcccdccccccccccccdbccccccccbcccccccdccccdcdbccccccdbccccccccccccccccdddcccccccccccccccccdccdcdbcdccbcccccccccccbcccccccddccccbccccddcccccbccccccccccdcbcccdcccbccccccccccccbcccccccccbccccccbccdccccdccccccccccccccccbbcccccccdccdccccccccdcccccccdcdccccdccbdcccbccccccbccccbbcccdccdcdccbcccccccbcbcccccccbccbcbbccdcccdccccccdccdcbcccbcddcccbcccccbcccbccdcccccdcdcccccccbccbcbdccccccbccccccccbcccbccccdccccccccccbbbcccccdcccbccccdbbccbbcddcccdbccbdccccccccdcddccccdbdcddbcccdccccccdcdccccbccdccccccdccdccbccccccbcccccccbccccccccccccccbcccccccccbcccccccccccccccccccccccccccccccccdccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccdccccbccccccbcbcccccccccccccccccc^cj\ad\ge^ddb^l^Wicagchc\kchac]bfaccaef\\l_^adgbhde^iak\_]ggcifbdhdgaih]agfbd^dak[bfcee_i`_cf_^d__acc`ac`c_a`a_ccaebW_h`c^ajd^e_p\_cbdgk_[bcmai`ahheddfaj`ccgdYh]jf_a_^i^fndfddecac_ncc_ecgci[^am`hbhnZbirc`gf^[^k^e_caddh^a_hfda^ciak`cbjihjadnghe^fbcg_`g]`]\hcccccccccccccccccccccccccccccccdccccccccbcccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccbccccccbccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccdcccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccddcdcbcccdccccccccccccdcbdcccdbccccccccdcccccccdccbcccccccccbccccccccccccbccbccccccccccdcccddccccccdcccdccccccbddccdccdcccbcdddcccccbcccdcccbcccdccccdbcbbccccccccccccddccccbbdcbcdcccccbccccbccccccbccccccdcccccdbcccccccccccccccccbcccccdcbcdcccdbeccbcccdcbcccccbceccdccccccccbccdcccccccccdccccdccccccdcdcddbcdbccbcbdcbcdccbbccdccdcbdcccdcdcddcccdccddcccdccbdccdcccbcddddccccdcccccbdcccdcccebccdccccbdcccddccdccccdcccccdcccccbdddccccdcccbbddceccbbddddccedbdbcddccccbbbbcbddcccdddcbccccccccccccccccccbcacdcdcbccccdcccdfbcededccacabcaabeddeccecdcecddebbcdadbcecddcaebbbdbcdbecccccccdfedcdcbbeedcbbdbb`bccbd`bbcdfbe`dgcccccdcdcccbceddcdbbcdbdfcbadbbdbedcddcecbbfcbecfdacacecbdecede`badhcedecedacbaccdcaccabebdbccbcdadaddbbddbeacddfcbcccdebccccbbefcddebedfcecbedaccccccccddebcceceadcdbccbddcdccdbcabdddddbcbebdccbcdcddeeddeccccccdbbbcbcdbcdbcccdbccecccffcedcdcccbbbccccddbbccccdcbcddcdd`bdedec`dcccccebccccccccbcbdbdbdbcadcddddedbecdbdeccbdcbgceddccccdbcdecdceccdcfeeddecbbdbcdcbdebcdcaddcdcdcdecdccebcdccfdacddfdccccdfadddcbdbccdbcccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdbccccccccccccccccbcccccccccccccccccccccccbcccccccccccccccccccccccccbcccdcccccccccccccccccccccccccccdcccbccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccbccccccccdcccccbcccdcdccccbcccbbcccbbcccccbcddcbdbcccdccbccdccbcccbdccdcccccccdccccbccccccccccccccbbdbcccccdccccccbdcccbcdcbcccccddccbcccccccccccccccccccdccbccbcbccdcbccccccbccccccccbdcccbcdcbccccbcccccbccccbcdcccccbccccdccccbcdccccdccccbccccdcbcedebbbdcccdecbdbccecbccdcbcdcbcddccccddbdbcccebdbddbbbcececbdc`fdcbdbbeccbebbdeddddadbcddeecabdddb_aachbccbfbdcbcbcbcabcecfcbdcbdc`bddbccbeedbccceedddbbac`ccbdbfcabadbbeba_febbccdbdaacaddccbcbccebdd`ecbcdcdccfdcdcbddfbdabcbbbbeccedcdabacadeaabebcc`baccf`ccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbdccbbbddcdcdbcccccccbbccccdbcdbdcccccccbcbcbcebbcbccddccbccbdbcbbccbccebccdbdccbccccbdaabbcbcbbbdcccbcdddccccdcbccbcbcbccccccccbcdbbccccdcdccbdccdcbcbcdbaccbcbcccbcbdbbecbcdccbccccccdccdcbadcccccccccdbcbbccdbaccdcdccddddcdbccdbdccaacdbccbbbdcddcccbcccdbccccccccccdccbcbcbccccccbbcdbdccccccccccccdcbcdcccbcdbcdcbccdcccbdcdccdcdccdcbcddccddbdcbbdcccccccbccdccccccccccccccccdccdccbdccccccbccccdccccdccccccccccbddbcccdccccccdcdcdccdcdccdccbcccbccddcdcccbcbccccbccbcccbcdccccdccbcddbccccbccdcbcccccccccccaddcccdbcccb^dYb\ecabfid]]idbi_gc]]eaaee]bacjcfbebaaf_^dc`ce_`bfcdmcf_bekabbf[b^j_hmfe`e\_gbjfccdeWeedidk_]dcafaakcj[`cgjh^``bc\ehe_cbiikdc[bZb^_jcgbbefaicbe]ca]^_adhcaf]fabcacj\`ca^\`^^l_aid`b^gi_f[ed[ihban]dca`cldYhfcb^]mh_`ik\df`i]fecihbfdalk`ebclc`gbf_geihibidig]]ccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccbccccbcccbccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccbcccccccccccc_h^cgceddgca^fc`ca_^degcdd`cbccec`b\kedbcfa^aahg^f_c_hbhbgc`_aecgageadagbbbgf_llib`h_adfebc`egef\cdibcdac`ebhabdbegd_ebf`fgjeebc`edcegfadf`adcgdc___dc`gedbdgc]cdb`hdacc`bdd_ee\`c_bkda_cc_kdbgbd_chdcb_^abafbZcbbdcff``f`e`dbdac`fhccfebcf_fkc`bbda`_fbhbbdcdcccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccbccccccccccccccccccccccdcccccccccccccccccccccccccccdccccccccccccccccccccccccccccdccccccccccccccccccccccccccccbcccbcccccbccccccccdcccccccccccccccccccccdccccccccccccccccbbbccccccccccdcccccccccccccbcccbccccbccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccbdcccccccccccccccccccbcccccbcccccccccccccccccccccbcccccccccbcccccccccccccccccccdcccccccccccccccccccccccccdcbd\\dab^idgjicgjTab\fafd\hg^bdcdadpdec[]a_cfdYheg]adhj`aX_ca\cfalfe^ikad_e\ej_eaaf_`c_Ubgfcccfj^`hg\fhef\kca]`__gd^jlfeb_a[dSiZd`]eaaj[\g`a\le`l`_gbac_`dbgfbagbi_dbd]clbbdeefeZgbicmfefadhacce\[e][lafj`Wgl`cgbjamcibbgjf`jehf_c[h_c^cadija_hccmfhp`eadafglhd`efh^\f_`aibicmhff`gc]_feY_]dci_b_cadeajaejffbce`km]bhkjefa_bdh^igkdh`faccbd`iccecg_fcecdclja_edebb`cde`abd`bh__bfaadfheg`fcbc`cadgahgdefdeg]ddba`dd`]d_`^ddeee_b\b\ce]iefgfbgb_afc`j]agi_cdgh]f\]Xcbii`_fe`_a`dd[dbeeb__cjhdgk_k_^bf[cificdc_df^`f`dld_kibceicfbddbdcbdcccdcccddcbbdcccbcbbccdcdcdcbdccccbdbdcccdcddccdeccccccccbccdccccccdbcccddccccdccdddcdcdccebcccedccecbcbbdccccccccdcdcccccbbbdbdcbcbcccdcbccccdcdccbcbbcccccdcccccccbccdcccbbbcbcbcdccdbbdcdccbcdccdccbbcabdbbccccedccbbbcccecddcbbddccdcccdccedcdccdccdddccccbcdcccddcccdccccbdcccccccccccccddcccccbcccdcdddccbccccccccccccccccddcccdccdcddccddcbcdddccdccccdcbccccccccdcccccccddbdccccccccccddddcbccdcccccccdddcccccccccdcdcbedcbbbcbcccccdccdccbcccdcccbcdcdcccdddccdcbccbccddccccccccccccdcbcbccddcccccdbcccbcccdccbfbdedmfcda`]fgccfgegedieacda`_f_agf^bedghcdb^\^_gea\c^cc`ecZa`lbh_dbbf_c`e\^_e`dbafh`_fbecad[fddcb`ahgcba_cddebcdc^_b^ecc_fhbbehdcadecbfeace_`bc^dcceb```_f`cdbba`e`fidlbce``ii`bck`adigcgdhdeea^e``ebihb\dc``cbeeddfdbbcbib]agcab^gad^bdc^fa]bebbdgfc_bee`hchhf`bhbkca_egd__acg_bf_aa^caebicbedc_adbbbga`hhdbeddb]a`^fd^abddfgeadc`gdc`ba`baeded`ddcdfdecg_cfgfdabbbdbicbbadgcbceccbe_dbbfdcdc`ed^abb`b_^a_dcbcd_cbbd`acfdgcggegdbbecbbe`c]d^cbceccjeebecicc`ccagjjdeachge_fb`ej_`dbbca`cefcdd`ebhj`ibbecbecbpeaceg_ccfe^cee_bbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccabccdccddaacbceebcdcdacbebdbcccccccdccdeaabdgcc`a`bbdcaddbcbcbcdddbbbcceccdbacacdacdfdabebdbcccefcbedcbcdabedfecdeccccbbceecdddebddccccdacdccccefdcafcdfedfccccacdbdbeaaddccccad`dcbcdccdecbcbbbcbdbcddbbdbaeabbdcbbadccadbcdccdbaeabcfdcfcbaccbccccbbddchcadcccbcccbccbcccdccccbcccccdcbcccbbcccccccccccccccbbbdbbccccbbccccdccbcccccbcbccccccbccccbcccbccbcccccccccccccccccbcccbccccccdccccccbccbccccbcdbccccccccbcdbccccbcccccbcbccccccccccccccccccccccccbccdccccccccccdcbcbbccccbbcccccccccccccbbcbcccccccccccccccdbcccccbcccbcbbccccccccdcbccccbbcbcbccccccccccccdccccecccccccdcbcccccccbccdcbcccccbcdbdcbddcbcddcdcbccccdcdccccccbccccbdcdccdbbcccccdccccccccccccccccbcccccbbbcbcccccbbccbcdddccccdcdcccbccdccccdcbdcdbcccbdcccbdccccbcccbccccbdcbccbbbcccbbccbbcccbccccccbcbbbcccbbdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccecdeefaabcc`ce`cbbecdcccdccbb^cagbcbcecbcd`ddecbfcfad`b^ebaceccacde^aceadbdcaaccdddebdccbddcdaaacbecbcbccbbafbeedbabgacedddec`fcafdbcfcdc_gagbbcfcbddab`addb`dbedbcchbd`cdfaabadcbddbcbaebcbfcc``ccefadedcdc`fdbddjceccdebbcdbbddadccb`ffbadaddfad_hb`bdbb`bdde`cgedagchdhgV`hcbdbZ^_`dba^_lbe_cdac^hec`gbc\cZiZcaqahh]]b^^cdeb[acf]db_aaaie`gcfchlbbea`d]afdea`e^b^fcccei`f]d\hbgc[]\hke_ee_a`adcbeba]c^ffdhe`a_bh\dbggk`jkbdhf`dgcgbfcd^ebdabjaedi_ekf_abegbdbeadgafcbgecjgge`_^faWgg_\deefba`hbahah`a__ifjfg^afachbakbffbgffcddbdccdcccccbcbbbcccdccdccccccdcbccbccdccccdbddcccccccdcccccccccddcccccdccbcccccccdccddccbbddccccccbcccedecccdcccbcccccccbcccdcddbbccdccddbdcccccccccdccbdccccccdcccccccccccccccccbcddbccccccccccdccbcdccdccdbcdcccdcdcccdecbcdcbddccccdccccbcccccbcccbcccbdcddbccbbbaebbcbcbebdbab`cadbbceba_h`dcbc`deaddbecdgbebefccddbchdeb`abcdcedfbabdaddfebdb`bccaedbgddcdedcdaedebedeacadcdd`bbfddccbba`c`edbcbbbaaccbedge`lbdde`fa`dddbcccedbaeddabdabhbbbcebcacdbccbec`cbcdbaddgcceefbcbbcdccbcababbbdccebcccb_cbccebdcddd_cabdbcaddc`dccccccdcccccccccccccccccccccccccccccccccccccccccdccccdccccccccccccdcdcdccccccccccccccccccccccccccccccccccccccccdccdccccccccccccdccccccccccccdcccddccccccbdccdcccccccccddccccccccccccdcccccccccccccccddccccdccccdcccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc`ca]bcabac_l_d`c`da`Z_b^f`bliikghcb`]iYd_lZjj__[f^hbddjff`gdf`edcckib[kcdcegfa[_afkjkke^kaf`dfgak`fZa[^_]kcli^h_adbaeec`aa[`aeede`^b_bdbZ`jdg_^geegakm`bceabeefafgm]`ea]dbe`fbaehl`c_cfcefgagea^_\`abe_bckcbc\cXj``_[\ihe^bahjgaacb_cbh_`deijeaff_]`_pf^iaeec^d`cccccccccbdcccccdcccccccccccdcccdccccccccdccccccbccddccccbcccdcccccccccccccdcccccdcdccdcdcdcccccccccccddccccdcccccbdddccccbcdcccccccccccccccccccdccdccccbbcccdddcccdccccccccdccdcdccccccccdccccccdcccdcdcdcdcccdccccccdcddcccddcdcdcccbccccccccdcdccdccdccccccdccbccbccbccbcbcbccbcbccdcdbbbcccccdcccbcccccccccbdddcccccbcccccccccccccdcbcbcccbbccbdcccccbccccccdbcccccbcbccccccccbbcbccccdcbcccccccdccccccccbccccbcbcccbcdcccccbcbcbccbcbbcbdccdcbcbccdcccccccccccccbccccccccccddccccbccccedccbcccccccdcdcdccbbccccdccdccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccd_acbacddec^_fcbeaZegYehhbiebdg]hebccbejccbd_d_g_ddhZd`\gfb`ebbdacgca^bbfeg`achgckbaccebddc_gceeeiaaagkedegbfd_ebacdida_`cgeabbdcibaabdcid`eciccdfaf]fbebaeba\dcf^bbl_gagcccagaiccdc`cc`_b_d^_abaaidcbgf`bceedgeaaebb[bhd_]efbdc_ogededee`ffeebcdhdc`egcgad`hfab`bbbbaccdbbcbaebacdbaccbeebccdedbcdbbfdcbbdcdcbabccedaaccbbcbadbebbbbbcbcbcdabebcbcfddcacabccccccedcaacaabbbcdbaadc`cae`ebecaccacdbdfadbaebecccabbcccdcddbdbcccdabcccdcbcdddcdbcbbdbbaddcbcacbccccbadcbdeccacbcbcbdcbcecdccebbbbbdcacdcdcbdcdcacdabecbcbaccbcbdbccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbbcbcbccccbcccccbccdbcccbcdbcbcccccccbbccccccccdcbccbccbccbcdccbccbcbcccccccbbdbcbccdccbcbbcbbcbcccbcbcbbbccccbcccccbbccccdcbdccbdbbccbccccccacbbbcccbcccccccbccbccbcdccccbdccccccbccbccdcbccbbccbcccdcccccbccccccbcbccccccdcbcccccccbcccbdbccbbbccdccccbbcccbcdeabccddccbcac`cbcdcccceccc`bbbdcbccdbcccccccabcebbcbadeccabdccaccdcdbccb`cdccbdaccedebbcdbacbcb`cdabcccbdce`baabbabadccaccbabccbbdb_bbcce`bdcdcbccecabdcccdcdcbccbcabcbbcdcbccecdaccdbbbecbbbceccdbbdbbcbddbbcccb^aebbccbdecbdbddcccacccaadcccccabf_ebcccdcbdbcbfd`f^^blg_ag]aacfcfbcfcmf]ilef`dX^^eabdaaj]adedhg[b_ahfbce``hgdfk_\`rhkhdeaYb^l]a_h`X`_caecce[^ddg_bhagcbbhac_aaeab`faccde`]aekhecgacjd_eYe\ea`d`]gbfbh^pddZ`fbY]^cdacp]_^\``f[cg`dd\d^`^cadigfdgepf`ef[\c`ebbbgib`ggnh^cXbd`b_iaaaekobmeg^bdbeabgii^ajda`co]af`ccccbbcccccccbcccccccccccccccccccccccccccccccbccdbccccccccccccdccccccccccccccccccccbccccdccccccbcccccccccbcccccdcccccccccccccccccccbbcccccccccccccccccccccccbccccccccccccccccbccccccbcbbcccccccccccbccccbccccccccccbccccccccbbccccccccccccccccccccccccccccccccccccccccbccbcdbbdcccccccbccdbccccccbcdccbcccccdcbcccdccccbcbccccccbcbcccccbcccdbccbbccccccbbccbcccbcccccdcccccccccccdbcbcbdcbcccccbcbccccdcbcdccbccbccbcccccbebdbdccbbcccbcccdccccbccdcccccbcbcbbbdccdcdbdcbcccccccccdcbcdcdbdcccccdbcbdcbbbadcbcbccccccddbcdcccccccccccdccccccccccccccccccccddccccccccccccccccdcdccddccccccdcccdcbcccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccdcccccccccccccccccccdcccccccdcccccdcccccccccccccccccccccccdccccccccccccccccccccdccccccdcccccdccddccccccccccccccccccccccdccccccccccccccccccbccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccbcccccccccccbcccccccccccccccccccccbcccccccbccccccccccccccccbccccccccccccccccccbccccccbcccccccbcbccccccdcccccccccccccccccbccccccccccccccccccccccccccccccccccccccccbccccccccccbcccbcccccddcccccdcdccdcbccccccccdccdcccccccccdccddccccccdcbcccdcccccccccccccccccccccccccccdccccccdccdccccdccccdcccccccccccccccccdccccccccccccccccccccccdccccccccccccdccccccccdcccccdcccbcccdcccccddcccccccccccccbccccccccccccccbccccccccccccccccdccccccccccccccccccccccccddcdddcdddccddccbcddccbdcdccdcccccbccbdddccccccbdddccdccddddadcccdcccdccddcdcdcbccccccccccecbdcdbcddcdcebccccdcbddcccccbbccddcbddccdcdddcddcccccdcddccccecccccddccdccccccbccbcccdddddccccecccdccdccdcdccbcccbcdddcddceddceccdcdbcbcccdccdccccbdddcdcccdccedcbcdcccccccccccccccccccccbcccccccccccccccccccccccccccccccdcbccccccdccccccccccccccccccdcccccdccccccdcdcccdccccccccccccccccccbccdcccccccccccccccccccccccdccccccccdccbccdcccccccccccbcccccccccccccdcdcccccccccccccccccccccccdcccccccccdccccdddcccccccccccccccccdcccccccb`ielchfadd[gqjgc`edhlijb]jej^l]]clYjeaegi\a`_bbibk`aZhqj_q`f_i^`bga[``hi_abbkZZei`g`d`Vp]gdcae_g[`\ag^e_che`Zi\jZWjV]abZnf`o`d_e]Znfgkajij`f[o^`fh\iedbcshbiib``nXiahjaVXeadcdbdd[]lhYjfec]`be^efdb_dggc]`\e]bbmiab_amedbbffW_e~h]a[`jk^dfd]Xhgfe`^Sidbc\ligah`kcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccdcccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddbbffeccdccccdcccbcbfccddccddbcdcbedcbbbcccfcccdbcccdcbbccedecdccccbebcccdecceccddccccfdceccdbbcccdcgcdddcccbbccdabcddcbfdbcbcbcceceadccccbcdgbdddecdbcddbcecbecfdcddcaccccefcbddedbcbdebcbccedccccdcbebdccbddccddcdcce`cbcbdbcccbbdcdecabccecddededddbdcbfdecebdbddcbcdbbcecdbdcbcbcccbdbcaaccbbdcbbeccccdbcbcbbcdecbeccddbbcbeddbcddccbbdccccccaccdcdcbdebccccecddadcccddecdecdfcabbdbbdcdbdccdbdaebccbddcbdccddcdceaebdbcceeccccddcccdbdcbbcd`bdbbdbccbbcdbcbbcbcddcacdc`dbaccfbdbcabbfcecdcdccecba`bcfdddbebecbccdcbdabcdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccbcccdccdccccccccccccccccccccccccccdccccccccccccccccccbccccdcccccccdccccccccbcccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccacaaad`begbb[``b`a`be`addfb`ce``gdee^fhdcedbfe_e\dejbceZ`bdcacba[bbd`dcbdfddb_bbdbegbdc`bbacebfbefa_\cegedfdbcabdefd`a]dddebecddadbe__cad^eb_f`aedee_fdjafceccbebbe``ec]bbef`^`bfcedcabdaa`bdddc`ceecbdjadadcccea`cg__egccabdecbcb_bdchfebdcg`bdfce`_eddhadcdcd`ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccZd`efeegmfdNakd^[fggZdabbm^icid]e^f`[^chdcfhkdjdgb_f_bg]df`gcXfj_ajkehd[dilaajgal^adcZdb^bb^clZocbd[co`d]lkaf`dee^bclpe[d_ZfjbkeY__m]beob``Zl``Udc`glged]a^b[Zec^fjbfd^abZagc^]`bf\bga\[X`X^m`]b^h[ebbjh]kecgcgm\`aghY]ndfcklbibh^aZbffj`b`e`hbfdjqg\]icccdga\e\cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc[[khja_ddi[c`\ccacjcin``aei_ojfkagdddg^Z^ifaahbh_`cfcZjpebichhiibaedidd^^m`eele`dfdehm`Wcg^cb`jbh`e`^_k_eea]__k^aidn[Z`d`_jc]`gejeca^WbebbdaicidW^fjlbbfb^]g]_dakd[l\Z_laiadlabho`j_embemdif]_dlgaim`i^bmd]`igdechida\c]e\if\`dc_]eibbgZ[^cf\Zccfead\_ghXig^b_]`cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdbdbfcbcbbbbcbab`bddcbccbdcccbcdcaccabccbdbccccabcbccbedebccccabbfbbcbcccebcbbacbbbccbacaccbcbbdcbcabcaddcbbbbccdcbcbbbccbabdccdbbbcccbcccccbcaccddabcdccdddbccbcdbcabbbbbccabdcddddcccdeddbdbbcccccbaacaccbcadbdbddcdefbdbcbbdddacbbcbccacccabcbccbbbedcbdbbbdbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcbccccccccccccccccccbcccccddcdcccccccccccccccccccccdccccccccccccccccccccccbcccccccccbcccccccccccccbccccccccccbcccccccccccccccccccccccccccccdccccccccccdccccccccccccccccbcccccccccccccccccccccdccccccccccccccccccccccccdbccbccccbdbccdccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdbccdfbddededcff`eeecebcbcdaaecddbdbbfcccbbceaceccadgcbcebcdddecdcedbcccdbbebc`dfbffcdbhefececdabaeceddccddgfdcaadcdebdcecageccbcdcedfcedcdbccedccdeebcddbb`fbeeffccdgbicfdcdddbbbdbdcdbcbecdecbecbadbdccefhbeaccbeabdbaeddadeccccbccdcaaddccgcdccagecbccccbbfdecccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccdccccccccccccccccccccccccdcccbcccccbcccccccccbccccccccccccccccccccccccccccccccccccbccccccccddccccccbccccccdccccccbccccccbccdccccccdccccbcbcccdccccccccccccbcccccccccccccccccccccccbccccccccccbccccccccccccdccccdccccccccbcccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccbcccccccccccccccdccccccccdcccccccccccccdcddccccdccccccccccdcdcccccccccccdcddcccccccdccccccccccdcccccccccdcccccdddccccdcdccccccccccdcdccccdcccccccccbcdccccccccccccdccccccccccccdccbccccccccccccccccdccccdcdccccccccccdccdcccccccdccccccccddcccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccebddebcdcdbdcccedeeccceddecccdecdcdcdccdcddccdcdcdcbdbcccbdcdcccedddcdccccdcbdccccddddcdddccccccdccddccccdcccccccbdccddccccddcebccccdcccdcdccccdcdccccceddcdccddcccddcdddccbcdbdccccccdecccdcdcbdecccbddcdccceccdcdcdcddddccbedcccdecdddcddbdcedddcccccddcdcdccccccccccccccccccccccccccccbcccccdccccccccccccccccccccdcccccdcccccccccccccbbccccccccccccccccccbccdccccccccccccccccccccccccccccccccccccccbcccccdcccccccccbcccccdcccbcccccccccccccccbcccccccccccccdccccbcccdccccccccccccccccccccccccdcccdcccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddcddcccccdcdccbccbdccbcdccdcdcccccbcbccbcbccccdcccdcccbcccdbcdbdccbccbdcdccbccccbcccdcccbbccdcdbcdccdccccdcccddcccbccdcccccccccbdccdccddbcdcbcccccccdccdcbcdbcbccdcdbdcccccccbcbcccbdcdccdbcdcccddccccccecccccccbcddcccccbcbcccbccccccdccbbcdcdccbcccccdccccccccccccccccdccccccccccccccbccccccccccccccdcccccccccbccdccccccccccccccccdccdbdccccccbbccccbccdccdcdcdcccbccbccbcccdccccccdcccbcbcccccdcdbccddbcccccdcccbccdccccccdcccccccdddcccccbccccccbcccbdcccccdccdcbdcccccccccbcecccccbcccccdbcccdcccdccccccccccccccbcdcccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccbcccccccccccccccbcccccccdccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccbcccdcbccccccccccdccccccccccccbcccccccccccccccccccccccccccccbccccccccccbccccccdcccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccca_bedafcech^ed^dadcbdgfdid`ihbafabadb^f]eficbbeee_cgbeccbfiabedeeaf`cbcgdbg^`cacecca`fcdcbddffcd`cbhdbdcaecedeb_a^ecdcbd^dhdeche`_ccgdedfeddbac\cccebbdafdeg`bbdaccfdbcbcddcgacbecafgcacda_e`dd_bcdgegef_fcea`dbbdccbg`ibda_d^addccaj^edgciacdececa`cbgeaeef]g_bdccdcddccccddccdcccccddccdccccccccdccdcdcddddcbcbccccccbcdccccddbccddcccccdcdcccccdccddcbccccccceddcbdccdddcdddcdcdcccbdcdccddcecccdceccccdccddcccddddccccccbcdcccdccccdccddcbcdccdcccbcdcccddcbccccdddcdcccccbcddcdddddddccddcdccccccdcdcccdcdccddcdcccdcccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccdcddccccdbcccdddccdccbcccccccccccbdcdcdcdccccecdecddccdcccccdccdcccdbccbcdcbcccdcdcdcdcccccddccccdcccccdbccdbcccdccccddcdcdcdcccddcccccccccccdbcccccdbceccdccdccccdccdcdcbccdccccdbccccdccccddcccdcdbcccdcccddbcccddcdcdbccccccbcccccdccccdccccdcdcccccccdccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdbdbcdddeddcebddddccbdccccdddbdeccdcedcddddccccbbddbdcddccddcdbcdddcdecedcdcbfddedcdbdedddccddfdbdccccceddcceddcdbccccdfdcdedbcccccbecccddccccdeeebecfdddbcccdeccddccacccec`cbdeccddcedccdcdfdeccdbceddcdecdcddddacbdbcdbecdcccdccecccbbbcbdddccccccbdbdcbcbdcdaccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddcccccccccccccccccccccccccccbccccccccccdccccbccdcccccccccccccccccccccbcccccccccccccdcdccccccccccccccccdccccccccccccccccdcccccccbccdccccdccccccccccccccccccccccccccccccdccdccccccccccccccccccccdccccccccccccccccccccccccccccccccdcccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccdcccccccccccccccdcccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccfcbcdccbccbedcbdbcacddbcbdccdcddeeebcdcdeccbbbbebdcebccbeecbcbbdccbcddcdcccccdbcdcbbcccdcccdceeddcdcbdbdddcfdbcefcdbccbccbdccbdddefdedacbebdccddccbcbadcbcfdccbdcbddbccdddbcbbabaccbccdbccccbbbccedccceaacbecdacddbeaccedcbadcbccabcecdfcbddbeebcceccdeddadcaccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccddcdcdcdddccccccdbccccddcdccddcdccddccccdccddccccddcbccddcccccdccccdccccdccccccdcdcdddccdcdcdccccccdcccbcccbdddcccccccdcccccdccdbdcdcdcccccccccddcdcccdcccccdcddcccbccccbcdccdcdcbcdccccdcccdccccdcdccbcdcccddcbccccccccccbcdccddcccccddcdbcccbccccccdddcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbddddcccddccccdcbdcddccccccdcdddccccccedcdcdccdccccccdbbcdebcddbcdcddcccccccdccdcdddcedcdcccdddddddbddecdcccdcddcbccdbddcccccdcccccbccccbcbcdddddcdccdccbcccdecdddcccccdcdccacccdccdddcdddcdcdccceddccdddeccccddccdcccccdcddccddcddcdbdcdccccfdcdcdccbcdccdddccdcccccdccccccdcccccccccccdccccccccccccccccdccccdcccccccccccccdccccccccccdcccccccccccdcccccdcccdcdcdccccdcccddcccccccccccccbcccccccccccccccccdccccccdccdcdcccccdddccdcccccccccccccdccdcccccccccccdcdccccddcccccdccccccccdccccccccccdccdcccccccccdccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddccccdcccccccccccccccdccccdccccccccccccccccccccdccccdcccccccccccccccccccccbcdccdccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccdccccccccccccccccccdcccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddccbccbccddcccdccccccdccdcecbccccccccbcdcccccbcccbcddbcccccdcccdcccccdcccccdccccbcddcccccbcccddcccdcccdcdcccdccdccccccdcdbccccccccccccbcccccddcbcccccccdbcbcccccccbccccccccdbccccdbcddccdcdccccccbccbccccdccdccccdccccbccddccccddbcccccccbcccdccdcdcdacgcacfaeaf`efdcia`ckh`agee_e_``accffafbg`feagafbdhbdf`^b`a`c`cfbbbcdc`chebd^cbbai`_dfb`edbdag`efadbeibahc``Zidea_e_e``dc_d^aaeadbd__dcibba_bba`b`ebcbabef`f`cahdgbchdl`abcb^ace_gbed`abcgedaedbedaf`feba`cdfbdbabcccbeiffbaebbfdf`ha_eiabfibafga`gbac_c`cfdddgaccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccdccccccccccccccccccccdcccccccdccccccccccccccccccccdccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccdcccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccdcccccccccdcccccdccccccccccccccbccdccccccdcccccccdcccccccccccccccccccccccbcccccccccccccdcccdccccccccccccccccdccccccccccccccccccccccccccccdccccccccccccccdcccccccccccccccccccccccccccccdcdccccccccccccccccbccccccccccccccccccccccccccccccccccdcecccccdcccccdccccdccccccbcccccdcccddcccccccddcdccdcccdddcccdcdcccdcccccdccdcccccdccddcddddccdcddccddccdccddccbdccddcccccccccddcccdddbccdcccdccccccddcccdccccddcdccdccccdcccccdcccdcccddcdccccdcccccccdcccdcdccccccdccddcccccccccccdddcdcccccdccdccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccchihh``ibca[abhag^egi^faceacdghhdkfdce`dgcdff]daed__bddek_ibbda`edhegjec_egbcdc][a`jb_fegV\dkcf_fd`fd``e_aabde`fX_\f]gd^cflZ_``ke__fj_lh^badd_d^djgfgiacefn^jflncaajdcc`fjgcb_]_fl]dgbe\dba^agabc`iecadk_dgZbl[dc`jXfacgheeehdcj`fh]gdii]ch^faedefhc_^cnebeehkbb]cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcbccccccccccccbccdccccccccccccccbcdccccccbcbcccdccccdcdccbdccccccdcccccdccccdbccccccbccccbbcdccccddcbccccdcccccdcddcccccbccccccdbcccccccccdcccbbccccccddccdccccdccccddccccdccccccccbcbccdccccccccdccdcccccccccccdccccccbdbcccccccdbccbccdccccccbccccdcbcedcbddccccbddccdccccccccbcdccccccdccbdccccdcccdcccccccdcdccdcbbccdbccccccccccccdccdbdcccccccccbcccbccccccddcdccdccccccbcdcccdcccbdcccccbcccccbccccdbccccccccccccccbcccdccccbccccbccccddccccccccdccccccdccdcddbccdbccccccccdcccbccddcccccbccccccdbccccccbccbcbcbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbeddcbccdbdc_dbbdaecdddcddbbbdeadeeabccdcbdccfdecbcebcadadgddddcbcdddceabgebdccadeccc`ceedcdbadacdbgcceddcbbaccddceddcdacbdbdbcfbebaccdccdeaacdeccebedaba`aaaeececbbcbcdcdfbeeabedcacaacccddebcbdfcccdcdfebcbcabccacbbdcdccbcbedddcdcbdcbbacdedcfbfccccadcdabfbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbdbda`dbbbbdbdabdcdddcbcccdbbbcbdcbccbcdbbdcdcddbbbbaced`dbbcbdcd`cbdbcaabdedcddccbbcccbcbbbcdabbacbcccccdcdadbbbcbdccacbbabbbbccdbbdcccccbabcc`c`cddbccecbcdcccccdbdccecceccbccdbcbbebbbbcbbcccdbcbdbcabdbbdd`dcdcbdbbddaaabecbdaacdbdbccadcdccbcbceddbbdacdbbdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccdddccccccccccccccccccccccccccdcccccdcccdcccccccccdcdccdccdccccdccdcccbcccccdcccccdccccdccccccbccccccccdcccdcccccccbcbccccccbccccccdcdccccccccccccdcccccccccdcddcdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccdcccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccddccccccccdcbcccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccdcdcccccccdccccccdccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccfcc`d`bedcdfibecaccecc`bcdacfdicdccdcgadbdedbedbeacbbaadccb`c`aceccccddcbdbddaedgaefbbcbdcbcbaeaecbcebbeceacc`ecadcid`ceeebgecccddgdhagbacdedbed_cc]dbcbbdcdbabbeeadacadccddcde]ce_dddebddccbfcddf`dfcdbdcacdcddfbebdb^cbdd`dedbecdccdcabdccdbecdbZhededcacababcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccdcccbdbcdbbccccccccdcbddcbaccbbccdbccdddbcdcbcccccdccbdcccccccccccccbccddcccdcccbccccccdccdcccbdcbdbcbdccccbdbecccccdcccdccdcbcbddcbbdcdcdacccdcbccdcdcdbbcbbccbdcccddcccccccdcdcabccccdbcdccccccdcdcccccccccccbcbbcbcccbcbbccdbccdccdcdedcccccccdbcbcccdcbdcccbccccccccccccccccccccbccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccdcccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccbcccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccdccccccccdbcccccccccccccccccccccccccccccbcccccbccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccdccccccccccccccccdcccccdcccccccccccccccdcccdcccccccdccdccccdccccccccccccccccccccdccdccccccdcccccccccccccccdccccccdccccdcccccccccdccccccccdccdcdccccccccccccccccccccccdcccccccccccdccdccdccccdccccccdccccdccccccccdccccccccccccccbccccfaake^fmdY_bigbb]ciXaZfjkghfagiTp\_bd^dfj`efafc[b^dd__ie^[b_g\ahcaWalZWejfef_jccVbf^bf[ifhhemhiih__hcZsjddV]_cU_dbkcekggdega]efjceff`h_k`[gYkcbhiYad\]gb`_dgibeeg_Wb`]^Zf_f_cc]bca[d_^lgdhhgbmh]`haab`fb`gdeechbpf`fbWfnbabe]gif_behZniTte\Zhhdehhe^bciehtceo__bbgcca`ababcc_dfkfgg_abcca_bbfed\ehf`cah`fdb`\aeeggcedecaddadcccc`ief`he`fa^cbg`cedfdafcb_hdbfdbcdfjdcgef`cdcfcbadd_bdbbbaefdebecbbddedcafafhcibfcccc`e`jeaeeddgfbbdedfecb`ed`ecabc^af_fdccbebcebdeceeif__gccce_`cd`ccbdhcaaggffZbbcdd_bdecc\bcebacn`i`bbfc_g`faccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccbcddaccccaceccbbccbbbbcdbccddcdbcbbccdcecdbccbdcccddccecbcbdccbcddcdccbcccbcdddbeccdcccdcbddcdbdbcbccccddcddcccbcccaddddcdccdcdcccccccccccdcdcbdcddcddcebedccdcddcdcdccddcccbcbcbcccbdccbdcddccbbccdcccccbcceccbdccccdcdccecddccbccbcbcbcbdcdccbdecbcccccbcccc`bfRagc]c]x[e^le__mj_Wj]^e^lfrjqk[mddd]_^ndXqcZiccd[W`al_YKiqUf\eZ^c^`kj[]lsgn`^k_Vlcge_YYdajjdfbkb`emprg`wschLXnlt^_[Zf_dedaeaUjc]]akhWgjYzQYY]:\Xjcabe~Lf\k`flbhenZjYbcT]a^\^keahYlhae_gaid_\bY`bbbh\\c]_nnp`[^_^ub^m[b_aeii]bhg^oahbTm`d\fXZg\NkX]kr[dhkWidWbbcccbcccacbcccbbccbccccbcdcdcbcbcbcbdccbcbbccccccdcccbccccbcbbbcccbbcccccccccecccbcccccccbccbccbccbcccbccbcdccbcccccccbcbdbbccccdbccccccbcccccbbbcccbccddcddbccccbcdcccccccccccbcbcccbccccdcccbccabccccccbcccbbcccccccdbbcbccdbcbcccbccccccbdccbbbccccccccccccc\fd^b`h_mjfnei`^Yfak`cagl]]^_igug_bgdc]m\dQa[ebbdaX`\^k`fqaf]Zff`j`f_]o`cld^aZbZc_Vifdbh]ed[hccogpe_^ddl^hk]fZfki]deojf]Zajlflfjci^_[fZYlb`dj[paebc]knbmR`fb_f\diW_gXgkeb_mZgZcj`ghc^be`hjVe[ZZbjhpg[b][itie^fna`blcYZpefu`\fj`iRfhU_ecgh_hmgia\h\gfaijj__h`gfiakb`^]ag[gbed[[hcubbqd[bcg]a^cZ`kaW_iriheaj\eh^bfe^j[dVbTe`Z]fXdgbhiobeg[^de_`a`daa_]VdcddehgZ[dlkVYYem_`cceqa^egce[j_eikkoVhbkcfdb``^hg`dj_caa]^^]oa`j_f\dd\^dg`pca^U_h`Ub_gbdeaXZfe^gfef][_ce`h_^e\ZYc``dhd_edaXlbc_bkhbXikaeifedegeoZfbfWi`Zb]cbagZnh_`dafiim^mjaW]]a^Sab_p\]adca[i`fh[]hbkY`[^ho`gdhehe`pg]j\gkqf]jpggca_ec_rhfeaohjfemfb\ib^a]g^ccmfc]^aei`k\d\hjcYchbYfbaef]bibd_b`_`Xga_ihcjWrc`]cdhk`b`\afvg_baqmhcdfi^j\_gffaW[^`eVUaZm`Vncabdch_^jc`lYmWa^^af^idVbjhjZ]fbkeghYjW]f\f_mb``X_Z_gjjiejfr^gY\Z[YVnb^d`kh`__bebbbd_bcaebchdbfcbc_ehbdnefdh`_ebaaa`egd`jck`bege]faf_ccag`_ee`cbebec_ae^_hgabch]`^cbbaacecedggeacdedabbg`eaeeef`bd`bdefdhhb^a`\adkccfi`ddfbc`d^d\gd^^bh`_b^bhadfbafcdbdcdcfda`cdaaecdhba_edfd_b`bf`e_`b_ah`c^gfghafgcdf_baf`cfcgaccibgfhiabfdaefbadecbdcea^jbe`efdibececc^ebhcbjebbdad_df`becdebcad`dfdagebbhbbea_eccaaabg_baef]ca_a_bhd_^bcfdced^iecbeabdbb`dfcfehgbbabafbbeifddkkbhf`dedf`\`gagfhedga_af`\^afdda_b__``[d^cebceaf`badggde`geadgcdeeeicccecbad]`gfggbdebebbbcbed]cdebaddbafba]gc`fb_ge\j_`aaagedafaiccg_bb^e_eccccccdcccccbcccccccbdccccccccccbcbccdccccbcbccccbcccccccccccccdcdcccccbccccdcccccccccccccccccccccccccccccccccccdccbcccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccdccccccccccccccccccccccdcbcccccccccccccccccccddcccccccccdccccccdcbccccfjmfge][jjabVZeej]e\fl`Zaq^\ilio\eY^fe\akM``crdgchccehglkiqffn`pha`ddaUljaaj[dcifXxeg_e`ojfhea`c`bik]bZi`fcdcgeQ`[blnW_b[hoi_]efgb]_ccnk^am\Zfkend`ghnemVlgec]ja^__bUUfZ`eic^d[aei]ga`c[cdgjTdk`aYdr`eWilP[cba``fbkb]_[Zja`dcdY]`bebdfi\`V__ga_^hgll[igabij\^_habedccdcecccacdeeecddbdadebdeecdedccecdebbbdcfbecfdebeecdceecbbcdgcebdcdebcacceeccecbecdeacddacddaccdebccdfccbdcebdcedeadcfbbdcdeccaeccbcdeabcbcddbcddcbdccddbcacbbceaccdcdegdddcdefdbbfdcbdadbecacbdcdccbbccbcedeebdeddddcccdcdcfcaacbcccdaccbceebcecdcccebfdcdak_dWnmV_Zddgf]e`Z^Vke^jh]d`jhadhhj^brgV[_aV_`_dh`]Zkm`ilh`cgh^Vpa\[sqXje]gkfZeXZd`d_\ibbSajieWei`ghaZZ]hYb\ydKkheR[]i_bkc__ge`\kafZdU^eaNfo`Xbifesj^bjgk_]mbkhhYh`mb\de_ds^]g]db]KW[j`ldji^]]\idgWjc]TqehvgegodT``Rh_iqfeomeYm[dbb^l_m]UiZebrgaliqcVi~aeaUc_`Y`mddcdecccecdffcbccbcbabbddddcdcdfecddedceccecfadedcfadbbccbedfeadbadacedccbfcecccddedcccccbbebacddceccaccbdadedbfcdbdceaebcedbddccbafcddebddacabcbfdcdddcgb`dbbbecedbddceccaceabcfcaadbddeeccecbbccaebedfcbcbdcccdc`cccedbcbbbegddaeceebebdcbddedfcbdadeebccbbccal[e\[`r]coakbb`hiP`baf_h]^jqdobg]ecijWdw_lhcdf]q[^Yb]^`agi^c__je[mgmc]c\c`^Ydf[ecb^agh_[^c\lc_]an_qfLgg]enli\]e^cXbOcY[b]ihegf]`gfhVZ]cT_[kWbmleZdZoUcdfffjf^[i^i]affcehg`fcn_eegZ^ev{\Uio^j^_gcqe\fXbra[o`ahebgicbfrVeUai`_Yjafaf_jbi`ogggWWLdj`moaga[jdanbcb[kdedcdccbaccdecacccdbcdddccbcdecdcbabdcdddcddcdcfceccddcbcdbedcbbccbcdccdcdddaecdcccccecdbcccbccddbdddcdccccbbddcbecccccdecdbccddbbcdacedeccdccddbddddaedcbcbdcbdbdcdecddbecbcdcbbbdbdcbacccdbecdcdddddedccdcccbcebccdedcbbcbdbdcdadbeccdddgddcdccccccdbbcdbeccdcfgfd`in\heZfqb`i_U^gU]eie\oebbpcdh_djbYuofsdfi`fUalVWjkgfleblaekb_dd`e[kc_fd^`e[\]]hie[dk_gp^cfhgi^h^_fc\amhl__^_hflm\ZcYhaeafiiRdic`ucd]ie`\nY]cOiq_ec[mdsdkZ\`dU^cgl_^gatddXg_e^cahp\df^Wj_aQ^YeRkaajgdWhYpaee^dY_Z^dcj]`^bZ_lbm[Zbie\gka][ak`[uf_pdc^iqnc_shkfciejeb_iZ^_Yqeibjhc^dea][Qedfa[`ceic`q_f`]c]^_mbi^kedfY`_\wfc[[fZ\ag\gWjfeebkSagjlkde_Zdhcdi_]egje]deg^^_f\Ni_be]iRb\fdajje`]cdaXgcd]\ibW_eWXb_o_lcecgsmfg_^alZbpcblde\c]fYe`vj^jmbScfgoaeackk^i^fe^_ngh`_akl\d`_[[igdcx]bVsacbfi]^\ml]Vf^iadjckob_bfchhih^^ga`cdfbddbfcebdccdfcdabeedccbdcebccbbebbdbddbbcccebcdcc`daabbdbaeccdcedccaececedcbbdccbccfddebdddfbcddbabcddbcdbcdcccabedddcabcdcccdddecfbddbcececbdbcddddbecccebccccbcaccebaaebbccdceddbbcedabccdcdbcccchcacdbdcbdb`ccadf_acdbf``decddbccbcedcdddcebddbedbccdedcacbcbcddcdbccccbddcbcdddcccdbccdbbdcdccdcdccdbddddbcdcccccccccdccbacccccdbcddccccbdccdcccccddcbceddccdcddccdccccccccccdddccdcccdccdccdcccdccdccbcecdcbccbccccdacddccccddccccdcdceccdcbcccdccccdddbcdbcdcdebccccccccbcebcccdcdbccdcbcddbccccdbcccdccddcccdcdcdccbcwjio^b\ana`Saf^iVgc]`jceccd_fcbdo`W_[TlYl_kh\Xj`j\j_a[gceegeil_]_X\`kdgca_fcda_^Yhejkejb_cYggfce_`^afg`_fd\aasbfel`f]c_ld`fU\[iXeUagceelaffaadhbeacpc\\\Zc_^UjfifX_ebeafggfq^l]knfl`bc[iagcbfgb_khldjmeb`YZWb\b`olZXbk\Wgc`kg]a]iYd`heh^^dlfcdfg^m\l_bW[ceicd^Z]_edbbggaegdb`eabbec_edbfddcace_d`fbbdbeccfgebdccbffbe``djde_e_cd`abccfeadefdeccdbe``bff`bdfedbifdacbcibbgcdbecdaaf`ddc\bab`bc^aebhabadacadde`eba``ddcac`_efahfadaacceggaeeagdja^bfb^afdea_dfhfdbaghcgedf``cfa`ab`a_`eadef`e^difbbbcebbb`ed_be`defdedcfffeeddc`efcbddccdcdcccbcdcdbcddccbdcdccccbcdbddbbcbecccdccdccdccccbacbcbdcadedccccbcdcecbcdcdddccbacbcdccccdbbcbddbcdccccbecbccbdcccccbcdcdddccaccdcbdccebccbbcbccbccbccccccdcdcdbdbbccdccdcccccdcdbcdecbccccacdcccdccccdcccdcdcddcddcbccbdcdddbbdbcebbbcdcceddcccbdccdccdd`gdia`je_bth]VgfakYbc[iWagu`_oXc^lhf_hfch[_dgjefbZ_^mlooac]ffblcal^Xechdgbdb`cbh]_fgk^`^`[bdmf\_]che`oYRjVv\^^\Y_cYU`^dhcikg^jed_lfe^fjfebdjbaX__bbhVicyc^a`[``gjYeg][dilc^ggpafkfhbn`]`gpXd`daqfXYad\d[hg`aejaj`gdj^`Zf`_eZ_di`jhb]fduecf]dbcadgTd]Zjdcgga]d]_dbfbcfcaacda`ccbcbegabbdabbddedaccacdbecbecbgbcdabfcdbabafcbbbca`bbcdbc^dbccaebbccbdcdcefeefaaedd_decccecbdeadcedebdec`dfabdcec`dbdebdcdccdddc`c`db`cbbddbabdccbfdbdddceafbddebaccdba`ceeddcedbecbadabd_bccfccceddeddcdadaa`efccccdgbcbbbb`cbcdbabbcacacbdcc`ceecccabcbbabccdcccbcdbbbbcbccdcccacbcbcbdcbbebdcbcacdbcccccbdcbaabbbbcdabdccdcbccdbcabccddcbbbbbaddbcbccc`ccbccbccbdcccbcbbbbccdaabacdccccccbbdbabccc`b`ccecbbcccacbccbcaccdceecdcbbcbbbcdbcbcb`bcabcdcdaddadbccdcaccbbbdbcdbbbdbcbcdcbcbc`bbcccbbcbaebccbcbdbcbabC``ugb]Toc`hNmhSz`bNWcfZir]b^nfXWdgcbhjec]adjdOihqp]TWjf_[mDc`qnakla[eLhfUVgfogah]`cblbFhe]\k^fdodQeoc`cfhZbijdje[vfjjleb\biW[jl^aba\memce[akdjeejVdclcajh`bflUecca_\_chekccifebkn]Zfl`jhY`^jfirjd`gi_a]rYcbaif]dk^bbe`o`cleUYkda\oZhhWU`cdced`a[dmc^\_f`ecZemfc^Z`ejf[M\[fa[QWVham_[ckUl\n^fYd_g`ad\iX]keh^[kgjYcb]hZWQddkc[ic`^h[]i^]`]i[jilfccWahiZgcif^bsXej\dajX]rqhbj]ddagllcjfa^^u\]ae]b_heqtceafe_ahSbofc^gZ[jeWl^pi]l^ohgch^qld][pTZphZeU`hYjdie_v[g_l\hap_\HcibSe^^qik]eZeZXrb`_]hfejjniW_n\dZfmmfjjbidx^bfbjp`h]dVW`edU[`m_\u[XaVqkcY]_agd^mlqpcQ^_on`mmdVdjZ^ka`mg\ecZ`Vgk`^lLdibehdpcdMfd^\m^[`]``ag`]]qhUZPdX^SekZZ^d^`jfe]`gZ[g_\ckg`nch[\]qelamjcYTdoigi[f^kgmdfdp]diiqk_chX_kgfcnmVcWv[uY^^_`bcT\c\idfd\g^`jkjcYae`b_i\j_iaZalg`ae^Wcd]bbd_clkdkeik^^^^qeif_eighcif\gXeodah_aeT]go\dfijbe^jXlac_cseddjhk`ceg[b`da_hjc_^gjj^geae_e^bbigiTd_onugf_iaicce`hf\bfbj_gYjlgfcT`f`]n^[hed_ddfgaf]^ijfbWXc``c\eZbSnhhi_\Ze^adfdcdh^i^`eaWadnmicb^kbg`^vdighXjbmklccbcbci]h]cebg`elhrh[aib_`k`X_fge\chikcm_a`dmbf_c\gYdb[`]dakfiXh^g_hbi`Webddgbf_^b\hkcfg^ekchb`ahgg]hgYmg_bcc`gg]f[^gffhf`nhhkjflajchebkjhefb^e]d]gmid_Z]eca^jXaenfdagdidiba]if`_kd__[_ae_ae^i]gnj]m_``][_bRgfa`m^d]iiX^d\a`jdbk]eYau_efckcgad^fdcb_ecehgaccebgVdO`hbdcbfoh_ckh^cjdqc`cZ_fbeai`geb_b`Zb\de`hYWjdfh`Y_d`jadce`]^nc_[noe^epe]kf\ajba^[`Zm[_ebf^c`dd_^ga`ebckeihabcjkada]`b_`jccm_geehng_aidieaeggn[k^[hfe_ac`jhcYt`cagbff_g_\dbbgdTkjii^Ybcb^_fgkZcfe^_c`Zh`eMiefYj_Xaejbj^f_\bciae^^c`dbad_c_ZZb^`la^XafcaZhgbajbej_\bia_caid_b_]ajaeWeekdSYhbdct]n^kl^bha`^gmfdan_\bd\e_ed[c_k`Wfb_fdbafeeb^\dWcbecfi`feeek``fdfcce]ggjZcbfhi^cdcdafopdef^Year`dYcqh`hhpaa]d`\ci[g^^Z^Padgd^bU`ghfbb[`[fbcb`dk`cco[fb`_`]eYka_d^gddUgaf_kpbhheoafgba`_afb\gaidegc\pfj^Wg_bdbjXa]V`edYX^ctbiacYehb\nigeg^c`bbg[jb_ehecf__]`ddf]cikddiX_foladla]eg_d^a\^_dgdahbjanjeak`d^hgd\__cjfbeacaaahaheb`e_]k`cck_`cgj_aaeccaeddbaeec`cbcbbebbdgfbaddgbeabgbabcbddfecedfddfa`aceddgcddcceaaddcccaddgdbecd`dfd`decfdbbfe`bded`afbbccbdcgdde`ffdeb`bdcdadceeddbfcaddda``dgcbcabcdbgaecaddceaacacbd`cejeegcbbddcfbcfcd`c_bbdgccccadbfdcccdcfbdafdediadbdbledcedeeccedeceeef^fcacdebagcccebccccccccccccccbcccdccccccccbcccccccccccccccccccccccddccccccccccccbcdccccccbcbcbcccccbccccccccccccccddccccccccbcdccccddbccdccccccccddcccccccbcccdcccccccdbccccccccccdccddccdccccccccccccdccccccccccdccccbcdcccccccdcbccccccccccccccccccccddcccccdccbccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccbccccbcdcccccdccbcccbccbcccccccccccccccccdcccccbccccccccdccbccccccccccccccccccccdcdcccccccccccccccccccccccccccbcccccccccccccccccdcccccccccccdccccccccccccccccccccccdcccccccccccbccdcdccccccccccbccccccccccdccccccccccccccdcdccccccdecfbdbcdcabedeaadcbabdccccdbbedcdacccdcdcdeccdbcbcedccecbccddfb`dcebddbdecbceacdbddbcdbaddbecdbcccdffd`dceaceabdcbedccdddaddceaebbbdcccaeccedddec`bbddfbdcebbcbcdccddadedefccccbbbddbdcccecccfdeddecdccbcccccabbdecbccdeddccdfcadccaccdacdceddcccccabbbccfedcddc_dbec`dgfa_jchlhe_dfcdbbcdbahdf`ie]hcldgafcdgT`cgibc]hbmc`ef]cg`agafdg^fjk]anghk^aad`j]b[`_e`^j^c`h]bb`bldf\c_hdagc|d`a^^delcdlibce`cafnkig^ej^`]_b^`kXdkhbb^b`cefcehjafmeai`abcYg`dcehad[]Xifa]cch[eaf_cYd`dlj\bh[bm`b]a^`]c_lifkbebc^Z``ch_bgchhbbfee_heefbmkbcch`]fSZfd[_eUefZcbefn?\bt^dWbck`bX]dagr[`e[dg^jbbhn`cdb`g`bgch`gl`nj[ee_Vb_Ul`^^^YddhZdgfe_heid_]kh\hem`ffhaiiYfj[`bbim^`gc]^[cfjcked`i`]hdZjW_[calekcaa`a]j]lgjcpaqaitbe[f_hilic[fh_a]ogoah^daY]oeqd]ahkbabm[d\qhc]]kb^akf__\c]eb`dlchVg]cb_\fagb`defe]`ebkbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccagcahegc[g_^cd`dX[^a[cgdeeQag^`hgehggc`efa]e`]fdcdaac^`fac`baffe]a`_accbcbc]bhb\bga`fejiac`bbf]i]_jgcbedfijfgbdacbcjcc``^b_dihQhgdbf^ge^abbcfjgeZbacbh_db`e_ba_adhgef\^cbdebcab`g`idhce^ahhbh]ad`bbdc]he`cjgdfn`hcdjigb^dcfhhjma``a_d]`fda`i^acffh^fh_eg\aae^ghibcaccfdabdccc`cbddbdcaddcbbbdaabcbccdbbefddceccbcdceccbdbcccbfeccdccbcddcbcdcbbdadcdeaececcbbc`bbddbbaddddfcdbcaebbccdfbedcdddacceedadaaddcddedeccb`dbad`becccebcdbbadbcccdfddccaccbbbbbcccbcbceabdbcaaecbdccbcdafaedaddccedbdccdccdccccdcececbbdbbbda`debccdddedbcbcbcbdcdcdbcdeecbdbdcc`bbccbaccbddcdccdccbddbeccdccdbbddfacbacdcccccbbdbcccbdcbcbcbddac`ebcabcdccdbccdccaaccddcccccdcdccbcbdbabbcdccbcccdbccedbbcdbceabdcccbcbdbcdccdcccbbdbddbcebdbcdccccccbdcddddbcbdebcceccbbcccdbcfdbabcdcebcdcbcbcccdaddbcdccdadaddddbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcbabcdccccbdccacbc`dcecacacbadbabdbccbadbbabbcbbbcedceeaccdddadbdcdcbbbbddbaceecdcdddcdbb`dcebddbdbbabcbdbbccbcbadbceccdccbebbdfdbbbcbcaccdbdcecdbbgbcgdbecbbcabdadabccbfdbcdaccdcbcadcbddabcecccbcecbccdabdddbdaacaccbbabdbcccccccbfcdbbbecebcdadccaadcecccaddcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdadbddbdcccecdccdcbadaebccccdcccdcbbbccceccccccbcccecbbebdcedbdcacccdcddbcbacbccccbbddcccddcbccbbdcbccdbcdefbdbcdbdcbddbcccdcdcdddceecccddcdcccbaccdcdcfbcbdcccddcccccecdbdccbbebbacbdcccccdcdcccdccccbcbdcdcbcccabecbeccebbccbcbccabcbcbbabbcdcdbcddebcdbdcbbcbad]eacc[cafcccacedeccbf`fcdebdbcabdaceddcb`f\gd^`h`^ceac`bhcaccc^cacc_bb`gebegc\ebegabfec`ade`ciba_dcc^bcaadddh_bfaeeaaefZcah__^adaedcehbd^c_`c`cdaceaedgcce\a_ae`bccd``lbaidccegag_a_debddbbedbcb_b_eabaiedcdcaabfg`caca_bdeedeefc_gdc^bccfdcbecaecaeafccceacbfkfekde]hcldfi_^YcchcYde`igda^ikg]]d`ebhd`e_ffdfa`Ya`f]ld`cg^]ebi`gZ`lc[heehaFfkb_a]gdad]`]hjbc_bdg\fckjhj[^eiefdefagdcjh`befgheYe]afb\jd_hcib^bl]_cdX[dbjeh_fcn`m[e^_abjgaa^dcgb`jc^]c`f^Z`cbXemgeb`cgjcba`a]ba^b`faddhcc`_d_dlib]gakc[hhae_ccdad`d^fkc`edhbjg^ccccdcccbcccccccccbccccbccccccccccccccccccccbccccccccccccccdcccccbcccccccccbcccbcccccccccccccccccccccccccccccccdccccdbccccccccccccccccccccccccccdcccbcccbccccccccdcccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccbccccccccccccccccccbccccccccccccccccccccbcccccccccccccccccccccccccccccccbcccbccccbcbcccccccccccccbccccccccccccccccbccdcccccccccbccccbccccbcccccccccccccccccccccccccccccccccccbccccccccdccccbccccccccccccccbcccccccccccccccccccccbccccccccccccccccccccbcccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccbccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccdcccccdcccccccccdcbcdccbccdccccbbcbcccbccccccddcccccccccccdccdbbdbcdccccccccccccccccccbcccccccbccccccccccccdcccccdccccccdccdccccdbccccdcccbbccbcccccccccbcccccccccccdcdcccccccccccccccccccccccbcccccccccdcccccccdccbcccbccccccbccccccdcdccccccccccccccbccdcccccdcccccccbccdbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc`dcb_dgYdbi_c`engbYWZ\``mZ^`bge\ghdk^dlh]e]QUidcd_ekj^a_e_a[bkbped``\eoecfkf`c[Yifd\icnk]`bnegjc[_aaaScb_gahgba\g\c`bocl`efcg[c_]dbjecei\jfh[ecle`bbd]hj`ag_gii^[bjcfbca^blcfh\X`ahefcekZ_e^j_kN[d[aY]eagdYj]p_feaae`\cbYe_n_be^e`[bj]ddd^ZX]jihf\ahcdfmdfc]dp^eccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccbccccccbcccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaabfacdc`ddbc`accebadbdddaccbadddaccae``bccdadbccbe_bbde_aedcdfddfccbbdd`cccfdcaccadadecebbaabbabebdd`cdec^dagccaccdccccacabdccb`cc`cbbbecadfeccdcbc``dc_cfbddcgccbdcca_cdddccccfacdbfbad`b`bbcceabbcbadebdaedfde`cddbfdcabacbcc`ebacaaaebdeeacc_cdcfdacdbcbebdecccccccccccccccccccccccccbcccccccccccccccccbbbccccccccccccccccccdccccccccccbccccccccccccccccccccbccccbccccccccccccccccdcccccccccccccccccccbccccccccbccccccccbcccccccbccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccbcccccccccccccccccccccccccbccccccccccccbcccccbccccccbcccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccbccccbcccccccccccccccccccccccccbccccccccccccbccccccccccccccccccccccccccccccccccccccccccbccccccbccccccccccbcccccdcccccccccccidg]iEdh`Srcei_]m`hda\kecfeflc`abec]Yicmdigcfd\a\`d_`hgfd^caec]kaZd\bifbeegeb\c]lj`db`il]ebkjZbgha\ba[eb^eN[ei\c]f]ajgYebdaaf`k`V_li`Y`mn^j^^odnjdnachema[f`loh\bZcdigkadok_cfYc\__b]d_bi_e_deb^_k_ac[kek`^`\d`figabfaia^ac^Y^b\i]aace`[]dif_d`nW\gafhf^hde\faab_mjkWd\koklck[dmVefkf[`rrd^cpac^UqWcW]e\ggi_jl\aflYdmchcebndcaefcadbcm]haehYZl`Y`lhe_Zi`dcab[ni_gio\a_ihcgibcgdaa[_`]fccj]\cl[mjjd]`afhj]\hbgi_al_bbiaidf\fah\fk9iiUg[][f\f`bc`_ghdef\\b`hdgliejc^^]^cX^YcIieejhfdac`cbg`cidbCdgadckej^WjbeYddagdjdbc_li`cj\ihf[cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclQ\e_fcch`bdf_\hXh]e`mc`dgdadeb]j^^khc`gdjfbedkfaeicg]cfdcbjbdeahiahgckf`gd_bgahb^gael[_iZd_dM`]_eficci^egicd_`d]g`hcjbcfgd_ak_ca^b`eek^bf^``eg^Pdja]c\Aa_a`_dggecgd]backea_bah^bhld`dccahhg^fff`dfd^^befld\`ccUbfU\_m_`i_f_knchh[_cgccec^^f]`dr`^gcgd_]]agddgehccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbghd_ag\\dciogclWfe^bed^il`fk_]_alY`f`gchOdRdgVf\Vebhd^f_ecZY_f[`dV]ikUhWbacbp_dfdVUglfadccgcoh\l`rdmbnifkifcf`afagcccndhfai^ba`g^ihj^^j_\cmicj^fdcod[``aeai`gjdU_dq[bXYldfZ^`dc\bglecfl^d]feb`_hkebZhqbdpcf_bbdkbefma`hc^ifbkfdd_d[ame]fbTaYjfQocbgbjbbk_Ylgb]bbghgahYgae`eaeebd_XZgb^\ncagNa^_c_hftbjps[cbckhjda^Vc^gchhde`n\^_\`ogccaghYc_[hmhafflkahacYffcOdgaedmhcbdek[hedd^ffck_bfcX`cmje[bcad[_g[n_eedchhmheehce_dhbdabc`p`]h`h`b\^ha_dge^m]dgXcgabccRgUbcdkiicd\sekZ`cd]ageehgd`fhc_qqgdf^a^adc_flgbec`Z_fa_codeb_if[__eRbZe^bgg_`Zdkie^e^bc\]bWjah_hfa[_bdgbg\g[\dXbeede_fc^^ehbahfafhad[`ifj`fXgcdh]im\j\ceedg`ee`ek_g`f``jbnhdhZbh^biddidd]k]__ZiZh`edd_cc_VdiaX\rh`cagejm_iga_fibjfecgccbc\eYWc\bfkkegfjZf`djbdggkoj^fb^d`a]cfn`hcadbfpbgc`aheh^kakfc[aZkcjjd`]hgicgdccbWbgjeae`S_d[cccccccccccccccbcccbcccccccccccbccccccccccccbcccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccdcccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccdcccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccd^Xhdq`eaV_dk^[`agi\mlcbbchbhY`_gdebaib`ad``]]esf[bjhl_ag\fgbh^^idb]ib^iafhmffhfkhejccbmjbiao[_Wgidc]]baa\eaj`abcfgS\Ye``ba\]e_U[ajf`deebg\a`_]^cc_hdZ[dga`idbhUf_]`dhfneeZSc[joY]fcbd^g^g`_cfffg_c_hdlZi`kkce`c_haag`cf^\eaebd^^\`^dbiWck[ahwb_`fZh\\Y]e^bkbn`Xfbbn[_ctglPahfdaafecb^ejlfb]efib``od`fVcenlbmeafdidig^ccdZkh`_h^c^abcL]nfZ`i\_[`[`jhjgPhlnfb^ja_aeodg]`f^mdfdVRhkfagaZboPig`X`]macbfcnaTc_jd`h`[]aadW`lWa`^b^fpli`e_g]Vc\egb`d`f]XXeef_focecklf`_bc^`j[aa^nk]naacbcgij`ahclad[ld\Z``fUdebcbfmZfumiaedgaj\eabf\faZdXkeiieb]p`iWeemlX>X^dZjaSa]^]_oT^cje\^cmedXd^kakb`dmej^acibd\kd\lg`adfxd_W[fdil]`[cfwfch\o\k`mSbc_]`ZxXkd`ndd_gXhhdillZi`biUcZ_jfmbeab^cmdk_mmqgchq`gfceg]bjhW`meii[k`lge`dg^dfd\aagabh_c^m\le\`ih[bb^_lcgmd_d_ahf_Yj^Ufg]`c_jbeiUe`^ep^belfgcXe]`beeigg[kh\fmkdm_Ocejmc`^jc_\[fk[nd`hl^\^dcQaZlgcgbgib[^gcfkicfXei`bb`^beZZbca\gbeThhnc_c^]fPjh_gdic_gbgemilbVegmcgheeldb]^^eXe``a\cYfkk[]o\bbd`P]eebbb_a`fc^[idceg[Tdabd_afrk[hiicdld_gbac]a]`i^o[ffc]`aiiZg_g`d^e\clt`[cj[][c_]hggdedejg]bdS^\_edba_bdfhacnW]n\fk`fWjaddkocadcfi_dc_d`h`dgfcadb]eabacabbacbh`aeeadbbb`ddgfg`f^bbdbacdaefddebdd`eaa_ee]eabbadbdf`cbfefabee^ccggdda^e^ddbb`gaagcbfbhcbbbcdfaa`b^becda`eagab`eh``gbdeegcdebbcbadaabbcdc]d_bcbgddachecbab``_dbgdeadeaaa`dcdaecdb`bfc`dfedacecbadac``dcfc`bcdbdaadgcibgebdec`abdccccccccccccdccccdccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccdccbcccccccbccccccccccccccccccccccccccccccccccccccccccccdcdccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccbccccdcccccccdcccbccccccccadcbcbbcbbccaccbcbbcbbdcbbcbbaccbcbcbcabcbbbbccbcabbccabcccbcbbbcbbbccccccbba`bbccbabcccccdbccbbccbcdbbcccdabbbacacbcbdbcccbcccabcbbdbcccbbdcabccccbcbbcfbbdbbcbbcbcccbbbbcdccbcbbbcbcbbcbbcbcbbcbbbccbccbbccabbbcbcccbcacccbcbccccccbdabccbdbbbbccadaccbcccbbcdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccgcYeZdff[iV`uhWg^cbgn\^dmc_bii]gjTfacmadWjjmaa`eg^gdk_`gae\c\hfc^`ffSRgcUfa\`mb_dja\fjabjYf]^dg^WWcgbme_lgohhYeoekfenhdZffXmdga_efa_b\ajafa[edZfagakecc\Za^aYhenccohk^`kdY_cc]af^i_bbg^^bk_e^_^VZekfa`g]aceZihcip_^c]j_Sb`n\]ggZdgbcoke\[g[nffagse```_]^mcdn]h\gfhfecx`eohg[debd\h`labeed^[be^^mf_cficbdichmdbamee]`mf_^fg`g^_idiZdb`fcimb^ead\ee]nibVqcgfb`ac]eclaXgabefbeec_dbcele^_c]ib`fgcbga\g\]imadce^\_m`hkgad]Y\jh[ccZib_gbkke`mia`^dc_bh_bff\[f_hcjfdajc_gb`ZjaTcageZj`bgUc]id_fka`d`gifjkbdkdfg\h\f_aaatZdha_c^[a`mjigccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdaj\leLkggj[ag^mgdjhfdhWqdciXiac_i\im\pdio`bqhacbZ^^e`d`^dm^cc_]b[ajlb]cfc_kaa^ad`^ibflhfkgflkqdiicf_^aY[nab\bhaHic_m_agjUh[d_p\ccaj[cjaU^ec\na`pbfggnglcamicdlTe_c^el_ddWkbjdX`ck`ecm`gblf`b_Y]aj\iWhiYafZ^eb`h^ih[_Zb_g_c`giGc]daj]caUac`\fb_Xaifdghch^fa\`b[[ccccccccccccccccccbbcccccccccccbcccccccbbccccbccccbccbbccbccccbcccccccccccccccccccbcccccbbbccccccccccccccccccccdccccccdcccbcccccbcccccccccbcbcccccccccccccccccccccccbccccccccccccccccccccccbccccccccbcccccccccbcccccccccccbcccbcccccccccccbbccccbccccccccccccccccccccccccccccccccccccccccbbccccccccccccccccccccccccccbcccccccccccccbbccccccccccccccccccccccccbcccccccccccccccccdccccccccccccccbbcccccccccccccccccccbccccccdccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccbccccccccccccbccccccccccccccccccccccccccccfmg]`jXghcX]cmhn^k_ei`_]h^f`Y`gaZ]_aqYl\]fbm`cbW\X]eagZ^l]b]_^ogaaicVk]h_g`fXbgndnVd_chch^n`ami\dl[Yoin^ge`i^ccdnab_hbfhcbli[p^ZfZ^^\je]^hYcf_d`dijd\ccZ[Z^j_hcji]Wdddbba]_]`acias]^ecsg[\\^hbgjabbmfifefggUa^cd`^ejkZ`ci_n]ae__egdreYeghafn^dfZcmp`ed[aab^dpfbgcbcbccccccccccdccdbcccccccccccccccccdcccccccccccccbccdcccccccccccccdcccccccccdccccccccccccccccdcccccccccccccccccccbdccddcccccccccccccccccccccccccccccccccccccccccccccccccddcccccccccdccccccccccccccccccccccccccdcccccccccccccdccccccccbcdccccccdccdccccccccccccdcccccccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccccccccccccdccccccccccccccccccccccccccccccccccccccccccccccccccccbcccccccccccccccccccccccccccbcccccccccccccccccccccccccccbcccccccccccdccccccccccccccccccccccdacama^f]l[[bjcd^hie\W^b`ia``eim_kYZdedWjae`ngabbfb^iic`b_Vg[bhaj^aZWbjcd^aagen```k_gheZc`iifdl\\ccc_k[Vic`\nbX]hZe_bhp\`big`nk]jb_`lkadab\ak``c`cg[bg`Sgjbcggc^eea_fjmaeie`hlbemagbdfgdh^cc`ihgebid]hlfbYg_eih^[ia]^ljkfcb[afg`ebj^f^^g]`YbgpecUZbrg`eda_kbl_c^`hjaibdmbbfnYaejbfdk^fqf^\YccccijVk]elj`ekdd_djZ`cd_nmgdZbYghlbd`f]kfcpf]g]\]_djYa`]im\Zhdc`ebpdxbcfe_cdi_bm_f^kah_gdg``Y`U^i^dgdcV\gXibnk\\_fa`cghck\]dbe`]_c^icfe[^cW`ZXTap^cbgo^_Zfagcac^\eZcecdX_]^d^hfm[bajU`^s^jYd^hTabdfoge^`hf^eeb\jlfjed`b`pf`^`]i]_d]\fa]^cdm_[acfd\hcla\ZgXle]^\aYbffcbV\`ZpXjcfdcg\dcY\`_gdccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdpVmhfbabnfibljhd\c`[e\bbebc[fdcmab[e]^_c_a`ffbi`iZdgk`b_l^`bkc`bdcae_dehm^b]d]fibkaT`cbjfjbiebmYdpg_hbjXdm^fgb]dag[mbedVewge_Zdgeabhd]_Segi`c[YjZcacb^js_g`e\c^_dfacjja_ZgeL_cc`ccbebchSc^heb`]de^bd]a`Ndag]_]f]iai^`geheabf`j`dT_`mmgfkbe_]fe`bhkgr_ecfb]iYedjcccccccccccccccccccbccccccccccccccccccccccccccccccccbccccccccccccdcccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccbcccccccccccccccccccccccccccccccccccccccccccbccccccccccccd_dabgljgcd_^eVhf`g`a[X]h[bVjk`bja]g]hccp[]\b^dYbsi]j_abcdaebeiZX_i]qihede^_fan`ibtae`cidk^b\ZgdgZ[`kZ_hc_\^nm`[jjaudbabZ`d^ZVddf]ai``iedbZf_f]e`naei[cePc^]`_k_adk`bf_qbbjfgg`e_cffabcibdea\e^ccj_fcb\^]^dk`cYhdd]Ycid\ce\jtmZ^b`[bdc`Z`Z_Xceihebaj\o`icjd_Ue\ZZY`]ig]abOc]gcgj^e]m`]e[f_eheae`fih_l^fehb`^atgc_^ZWbh^bed\Yei\dhbq]dmjim__fbYefmhfcbcabW^`b\d`cakecYVshcacjgb\hdeack]djkam_egbbQ`ck`]```[lheg`jhcnhd_bbfZjbafc_aqajgZb[kne_]Xacb`cc`dk^dRackb`d_ecgebegj`a`]fbhcefafhef`_mejncqfj`bh`adoeaWbffhaffbkfgeR\]b`adeccdcccbcccbcccdccccccbcccdcbcccbccdccccccccdccdcdccccbccccccbebcdbcccdcbcccccdbbcccccccbbccbcccccccdecceccbbcbcbcccccddccbbcccbbcccddbccdccbcbbcdccbbccccbdccccccccccdcddbcccdcdccccdcddbcdccccccccccbdccccccdcdcdcbcbdcdcbdcdcbccccbbcbcdbbbdcdccddcbcbcdbbcccc_eb]Vyifb^^jaegamdeflcdbhXah]okY\iafhbZ`f_ld`fe`m_aflegen`[he[WZc[]_^deoZbacjYY]fllncfal[]cg\aiYd]if^bialamdfcde_db]kf^jefV]ki^hacTTg\jdfk`c``aal[feaigdibffjZMngi^cdi`X_gZegZtj`p[fdbdb[b]aijhc^_fjgg`eo_`^`me[l_`hdejh_k^_a_bkfegriVhcodafih^hoccWl^eaa]ejf][f㨓lvPœ{{Rcbwy@wQ`tnpqm+y_NgvZ^ Q\>w{|ss]gٸY[tbsʕ[N{RhT%<}AJr}㰋xogp{"{nyZqpjpvy8ІzywsuA6*C191-1GCPF}I$,E(@?(,2@:,?9.5F7(JIZ%h)7ܭB?J(X2{.*64,$(,ATq4/=NS"\eEL5D'%4&@J?JJI *7 A:+P'+@@?R-I(,2GMX(;24] +u';B 8 A)Q+?a[6-&+"NdN%U5kX? 37!T1?$=9/:&M9=6C,D'3+:9W+0.T4J8m=QC&;-0Q>53: +4,AjCs1@>6C;Ck|p]Kj`fUM}@jjtL|upgJuv|Bj||_(RUKgzBt_v}lrlkoX6}w`z|V^IbHynTPWNusGk^{Mjd9vmiv~mCBzxypIwWe6ZmhtW^izvjWVEeDcoY:hwmo]ǭHY_~6vn_knsƼıÿʹƳøƼ¹¯Ÿ²dzЫʽŖʸͽɹŸիīʮѕųwÞ˼Рù²ʚ̨ʀȭçĴʲŷ¦кƻ¸ïɾȪưý̹˿ĿúƬñ¸ʺŶɽÇǾѺ͹µòʳøŨɳйȰǷųÙû¶yñŻƹì˻²ôȼį­ļƺտˮºƠ͵Ѥ³͹ħϲŮ»ƬŪŴǭǭȲƩŦ˼µϦĭŰåÖƴɰȨŸĺ~Ǵа­ʭ´ЪǿȪ¯̵͢ȻĦϮǻDzú̞Ź͹ѶԳđIJŨӪļɸĝǹƳȺªƻŴҸóúŽǽűʅùǫŦҩƳɩģñƺ˴˭Ժ͝Ȧï¥̷ĩ÷ľȺɩ½ƢĖǵůûȼĴûڨǼª°ίֺǷʪȾ°‹˽ªŢ¨ɨ¾çĴ˙ǺŠͦ˹úǯ˧ȽãļƾøΪŽ˼̴Ţģãǡù\ȧͱľäƻΡźƴüΧøŭîãçĭʰɺǵ²ʦĺʥʳ´ĬȭʗŵÝɼæȘŮʹsŤǨɴʨŶʳïò¢̻ÛͻΥèʥƼĵǺخƾƢøµʥïƾҰ˸ʶĹ˕ɴ}ĩŸ—ͳѳƼýɶƵŲʰåǩ˽ęϤ¨ȭų¼үʭҴį́ͨ׼żĶ¶ĩŝŷʱEϲ§ɲģ֯īƻïŭӨóĽůƺ˹ţ°ɶͫƺťȹġ˭Ť̴̯xʶçǮÿ¸Ұþĺ­½ɲˮiĪ´ƻ»æŶ¾Ļjʰʱ¯ǵĦӫƴķ±ʧǨƽϻŽűл˦ŸķǷī˪ȵüҴǶøЦϸ˲ǿƼ϶UÙģź¡DZлĮǖһթǯǩϟĨ¦ҴįǬƶ¬µųȾĿøůǩǷĵȫǣŹĿ˼ϧì¸ПĹóѬȑǺϻȯíñɳòͬȽӵ¾˨þ·ά̻ͭҪӤǬ±Ƽ̬̫÷ÿƙ̡̹ơȸƒžĮ͛Ү˶ǭ˦͸°̳Ѹǻշǿʷþ̹ƻòǴˤƻåïĬĴĴųȲбìõüȵʹŬĿ¢¯›ŵǎʲƼ}Ҵͷ¡«¬üƪü¨žɽŶüø¶ƧĻïʪ³vğҳȷ®Դ³ͷùƶѹԬǰƫȱŪɰʻԻ̏Ǹ§Йɶϱֲƽ̵̢ЦɥʹͰƬеȸǷвŦƩѬݳ¸ŰŘ˝ոлݺ¨ʭپʲ¨կ͵ȴճʭ®ȭİʹǸ׻ɶĢɵº˫̺ƫļƢżúǾ¨˻ƴù̲ɻ˺ůž¬³ʭ³˾ǻǶê®ͧªŸǟü̪·þťźIJȭȰ֩;ȿĹɯʳij½¥ʴر®ø¾¸ͰŴúŹұ1ξĠ̠ƼǮϮķǛǷƾ­ô¹ƳĺȳŶĴ´êƵûĶǭ­δʹ¼ƹ̤ФʭéĕæʱƤ;ʾijʮƻ׮˸˿ī¼ճƼɸƶüþýȿȮ˹űëģò¼²˹ųźå·İŸѦǾɲݲˡԸŽЧŠ̾ūʪԮġǨҨөŭŵƺ÷IJԤƮĮοȵӯпɸښ̿ͲԲƧΤʶڡάƻ٘ЭױͽĵؿñǷɬįƳУιľƺٷϴĶô¡ñƫǸŽ̝ƶȸȕǻȣï̼ͧƺý¨ĿŚëùͨϴʦǿǺ»ƽɝ¾ȿưϳʭïРôͮĩĴ¸ìƫͮŹj±£ǧ̬ƯΨըʩž´̞¸ɸɳ½Žȵ˷ƫǯíůɪø˾ʧ/̦ʶȯ³è±©٧ūǡñʫҾɻƾŵ¶δ¶²ݦ̬øŲŴϽմżþûųȿмάĬǥ̵ĤצŸơºιϷö°ŵû’¹Ǻó®Ⱦʯī²ijęȭŬʱķıąĿʼƩǦʮ̸8Ŷĺ½ŵ³ǯί¹ŴƳΡɳʺθ˷ķƲĩűǾžʵʮʳƬçǮħ½ûҿìƸϧǨ͸ñɘ­ĺïҲĤǵʿ¾ľƯpƱˣ̕ɸȰ»ŰǨ¹ŭƣ“ƹɻúʦ»ȻŸ·¼ȪȞ³é$þɰƺ¶ťȷ˸œǶϏºƮͯʠͰʰϿīѻººųʴɰ̦˺ܮûɷǺǬş¢Өʦ˼нƢ̮⾿˲ӖˬҰѸ‚±¿кί¶ǽȹǹſdz͹Ϳ¬ıȶ¶Ǫͥëʷ½õŵŨźȫ~ӊȳʭ̨ϧэìšƦƲıД¶Ͽǹё͸®îȫͶȱIJųķĸɺĭǺô²ɳþΦçͲдʝ%ͬdzЭϼμž˼˿ʫʽȫٲ4ʨͤϺȘѧµĝ¨ɟ˷˺ͺ˛½ːί̻ƫɻ˷Ÿ˿;ӽDzǺʸưƩϥºѷ٭̳ǿ̫ܲͱӌſϓͮŔΫҷͨƐǫϥȴͮȴӰԨdzɰΩ˪ͯ۹ø¢ʷʶƯȸɸ͵àɹźƗ»´ɨĹ¹ķ+şŸܯŞʰ϶̶›ʗïƹ̺ŭ«̻˫ͧαȷΝ͝¥ĸ·ŶĪɷöƭêĿèΤŷǻvǘýťֶȰǾðȸƷźͼ̵ѽũé̸Į˷Գ³̹ΧƹǷϴƯ͟ʺé̢Įƫķɰ¸­Ǽź´˹ʬ°̭ŲܺȧúƺĶŸȼ̾úªȻĵŞŸ̩Ÿͭ¬džûWñÞ°Ǯƿ³¼ȫîĵûüͲòȬ߯ýôͽǺаͼ³ȦúɿʳЯƧǶӜŶ̶ǝ÷ŮƿĽƝèˤƬ»ǽūÞʛªŠůƽϭóĒĿƻ¹ǷƿĕͰƴȰūĶǖɲ̮ҷƷĸɩȶõһķƭšƵ˴Ȍ÷éîѺµ´ř¸Ɵنƽ̼Úóҿǽþк¼é×ɰǼԯį÷ȭ͵Ʋиέÿ̱dz³˷DZ®˸ʹ°ò´žοḲΨѠȦɱҬə¹ĿĸҰ˲ţħ¹˸ԪŲʩ;Ɯ«ж΢èóѴľȶ̥ƽɲƽ¸ͻ÷٧þã̽ѼմͿǷߴϼ˷ßϯĥįȽŦǟűŬªͶֳͯæȥê̼˥͵¿ήƵ´ŮİéʱȺ˻ɵ̱Š˥÷յ˼ƢˀڹƸг˻ӳïv̱ŸĵŶ¾Ȥȷ´ɹƲзūžù̴ʺƮбƴɸżɷȮȾɴ˸ɦĿîǭܞ´ŵșǯǴùҽ´÷ŭ֪˨żçɦȟɽǪǹ©ϳʸ¨ƯźΘñ|ȨŹ׸ʽخ̬²½̳úåͬʺ˨¶ȤÿƴѺȯʸ¹¾ӯʱƩеכĸ̶γ˯ʸºĦԫի̷ʮэƹϯƢ͵ʵ³ɨƫ¶°ĬЦñʽı޶dzjùǛˮìϼׯͫũìëȨİǴɺȤĥĶͧŷƬƳµƷ˺ɠ»˪ųͽЩԪůۺm¾Ŭ͵¡ƈµ«¥ųÞȢǾƼĜóҲþȰżijĴDZ÷şŹĺηɬ߯ëǸ٤óȴ˰Ħʠɼìɣќ̧ȱƵƚǽ˱ʱóêwȖŽϽʼũþɣøȥ̸Bڞȹšñՙĭ˾ǠƫɬϧijͻƯųϳȮǵü¼ǽǶȷ̲ͺŧĵ̿Ĭӿʾ÷˷ɬĦ׳ɠàƤ%ŨͲֳ˿űȺơȴ̝ĴžӸĹįɴʸɴǴ&իǹ¯ƩЯľɾŹŘǫƧ֦Ⱦ˧¤Ğаºպúʰ²ìƿŵȼ©ŽµɲȩƵǾɣźͦƳơȸȾǽ½±α¸ªɽȾħǻººǤŷŲľʰůǠůԫȣŹ߳̽ɸ˻ͼǸ̦ԥż̯ǦϫȵؼŲԵҮԲ߿ʱʿǦʹʯ̤Ƣȹڼӯ¨ϰĵӬӭޯʬȹȸȲǾ±ѷͱЫӳDzǤӨǮ϶þũ·˚óǿŬ͸Ƨưöķź˷ŧùßͨǼѻǷƹµ´ķҝµνDZíıyȲùʚáμ±ƌó÷ÝɸƼεȨ¹êнջ̺ƪƺǴ̹ԵʰпȽʬ˫ǿηɳǧǷ̸ı¿ϰɥ͸Ǧ®Ö·˨ͻ±ʖŸɹŝճɩѹĤïǸϯԽטžȲͿ̴ưų̨ѹżܰͶ͐˭ŠĮϫӹñȡ̫ŝΰòƭϰɿſǺɯĬƿƼͿ¶ѫΡѯǦҵºʥĭٸȾ©ƴʹé˯ѹеи޴пϭҷðحԮĿǶŰ㵶ýǴйˮְɬǯܺϿ¯ìϡµȵ˲û̮՝Ĺ׸¯ʹ˩ԿܬƽĨĦǻ̸޶¹ƿñگ²ƯȺľͥ͹ȲǵŒưŹϹξذҺ»İşОǯͼŴѻȮĢƿʲַ̪Ƶη³ɥí̫ͳçɥþȭü´żǰɵ̡ºzθ³ɿĹڦë¨DzƵįݸȷDzʱθ٢֤ţȵ¯ѽij¡Ǿòªȭǰأ͹Щŵɹ˽ɺżϹͯǾȼǸɳʺįijŴ̰Ýε÷ʳ̸۳ư٭иɮȵïɹ±ðʯαǠҺ՛ĺǯüƿȾЯñòׯ˟¬µʷͷ̽Өǵ¸š»¨óʺůʯչ´Ƶʞ~̵ɾŻƸեʹ㹮ӽם϶ͲƺžΜäüƹɬıºȴЯȬĩԵƩ̱ǞŨʱĹ۷ʴaöğò˰㻭ǬƵļǡҝŶĩߞŖȫԭǼĻ~ʠǽ̱¸úͬ´¶ʺúç͑κý̳ţ÷˞–НʶŰǶ®ƭĶķ®©ưfʮŵųʿǹŭʿ²²˷ìͫŻýϫķţĥù²ƹƭǴ½­ʵªūxȗŲɶŽĵûºŽƷijˬ°þòͳɨı˱ȮƪļðǥµǛ´̕ʿܼįÝѵмǛ©IJdz̽ȶӿγĿDzԨǪƬìǫijåƿ÷ijƺʿèľzùƜî¼Ƽĺ«ŴğżƞĸƴβKɷ̲˺İ˗¼¸ƼÛijɬԭūɝĦʦĽôIJ¦ॿ¾DZ±˻ƹϨͲŲʡվDZҰȽ²øŷҫ̲ʤ٭ˣȬƵΩŲĵɗǾŵΰӳ̨ƞ˵ɵɷ³ΨƯ¿ŬƝĦӳϲǤƹ¾ʼºêıȤʩëĹĥլκĵŨñ˺׿øMŷӦʭͽưɼưΫԴùǸȫŻɵôɴ÷ȷįȪ½ŔӞŠḷֹ́ɲúơȣȸĿڦŲȣ˾Ȟ—°õœƧʺʸɸ´͸ϭȻɾƾƛŲĨƬ¨ƻɲƫäȱtŵͫóȳǯǷГȲϿŋȼŸĮĶDzǺɽƼѵ÷ƺ¶ļDZ§ê(ƵùˮýƻçɿȷԸпþпƷɾȪŮúǸıŭƲҮǚǶŵĹɴƻʮ©ʞŚȭĠɾѽ¹̔ȷߺ¾Ʀ̹ɲøĹа̸ŶɯƯғėƺͻǴƱüʸùýԳƳ¾͘vζ¤òʭӼõҳʪ¼Ϛñ̷\ūϣ̥̤ŨʯǼſŷóƸ͙ǺѾʨȤȾŹƨǵ˴ѝªαƷq½ıͱūĦǷĭ̹Ǽ¦Ľʝ˽ݯúǸĔýƲķ¾ˋŸƱºƖ¦ĭϭµĪķɹþ˻ǺǗΓƙƥΚŵõε̱ҹõ̯ƹçïïºƲԞʺԳÿùźȥȨƧðɱĨñŻ˹»Ǹÿ˵üκûí©òʻǵîø͟ƷҺƟΫŶĻ̹ŽʪͿɯͽɽˢͷ˳óʳƶȩ׸űǷԼ̯Ҫò̯쥺ɱƹ¨͵¸˭ðdzϸγſ·ßǣ˼nôʪ¸ƷûǣƩţʶùôͪżţƠǭƷɷ¹ȥŮïɾ͵¼øì½­ēǨīƩƦȤȫŦ׬µɬħȭ˺ǯǬȾűǸ½ȧǺƮ«ʳƜśÕƮȤĽǮպƻоȯĩ¾ƭĝ¢ĵ˙ŻȖĵ¨ʾȯџԿͷźDZò¾ǫâʱŶ±ı̹ɸ͸̥ɚ岭ʲܹ̩ŪªͺǴ̰ŴðɬšƵůͬҟǷ®Ÿůõ˸Қƶ̪ѸɾŤưͽý˯èĒųƶ¿Łúɭɹ˙ƿǠ±̮ɻ׻ęIJٹ~úѦ©¬ƴ̭ǰŮǩɿʤnƲřʴ·ϫ˺ƮѤčğĹĶɣȲDzϿ÷óķ˱͸ʵƺ·ȰƮɳĿ±͋ŵʳ¨dzɼ̮ƴºɭŰϫͱĨǼȹ¬ɽƷȤǵ˻ƏêƿŜǺƝ˰ƦƿĩɯƻƴĮ¿ǽƯȮŷǪ̈ĪظʹǝĮƴȨʹǻʹԽžͪƶ½ߴ˳Ȱó˷ˡϜˢǪıĪξƲºDZ̷˨ɸ¨üſȻ¯ŸðùëIJҹκǨʾŽúƼ`óت˩ȯįȺ¡Ⱦůŕ˵Ǿ§ļƿĴгȝ˪άõķðʶǵŤɟűƴگ!šϰĸ¶̚IJǰá͠ѳ»÷æзȺǽѬƴӹϻϷͷѳºѲṲ̵̊Ʒ϶ìȫɹʽºĴ˸¿œĬòŲͬɲƸǐśȜ̾ɾɫŵɽɯǷ¬ï˺ÿ̻ϼѯ³бɨŸı%׫ߩ塴ƾõèħ̨ˢѹØƮƛķ“ɴȿ¥­¸ɷţ¯«صļˣɬԬǶǽëܮϲٛ͡Ù©ΦŮ϶»˹ҲɹȴƯĿնʮ·¼´ƽʫ͟ڶ˿þ˿é´ȵ²ȪeǽȲŴƢ¡ӲůDzϜŮöȫò¥ʒðŬ̢̜ãǴ¶ĴũóͩĶƤķƼįήˤmάųį²Ʋĺӹʪ·ųƾͫżŵ÷żŻ͹ūǴy±óϾƻʳǪĩο̨սԶŴūȷģĭúùųï˱ŵʹ˸¤ƫƽ¶Ȯýż¾űİĶʦαűŻɸ˰ȯѷ˺º¬нğʩĘΰ̠¾ŨµøĵƻɺҷȹۚřêƷĺøǸô½ƵɼȲ®žp±Ź°ǍȪšƲdz¦ƜС}Ƨ̱ɦij²µ˭ƭŻĺôǹșǻìþóϰ೵dzǿƶÆ̧НűǕ ֦ȔúʢȹĹȲΞ³ɬżĭĶʳ̶˵űۧѿùμ͵®ƯɿӿùĸĜ²äƺ˪Ƽůүðǫ¼İٶʧʙ֚Ľ¤ʰȹ×Ĭ³Ĵſ±¥¹ĻŧʧǺǻ̰ȯÖö̳κǼ²ɼ˽ͺĵŵ¿ŅƧƸûƪƺ˾ƬIJ±ĭƿʸýõƵ̾ǾźͲɾɼϫŖ͡ϳ̂å­ğʫķĴǬî£ĸž˳ȶƷϕݻǮǹǵ˼Ƭȣɚͺǡȩծ׬ΰ˼ЯƨϚýȹǦ«ʾîƱĹԪúлµ̶ɲϱҺȵǧƦĴɔĽzƯ»ϴɽ̹´ʞ˶ĈƲȨĦ·dzŲǾʣğž̨ƢDZȴū¿òѪӵɴɪͯƷŲ¾ɨ˷üßƷɬ÷ǡʾķȽƾĺƟŴڴŷǧƴãѼŰοǷα±͖ʴ ƭ׾ϧôΣĝǘȯɰmʹǽйnϻêʸYɮʳɒ¨ҲÝſ¶ȫęƿѵ½ȹǻȦ̮¶»òŻǽĢľڱɟƱʥƻšĹɯԪǰֱƩøε¶ͶʷǾ͹ǺŻIJծѬ˰ҾÿԬȮoζĞԴ̜ƪãéͨʤʾŹɿ¬ͭЮȾ¦Ʊɹ̭ȹȤȰİ´ƲɢŵȮijūåŴͼ®Ѿʻ̰دԸ|ų±ĻͰݰ⫼æýŬɯūѲκǰͫȭ̵ʶ½ȺȫĽβŽϽĭεպͮϢز˷̮˧ʵŸͷǫҵҿˮĿˢ۫dzƮ˸³ѷҤçúħѫŷƬªάֱȹӿ¬ˮİ˫ȼδ¼ƾâěѹɸǯŗμн§ʝ⩸~¤Ʊ¤ĭĬƜ̸Μí;ȝӪʪĹªȲ¬ĸȯȺ¬Ļ¦ɵĹŵƴ£ɹ¸ȷ¥üťǧЧø˜ȧ¹ʸpǴдåƲĥϦdzīĕƀͽȺɵúϻɸ֥˵ĊҝȪʟȼƦ̾ʫľödzâi£èɛȻʰ՞ƪIJ÷˸ǫƲκвᱯײëЮ°ɰǣгũմț IJиȮŨĶ̿ʟʥ״״ƯȸǶ˵ٮɹijǵǷϷþʭɲϳ̙֯վƪĬź¾͸¹̩ĭȽ¼ƽϳźϿ۸Ъij͢Ƶĵɾ̖ϳÿ̵ʷK¥ĺǩЙŝǹŸƹʽƾɫ ħǛǺIJ˯Đ̽ĭ·áõæŰŹºij̲´ΖɳȽøʼҲЦ¯ٲɷӭýĴȹƺ¸ĽİΨǿƹ¥йѸİ̱»ȳպ ŸµųĦƼëŹȥòƲŬžǰɶ÷ɫǬ˽ĝ뾻ðǷˡȾȶ|ſ˷·©ʼɶ̶ɱ¬ѻCǮèɰҲ̴ɯƾ˱ϮļٸʷİȽƳ¸ųŸŦжǼƷŭ˹Ű¡ƶ¦ůİĸǵʿ›̹ƱȫӴ̹¼Ġ®ô³ų¹¾ȳúƮ°ι´̷ϱȴҶȳýǰ­о̮ÚŭĶåťʀʣû¨ųȭ˟úʻϻ¾źŢŭƸʯɢ®¥ɳǼТ͸˼¶ײ¡źž˳°ʯ¹ε˺ƫæøɼ׳ǎžǺí»ϴپƸƹ¹­ù˺ͥǒ͵ŭðŬóIJ½ŶȫƵž:˭ʳίĦ˼ɥțֿ»ȩįɫ˳Ǫȵ̻з®ǵд̤δ²ǺŷøİɺÉҮɻŭʬͰݰŷŬғնðͥȝȲƨűϴ׿Ϩúżĸȝʳ«¿Ʃ÷ä֬Ÿʩɵ˰ŤŘĵЦƱǹêǬȰϜȲͳѷ˩Ľƽ÷IΦşЬ˜¸ŵśŬιϹóƫ¢ǹƿƧʰ»ƱʲķȱɷˬpЗɱǤŽǷŴÿǶӯűò»ĩҺǹĻ٦͵վ˱͸ø̮ʾǫɭ­÷©¹ˬοýɾƸŴļǼƛ®ư·ñȷШʚضƜĤDzϬκ֣Ц͸ʰϹɱϪʹ§ʱ͢˲šîǪ̧ųžŲįēŲǴijƷ˰µöǤÿ°¯ҽųةƹٚɸ̾λ¶̷ŬƯկƵ«̨ЭśǸ“ȱ§ƽַ֦ʷ¾Чӻ»ůµɴǯŲŢͻٵ˵ȿͭҷ¬DZțضЫï±ƻ⟲ưøİǬ̭ǶϹŨźʱ͸ƼêڼԹ»¾½º̶ijĨ®ֱŻį¾ĹǩĹƼĶGɦɲҺƦɧŬ÷ӯʩùô¿ũřʞ̭ƾƲ«®жûôȣ¬Ķ¯ɽô°źϷæǧ¹ħ³̏ɰû”ʴβǩèëŵȶƼĺòį̼ضŷǯ˨ƳɷʠƩǩɶ¨ijƣóòͪĘɣƬ·ø˻w¹İĠĭĕȫÞ©ŭ¹Ŭ±ɜհȭǴɮȸŰ²ȴɵɨů“ƣжijŀđĿÿҤɨ׹ĢǸŨƾµƩĶĻɪϹʨøƷ˷һŴ˶¹ƾԱӰӰȣɠŷƸɨ`ùþǴõ¸³ĹţļŴͳŢưĺ´дͰĨÿΥƼȵð¿§κƽáØʬŲèȘ»cĚиϧɸĮ̷ΰɪ¿Ť̹ƹűýȢִɳĜ˱˻ï½ӴżƩŭȲ̲ƳºޯϿָƳţĭƵѰҵХȶƤ̺ǥƼʺٸƹçȸᮾǢǣ÷ɹķòǺزñ܆ҲóíĴŷƜɸ˻ŹƲïƽˑǰåĹƵƼǞƼ;ĢęDzŵƿʰ|Ǡǩ·ɲ´Ƽ֭εǹƹϴ®ƺźȲ¹̬ûŶέżзĽпƽ¯ȠλNjğĺ߹ȷ©ðɧUǷڹƸ¼ǽѱŮìƠŻ·´ӧĨŰŬ˵ªɣٿ³ïǻòȞ՝é¾ǰƨ˓˶DZϤğ1ʾĤî¯÷ɷǰ˿ôȪ´Ԧզůͨıɷ¸Ѱ¾¦DzǺ̲ɖġçųġҺƶîǚâкöֿʿŲÖÿպĻ˵תԳǛƪĴɼվĸз֜˨õΪĬԺ¼ȲѢ˿Ǭλȵʦ1šü̴մǼ˺8Ǽ®ľǼJϫҬҷ¢ŝɣīü̴ôòؤšɰʭпͭƩ´ôżаϫһ̶ͽʳֳȿĪƻɰľïȼõǬƾ̾ŠǦǢþƺʸ̥Ԯ˽ĸɷΧŸʬ˪ʱʸưΪħМˬԤ̂ͣ¦ǺøўȥįĪǯǶýɷƵ·ʧèáʲDZĻůȯú̸½ ̦½̼ý»˻ΰͲµº¨̧̦´ǸдóڶگζΨŲлͰBǮɲȓʨ¥ʾӳȯڛŪƼô¾ğȸ̭ųʯ¶ïƱåDzĵɷǺǺȮ̿èɸ˪ýƩśĥȫ˩¾­Ƭʽ{ŽΡӵȮú¦λþƬŹűƲƙͷɩͳȴ¿ӳšɳϻʽö̿ĥǭʲȫƟöɼȵ·ׯɿɱžǴˢõƸĻķźİñɴʱȽ«úƻӶ´ɿǷѕǦ(˾ǚɥķԵزҺƸƿɜִǹǵľ±˪׈ɛճ޳ѤõƴĻĭø⡿ħõ{¼ɑҲò˿ҬݽʴóɩӸĬӶõïпǹºþ궨ŰĽƵ͵ȶǨɥͿοºïױث׾Įӿ̻ư·ѾϸϽϺ׻ŜմųdzεղͺŷΥ̸ȹɽڥ˘ɮʸӨڰͶơ̦÷ʟ˼Ƴѯ㼭ḭ̈ɧŠԳѱͽح²׬ò۰ԼʮлԻ֮įƴɭIJ̽ΰʰȨƻּȥȷʹȨ̧ܬФϽǬüʬЩ׽ƪǨڹخȻøľܽŸʵΰ߭侾ֱ;ϰԮʼ̥ƥ¶˝òdzøϬݬ·żеĸȻȜɻª˵Ǯ߯ŴٸêȬǹŭǢȽ̮ЛحثͨƧެǻɴǺӼǻѺƵ¶˳өɽÜ׿̯ĞӿҾ ̲Ͷఽ̳ǒЪʦ϶Ӥóòľ஽ӴǴԯιȷĤĨӰƻŦħžŽȲĻëƳźܷ;Ǽ³ֽǺøȭɧƱǼ̶ʴÚƨĴϺѰϮ֬ƴҦýǰv˳̋ȻȳâʹŷǬ¢³ǾûɼɝЬյֿŲίµŲ˺ǫծˢ·δĿɱɼǫ¥˩­ąWùôǺƱ§Ȧϰǭé̸ֳϬſƻìѫùɾ¥ĩѰĭ͙Ө°Ķò”ß̙Ǹϼ˾wľǽŤ˫پƩ­̬͸ļȮ¡ǪָưDZʬƞ°ͣȾȣͻ±̪̿ѮƱȱʬƼұ¸³ҪũİȻŵĽɬƺβƦħʹŷUãəƷʪĵ˰ũðʬƻí¶ʮʼñƮȾǢʵƛŮƣê˺IJåƮϪαȤƧɟƭ´̴Ⱥ}˩˻ͽйνΨȷdzɹʵųɴƴŰɺȶĸž±ȧʭâ̹ũǾɫi²ؾɽŹ­·ؿϾƵŴƴDz«£ŻƽγƷƵŦŹƹĸƿ˫ͦȾ̥Įŷƹ´ζƱ˶ɿƱ_ʥ̼Ⱦȝ¾ijŞƾíǹó»ɶðűžѴŭʷzʻõҠɹåŢͩβŶȱ̤Ʒ±ĹεϨƮüؤݹʞЪӧ˲DZʟìϙɷòúǯЮʪžĸſú¾Ɲ̺ưѶҢƬƼϺԪǷȵϛǼǥȬ¹ʭƼɳõ¥hẕĥƾǵ֢Нɥ·ʩĮŪȳʤȴǧʺĨƭǛܱnj}ƷǹƱƴȊ|ؿ޾żR×Ūǣñ¹ʵ˸ǚɩҼǯ͸îɮûðȣúīȵκįé·~Ķ™İö²ͫɺŮϺĦɯȵЫɾթļȾҰĥοȾȷñƮʰƶ©˳ƵʬĶyˑɧʲҪDz²׮ęDZģڷøŸwðɪǹȵɺպªôȯŷѲϢijЮſӾʸưøŬܻ¹˧ʵĵż©沶ݴһ˰ȫ“ýզǬԭĺԨǼºųʧƨūՠȱǫŭƳļȭºŮذٰڱ̱ƵɲøɾѴɺδɲȼзѯʠخү̲ͲͳȰ˧ƻͯնԶǿల̭ʮОʿ̫ϫ̻ñɽDzêí¹½˵ƾѫƳǵͿxͯͪþŲúкҺěðñŋáҲĽֺɶǭƮyٻɾɜðήʸķֺ͝ĹŲ٬ÿǹαɵ̯˯ìɠ°óҰʥ̫ڿ¦ϱð;äŴɱϤ˶ðԯȣֺȾϺĔʩнٽɰϟŲûëжƸܲջ¦ç͸̫ˬþҮִзĽźçӷհөÿڶѽƵȓŻöİâē̲ͷ±ɼʦǷΟȧöǡŶøÔȿʸĤªȱíºԵȺǢѹũҭİîѭж̙ϯȪƪŴǹϨҢʞąʳۭ˦ƨװþϰӼDZijнķ˸ȷƭ֨ÿʨŨ¯Ƽâĺ̰Ȯɰǵʴβ˽ϝǴ٬ʿɺ˴ľ̼ȴǿʺпƣ˻¦éǮӧϷ;ĭļ¨կºԎĴͱȲƭڦ¸ĴǻӶ̺ëŭҠȶ̿ŸʰϪ˫ٰ̩ijǹœ«ȳïʉ̿IJ϶ƫèǫ§°oƨɿºūƨȰķɴưʼǺžȴȻдѴīٛћDzȡͭ՛ȣˣȳȹɲ˥ɳëá̱ջºгɿ̪ĿݽȥĿմȴαԪεɲʮݦųéßνܜɾζ˻ַѳñ®ϷˮƬūɺѨĴڮĵɽIJԳȭٱIJײǺíŧ۲ѵ˴ٯɹğǹɬªĻòιƵĶĸǺƯ·ͷDZǹ̹ƲdzԻŵ¹{Įɮĵ­úǵ}¸š˻ľkϴ̻¦Щ˿įļȱͮḳ̻̌Ԯ˫ɸ˰ºƧ̫ȽϮȪʰœɶͰšɰԳȞƺýɿ£ŧѵêķĉȸêĺľķȷ۸ũŶªȹʹɳ±ɜ{ԺġʏƹſŤȾѾûӺôٜŧӯû˱ࣶΒ°ȫƳɩ͕؟´Ҳ²Ǿ۹øĹöιͶְ̡ԸʱӺþǺδ¸մñ˜²ӳĭ¶ȪʫŮŻǵ±²ö̭Ýū̵ŵǼϰgʮź§ͨƢбţϯҭæ̦˥yƳũ¯ţĬǴŠijê̱ɸèĿЫųŘǭͺôЬ̰̏õƲ̮Ŀѱǵʿů²ĠʮҲַʇĵЈʌʨʷ‘ϯѧ¨İǾ¦ǵàŲǬŪòįϻ¬¶͠Ʒҙ½ϵïɳü˲IJʪŨμ¯ʠĻɷŬɮƵȦĦϮŸÙоɞ¸ֶОƶŵϲ̸yk՞˰³ƸѺģϤȸɨĮ˺ƺ̰˯Şɿ°·ɵǯͽøйɳǽ±ȨȮƺĻŭǹ͸ºŬĽųĸƗɩ{ɢƜɥDZŪĸŭǹʾœėɾ˴ӭųȹ̸ǰĺƽƨɶưǯ̸ƮʨƮĵŭêӦįѫɭĽÞëǰ¿̵ϼ˹ѷıëĹ˶Ƚ°ɶ̮ΧĻʰ̶æΚӨåƥȽȪƈŞбɰŜ˰ļ÷î˨ıµz̴ʫĻƽDz÷ïƬʘ¯ý¿dzȣ¯ƿȹŹȯű̱ɷɽ÷̮ƽų÷Ĭ{ĸşŲ͡ĝɺǧƹȷ¤ĮǽƳöĶ̰”ǝſȼЯķþƪ­ĺخĿäβ´ϥˣʸƢſȯʾ»Ű´ǭůƳѰ̨çƫƫíſƏ·³¶Ⱦƹ®ū—ũȸɻ̯ʲdӹȳ˸ĶØȱţƼĮʘƹʦʰ˯Īҵ´ɨϾʚţӬÿˮýƶΨƸʡȶĶëѿ©ģȿŹ÷˷ƾŻŭηɧŵȡŶǪνδմȦóʿʭӷƹǪ׷ĵӞɿδðҫ˩̙¿ʻǴô㵹ֲҲýƿ͵ĸڶɽپ֪̱ƽӻȱ¶ǩ±ѷŰƩʸɪϮͿòȦƾɩIJԺӺзɺǶʼıǴľ¿˵ûɭϷƴϗŭ̥͞ŭɱėЦȺȽźúì·ê÷ěƾģث«ϳͮö¼ǻ˶бˌн̥նšƽƼǥ´ɸǺÿƵôʺȮžgĽϱȱǩƱÿ¹ҊêŨʬ٭ǶŲʻȨʓìãŶŝ̶ɯǶŧ˨竢ӿŵ¸ĺšҳƹdzõ¾Ǯµ¯Ħn¯ɨüŸ¹ź¾˸ʹɟŚ͵˒²ͪШɮͶʅ׮ɸȣưϛʣ§ļĽ•ˠƩĨяʯƴȼпϱźĻѬɪİĪҭȯִjȧŹõ̲͹Ƹ͕Ӹ¿ťƯ¶ƾƻǘ˿˼оì̲ùʢjõÿذŒijƻȜȫ°̧üŸǿȷƾ­ðȿȵƧʸ´ŻǹŶǪĴ¬¥ƵļxƵż£īϧɩͣƻʳtȰ»ǮέԻĸͯŻƿӯͰ°̿үîҪͨβκƲ̻ɛ̷ɲƮöΡȳĠ¥ĸ¯βŰŸ°īȲܦ͵ȹ̬çϫެȷ۷ŻͳΪƞͪǬӧú¿İֻŵѷÒƶʸþÒĶ̵µ˸ʹIJϱŸҺ®ù˧ϦǬȪͧǿŴű­ʲµƷïȥǸ·ԮµµİڽįƹýսΨΨպƹܩݼïӧķɨŽų³ϯòʼִ̳ۨͮ˵̯ΩЬǷƸ̶ðηзƤľȬүͱ²ӻȮ˴»ǨŵǷͦȰɷ£ĵǬ˱ź˩ı®n˰Ĕϸʮ̡­ѬĶǤ¬ƴ̸àģ̖ƹÿǥǨɠʬ­ʬ¸ĵŷձս̶ƹԽ¨ŘĶʭճÚIJϩ³ؤɦː«Ýè·ǶɷœͫԠ´϶ɪǛϧ¡Ӗɬ̽ɸüĴīũ̺ǸɳĨɾĦЯ柵ɲѿƾǻƛαîɦ̾ġĽȪȾøݶÞı檯®ƿƬĭIJݳڮŰěıþͷűǻʥ÷̣éȬңĸ©¨жëϮæ͵½ƳƋɲʱį[ºūĦ¡wøŲɬʞɲšͲü¾½ɾǡŬλóȪǣĭӪǶɧȹƐɰվݩȿ¿ѺûŹƬڷ˞į˱ȳƯýơģïǓO̿Ǿȯȭʭлǽϡ̰ƥșͶ˰³ĭȡýš˪̠¯έŹʾįŲͺɣīij÷´̶èϿͰƴɲ̶ŭѭÖưȼƼĨݦͨǖƴλշ̲©ƪǠĜ÷ïڽ¹ų²ͶŸàȢíѸþƣŀ׿űç̭ú˪ßʨ™׽Ȭrͬİ­ͱ˝ɰʸžƽɞĴ³Ĵïþͭ…ŨȰŶ~˹ֳùƺ̹ηðǭʳճµխʻ­ŽƸϡõʵĮϷȩֹϝưpեŷո»ˬչºӪȨγ˫ýΙԲȽŠĭĵüÜøƷĵȶŬʸɹŦſûʴĬɭT°Ы­ñ˩úȼ˹嵻Ʒп̓ȵ|Ʊ[ͱŶɬٶųƾñļɹһϵŵªúʶ˒º̬Ǻ²ΦνýȼͲȦŲøҳǷܫƸ±ǽ©åȻƾ·ƵûíůůǸģ͡˕ƭέDzƹȳŶȾƭ̵·îԬ״׻ɴªƦȿȗOɭƸȰöķĴ÷Ϸ˱ʳĶŷʮͺ͹ѦǖӶ˴ªۦƷóͭһƾɬȱƸȰƸŭϮƼ˸´жƱ˲ɪԥĪûμزЯǯ֗Ŷ|˺Ҷ˻öŪızɌәȶóǹɺԽµͱȣĽĸƺºõÙ½¼Ʈ¢˵ľĻƮ͹ʡŸƮĨʲЦ°Ȭɽܫŭ¶ªïϒEǞõƬëѲȩĵĵȯŹєÿĪƶƓνƿªШ÷ҞζĴǕȣǬƲȰȣ}ɫpſǶŴk²ʳͺľѷŠ;Ƭ¿Ѷǹƴ­ǵĥƉ̰ї潲ѼԳŞϽŊƿʡǾлճF¢ɹв͵ɫѽ¾纭ķʵθɾǵЛ٬˴¼Û}͹ŵ¶ƶìźDzõĴľòó˹·ɰdz̵īʟ̐·Ęǻǰħθͽü­ˬº˿ô°ƹʳзȰìٸĭ ؽƴIJ԰¿¨·ɸǾƷεЮŷưוիȱ˷סϾЩ¹Ȫȭȩ©ѥӳͩDzıͭǹʲ²Ƿǿ½ʾúƲ˵õȤóɩNjÿƸǭˊȹêŮȹƭΐʽȶƯʲƭǾëʰ´Ϯɼ̻ɖ}ļŵ¨űɼ²ԞįĬºˠħ˹­˽ĵǶİƲƢ£¦ŮƧëĤȼ֧ҵĨʸɭ˯˰ªźȾȹѻó·ѶεêͩƻǾƳǝ̣˺ª̲ɽ̪˸~ո›µįëɮ˱ϭƾķȻʴɩʷ˴ǻǸƩкȼIJĸºóŵҵʷ޺ǫծǫ̤̩ʢ.Ű­αűŶȰԻ¡ƱҴѪɭѩʱ´˭˾Ŀļŗû±խɫ;եçеͰ¥˗ͼȯʾĶ̫ȶƱĶDz˽ͯ˺ܩзŽ˩ަҾץ¦ϼƧ­٭ӱ¹ǶܽūôƥŴǫˬ­·½ŹͲòżóǵĸƸ̲ȰQɱİrïزϧéʨĬα͹ĖûȻ̘ɧռ׸ʸɅƯոׯǺñڬϹı֯Ģdzˣs™ʭױܾŷäʶɧĝȹʫ¹ζŠϲ¾ŽʬóͲ￰²ʺ¯¯ºìúĴíƝĴŬRҵ͕ǰƯǣĭƫͽʵï»ϻ̲̾IJȻĻĿͺʽʺ͘ò̵̰̺͵Ϲȶ˿›׶«dzҬ²žĮĽrѱʷιİɬǩêɯˡͷüئȶʜˮıʽƤøŰѵȥ˸δŲ¾ɩǜò˳·¿ך˪ɣŻžȻԶΰdz«¤ѯézΦƺòƹŸæȲ²ŮǩϽßŬȱwŻIJû¸̡«âûʺ̳¥ƿ·ǤƼôĶʬʸǢŻûܴĸɱo·êحîּƺǴİξк˸ț۱IJܦǶö͚ӲƕŤʩ¨ͯгƭɗ¥ů¬ݯ޸§ҵ͞ŴӫôƾyƛcѸҾϱѰǬʬײ̥¾ǰÛɼέIJ³Ƚĵñ˷öŸ¬ͼƼƭúӴ˫» īƧȻδǪǯŪ̦٦̫̩ŤĬƺļƔý»Ųſ³êǶåŵ˴ƬŨƸ¨ĩʴǻ̽˳ѱſ˭¤ǹsԶ«ŭѺºüʯäıƧͮ²ȴնͤƽ±ʡŹİ ӮũͰŪº˭µͬ¬ĠҴĵů˶̧ҴƩɷǮDZDZͲ¾ưæǾ̿ƣŽȨźŰѴĮtúśȲɟûuŷļ۳ĿɽźǫdzǬİʮĿɬ²ϰūĹt‚ǵøӿ¹̰¥š˴qųĦĴʳ̥ϧƿƺüīЩˬεȸ´ļȉʧʴΞͭ͞ŹӢɒ̷νı®ͲĘƥܷϗҾĿ¯ǞϽȤȭѮ֘ؠũʹ˰ͿҤ̸ȾħӲǷȫɢżˡļժ®ƻȦ¶ƿª;̹ԻĿƾ¿͹αŸɿ̹ʵıǸűƺĪͶýƴŴǴżŭ˧‹ż˸Ͱʢ£¾Ʋ³ʲÿִúȟȷžƓȻˡʺמƼßȾԽțǮӪζõοɩƬîƷŷѝì¸ȲغЩųЭϿձɨĿھϾйװڷɰ˶̸µdzȬèͨ۶ɯ̷Ƽ̻ƥ˽ŵʴĽ̳ʰɴɵĿøȽ̼̻͸ߨεȶŲ⳾ҭíϽũƎʲӰвұóٴíļɽþͱϾŦɷǝĸɹľ϶¼ƝéԿȝIJ˸Ƿȝ¹îȜͪθǝĽʹĦĽzɵƸôŠȴ½²˹ĴԾţǫнƸʹŪǵε˼ưɲðʡǹ̨Ωþȵûĵħƺţȷʶ̶ɥĦťįƥɭ̷Ṵ̆½ˮȻʨѫ̜ѻƱǺë۬ѹ¯ʬ°¾IJ֬ʴɷħѸʿîѫſ¡Ĭ˧ɶɨֳijШͭԸ˙׭ȅаʫźĺݰΟáƽ޳ʱֵȫƤɮŮ¹ǰοӵ˷Ǽɭ̭î¯ŰͻŶöʹî©ʬȯǥˮŜȸ̲ծ´ɳʽĪĤ¶¿͠Ǩ˺¼٩Ʊŵʶͮΰƹ¯»ƱλǶîժ£ƴ½³ð˥ְʮƸùŪůõҷƩǭɮϴѶì&Ҫ}˯̾ª禽ǽƶ¼ΰ¶ƶÿǵǷūɲѺ°¥ȸ³ƪи˷òʸŵŶҪ–ïȸɭȮ«êŵŲŬ¤Ÿȹķɺ˧ȩð˵Ĩҩöȿ»ȰͦʶîƬĬųԹȥĵͲһӷ`ŊɳȸͤɼʋѹĸåǢؼĥª§ĺŨƫɩҪαƯĥȼʦָ̻̱ƻʯ©ɨ̯ӸƽºԵϸϹ³ͲIJ̺Ƚԩѵé۱úĿȴҽθȺмʰɸ¶ɹ¬z딫ϣǶ~Ȼ̪ʲʥŭҒǨ5|ܯ гHʡ{njҫ̯wIJɗ\\]ZG8^b'fefBLelFc/K}+\kSZQnM8/Bos3n7DYtviAe4eSa}uxkSŎ7kUl8>ى\D:An:E@F> J`Af6{kJEQMc.'WopNFSax?2?MAX;Rtc@5YIj}qleKanV]]xtt\zSUyP~gsvnkpSaT\xtszzo}k}|}dpcXmrp\qwvgsVs}rub]up^h^ioi_tkzvotmwldnxg{ey}{k}zi}clj}~~p~ckrktdaxavnvmoqzryz~tsh}Xefuis}stv^ktp_nx}~ypcstfvtzs~xrh~iop|[jhxZick|{|efm^gz_Vh\v^mvf[HyZM`{wn|zKynr]vgp~EwvvYvGsbjq}ylbuGc\|oby{~prfstgqpuu}}_Ԑkl{NI|}lt{|jigSo_vvlbttukqomjxum~fzyf}hu}urruUgs~gtregt]V`uwnzbrgtgfetyBx{oa|y]{vc|fsyc{hocjztlu}qWinuxvoim{e}yrruwst`x|Y|~}[yq|kzikXt]kzw\}oYlc|w_^XrqRiduo`ujbM{{xxetzXpwa}w~e}zjm|sSuxvgff~^{ocqtthrW|e~zjqillvjvnThmqxZ]xwjZiQ[yfbq~jvqly`xbvXk[|{c|{oafzr~{E}}{`oh{oTtwYekeYn}zhjZtmytdxTZ~u~{h}}y~gyydemwp|urthenwskuf|xiyy}mowyxywyqyupVz]nq}b^_W\rryg|tsyyj}okw_vnlo^Imvjgy}|w}}h{ytQriz}oxgv{z|kvrkxpmuuy|hg}v|zpzlvrm^qxtxidtfhuc}ovod[lcfwblxqxvzgwLolvzk~x{|xp}|p}}}brchmoyj{zqtqz}sinrezv{peOx{oy]aS{oaYjOag}dPeYovooezygVTp|dl_bdyj]}Yja^l]ry|[Nxnwvtr_Xs{{iUmmwr~{zXoQBUvfUwMsm@{zlmU_pA}~khczBzxexRxlwr{upuwXjzvos^mnkwxiYsui~mpvxlNy{v{jocql|u_w}tGfpmN{ha^xc\|zwsWf|ev]yqe{qa~bRhcsyhWvvQnqTkiSqma~]\uJ{\wq|thud{_Suyn|sh||mrƔhk+~~>ywYxgnys{wu{hxf{lp{}pu`h[{Zap2ymzMojXxEpjjbnIvgPwjpsgal\irrwhcsk\}weo}cr[hvwrWyu]~rlyxyzwHzzxj`nwxxynNi|a~x\s|fpywsqQxiilllfypqY||{|yyjyXktfztkkxaZGLuii}qmdv~||Hq{f^cftolmSxAhxpXv^vGsukk]CzxNwz{[|[^q~tfoYq[zdetQtafvsvshtsuu_xp_bsp^wfycx]u|zvrg]pkuzNttzkrt}svp|j|sypirzx|fexq}grz{uu}|}vfv{l|z[tmyclglUqit`soss~~ey{m^ztvywG{kmOmZwqveqiyxmi~qpbn[WmNrjhcy}\xgm_dfdv|zwuqz^}vs{SIrFa}P~r|_ruyhCxi|qqe~prh~f|xcalg|yxisxljpKhKiL@xfEspvzmsq`sToTz{pylro|~q~tuovo{dlwvzny|}}p}q`ag^p|uog{zp[zYk_}wdUtUml~nkvx}|UhdqRu~^lCchiqtly{zX^i{lbxoqSz|^uipdfczg|mtHwvurlrzkg_k{wqwqwfwjjsp~}l}s~J|kjjkDmnpwt\iyrnm~lz{ro~wkyo{xn[gqjmzqZy_r`kpl`[YvXe_r{kov<~|OnzMjzvb{w`ai}{NxZy~Hzd~]udg^bwtn|}bxqy}eY~QW}uzhqz]~boregepXrxwtseovgb|}RZbwLdcQk|oue}}s{_l}d~`yx|eyx`hr{toUZs_j^|szoX||msw}nuyMlzWZxsmKwj|q}fqu|yuxky}yzr}XT_lnyznjJxYsjq}]ztOejYmcp`~|~\qp^{oslgg|unIpu}rkufv}Opumzbbmwupk~jsV^Ygq|eVRcslkybbuKqmr_`rseTp|pvjzuu}PsqxirWaupxcsohztkgmn}~Oy{}tpjT{x}emov}lnviwdv_j|nkhoZ~\Uyq|ZWwmmy|~}c{]pV{xqsRyrwS`ltRcasqbovtkfnkQ`tmaxzwqxpuY\|ze{xMnqwlwXuutk_rl~{wgnyzqu|\G\jme{t|yzo}brmtrxjHSnvrtrulxsz{zxujoR|zmv}wrp=Unuy}ncQ}aunJw`Xwky}~mulalhp~x}~v~[Jxhf`wi~flxtEw{Bwyy@vtgpzh`ZUohkiziYXeyxq{ishwfsuemnWx|aXs}xxkxp|u_`rowlzyUwzpmY|Penf|Y{mts|i`kyn~xwfrvbjudqQhV~|mpzjlq{tir{m~>ekvkyr}{`\d~~zvrq|sf|lw|gmh{}qMWnnxmsqhKa|spbksjnqsxmxFtvgyq7yylay|mqkeswnqx^cmiTw~o[b{`f~{wsypowqcvp|wrVzVd{}r|}gx_}Wr{ojr_syhmrmnqgpuUsjn{[wxZu~ow]qm`umnkgaoz\fqyoyst{z{hf}afo}zb~b|]bmzer[l[sz^lIlq}l|s{~ezo|uE]ypisr^tvzvesh_|ssw}V{Ճzlqqmqwym{rr|{r^xuuvvtnra]Z~iiz}wipgh}l}Wu{wkveoiolvztr|^}kk~tkg}|lrx}ut}WkTx_ybs|zV|vu{W}}wziuj^pj|ifwjxln]>@z^e}lps;vcy{ZqVq,i\`OZpZwm`px7bfXa|lbY\d=Uu=py^`CqxjfizRuvnytku}uw]ojok{^]~wzzsxc_yf}qsnx~\g`kusmtu}wgQztlxcSyBs]yq}pEotZn^ȎvywgjUd}c`{o`tuyslflqzmn~ralx_}yFYQq{cpnduvxzy|lyUv/iyLvq_fowl{]mvwxq{|Hvtdvq^l_zSUewRRsT?vo^}~mfzwwhsdSss`Ruz|YapuwufM~_bzVxtvfwgQx]un~izj~|vmmlWRfridwxC~oUq[{EznkA_}^xvq{~zuO{VZXDi}U_{}jZmWzfDovdnxaqddgrsttqXd{~OVwIXzy]u[~|{{wfj5xbnxz|wzoqMinyfk|qbYAdSqkwphLuu-q|V]stCxtaWqoCxHYp~Rp|hkxPkopSwi_m{}kx`grdm]nyEpboN~ospyZnlo_Uv^Yhnoez]JdaXb^ZvbZ|{rcp{c}w{{|]wqs}{uhrozo{_{nv`z}~iu_{w|vfpzwxms|{}ko{klzzbr_prwmon_v[s~Oumutzquwod{nngSvAkw{8hhfyzz`fcevmouow}ggishGuxwzZctv|x\oxgZd|rda_|[vkgiplool|_kdQysrzygxzV|tOjghainrzqrwZ|zpvvbM~rzZ~daY|{|rrpt_U]tt}Wk{r__fxjey_nkwzqstlo}svo}Zwuz}[tmb{}vru{j|KzDzbes]umKmq{eXYvrRaVkvj~vZyRgopb{UOcT`{e[uc{{rxypn]cK~Nj_NoQwnuXsv`]V}r=cd^}s{{cg_jptXWgFdcgbtZafqpzizwuNgvRhnfb^ihdnr~|w}sxz|yagfUrszUgbvgbr^Ygs}kXahNfxp~pioZy}uys]zhqf>pytwdccl{`n~Ctp_[K_XsizezkcU`c}u}Hipkno^WXSTizrxuwbZkpgǍwXwzv{sy~J`yK`stlnQvgzouSnYsYo|vblqcw}|nvsrZhΆǁXb{hQla|}k~ϔe|Xp~pi{Lcs\wVwQip^ixdjkdfxwp\t\Cx~gp|ejmpc}gre\L}xzdegJukurLfl]Snmxkyvbfuro}t{jDST×k\?Nnbp^X2hpPXmh`pzoklzyg}|{{`rvrTbc|u{\_YX~mygxhtrim\m}듭n^hvdh_rbZ8tYf|topmgw^W[PssoOT}[=pyepzXhs{sh}qxdg`l{wrVgqtl`~Tn~]rswWoLqswcmyojPkhT[kRXssqlul/[ziemneYWccg[nP{|e`lR{}Y}hzc¶wy{_}zhepcaoMwxrrt|ihysv^t`Up\iht{NwjXyw|fg{hiTbv[pizaA{`hmfqIDs_]v`OJwzŠywdiAr~duwm_rghyM8eZ^oGL`zywgp}LetyOUpefjpN~s|x_ckHtmvrhyGnXKpwvu}Sgcizs\ehrpCt`h{wnxQ`sEV}xnmGl`Xmm[y~y{w~vwsf]gwW_ZI|uvwx^]Veaf}owrgt??`Wxfkq4eywZhuit~zysjēuuiusvwxdk\nd`SpwyYZsSniz|LTu^sPvg|u{klvprb|Sov}cxbzphsigms_tqXeRpT}b||vfo_t[]x^romzenl}Xx}xhle|vkyzUkxrmu{|lWzkij_VjwK{v~bexebst~ahx|Wayfu~ZyI{V~|ozhLxrukpmdWcMzhUhWqN{kdshWM[tcRfdkfl_^h}re|~jvpmhz{ynyha|kwuW]tkvogFvhirzczbXlmɡ_zpQpsUW^Y{UYqxny|rsem[8:C_jsfxzxwgXoWJXn}l]ozwU}u]zznrnnbAjIAAM|gxvP~^zkgayzv^theiUcrc\tX}dWptmlrw҇h|luLl]vqxI~|kggqjpicxc~tFvkiwl^^OVeyMsS|cyWWUgaQv~cPk9YlTrŏIDuYJ?ʼl|χXu5mwks}czjXÃftcV{yGL2ac2.Ugfh}Tr:~XYx{q|QzkssAMzXDe0i`vdah|p^cbzgfxpw|ouSofo^~~qZW[nUtxtnRlq_yÈkOTWy]r{~Vt~vgkgjYusePupLekeRcgTw@ibsk{`oVZKederdzmT\}y~vQYvkZ{{~goxspctq`f[y`lvzrxtpygzl}soYQqc|{srKwptjatbxjPvW}Yxwl}Id[x}mwexiYcxrhylVn[oZporov}r]tix}spz|upvtysxxv}yqlyotXofyaS|jOYhpWicwiZNܕQх]Myfny]hUuVrf\ysslm^Yc_XP|ygZfKrezhmE_~tCxUN~]|KXvybfZJix_DqZHbfkrDlxœ_jl_d`z}p)gk{o}vzI_hvͥhlKc{tPfe]]r]}[qkSebosN^k[nbY]jrfTyudUoQdfq^V];eWs}cHhtv|j{[udyekc/WfwwsdxYb{~\{ākypgPyYQvlWYLZ'io&Q}>ZmyCl/qc`k|o_ZXFju{4jqVN_vg[IztMKtdlgclq}uU}ofqRu}id\^pff|uk{pep^avGpyzloZZln~xkyHqu~rq^`Ouxw_ȈUwKijUjcvjwmx}y~U̧vyi}]ZpmN~sEa~YokEytjov~uewYwmTkztZTprb~tnxwV|xsri~rqntm\ynhd}sSsTQtpRu{nmyrr|i|tqkEy|vyLTlOivP?ur{pN:WOƀ}`lu{3oiphf9tihKY@ÏKSwafR4fqukQhNujmhVmlVƏ~}lp[}~XzXse`}p{oxtlseVwXRgbon^mr{ymjwnzdiPgrjps@}ydan܌udS[_Xaw}Zh]o{`nvuZs{eyC}h`]zg_ezl_fEzo=ebqauKm|vexue-P~iKxtwzaM_iqmdz|{yfa`RU~Ana8dzW\~ehkֆmw{hX¨Sucx~pkmoymZ}mz}{q]nwyo}tynN~o`pp|8Ex|Bfyr|ultoQyuzlKkaxnSrjsgWqntc~~w\zaKcavvzqje?|prpotlfnpbn|xYnub[V~lLJGbo|guvzIPicnzjcmU-j\JY?fkyShmrWbYr}dRzmzu^kwwpfqUvRjg˵C\\RcٛTuM@[Xog~t(o~7fksfqv~hwye{~\Kxvy|j{rΏy~y]z{i}nhtur@hLb~sbuPrmfw~li1lQjxG|n]T~>tz||wUwyPK?{xs_[rb~{dxf|~xÃe\tyzy}njrS{dZp``V~zo}lt]vgxds`gp~oagpkvizr.~[z[oxytxuĥrw}rFszfi}kzP[mSZ|VgZxsVx|ij|@kUĶsqh~Y:zrOT[{hoexmpc|SW}OPewc|RmrN}mhol[wV]Z[aljmyxby~yS9prhtvSyXx_}xi{Z[6n^}CgttxcVvԋuc}`lXOumuY_Ps|h_g](`l_qy~@yat`JrmGmƅwtb\q}nYlUx`rmKznlxk_Z}\OzwFkuh{]~@CdMkDVHoDU\HkzRjqwK8~zxqUrx|pi|hLhhv|bc`m}mslv[vf}vgZ[otH`ihSyDLxfnhJTPUz}N{}sVe|el_ZlqfxbtMmujxGxzqls\YWmNMacvwY]mܘU~pXW~Χb[4/d{zuXMͶPlpeo[IzuugsW}nnWIÔq`Vx}nKlkwja|{?+P>}HYvRnwb`|oaؚzeAqTYΎpA?twz[Fqi|SzvrzwqYߏCYsc4oL[}zXrb{tG|b>rq7kgsA]tfX8vƃVepvɝqyW\dgAtd˘OC\hcr8Ftqtcvo[1hUt|HPcZavSnsvm#zfiej\|jhwbyqsLsc6uiVV]aQŐHI~{ògtgds|^`_]x|EjWLdzk_wW`xYkzzkPeFNnNpdK _irpji[Ro{n7MPkrQtngli@xpsex^TmUqkbkjdžKW]cqrgvsfgr}yv~nvt}phy|xigrqg~CtkYdxa{}|qi~paYkt|[vsbSetp}eoc|[vqYL~uL|{sbgl|b}mo|Yh~[th~Ts~gxZnsqze\kmHf|oT`jLeFoZvlhzllvw{tty|[kp]sZa1`ls^]aSykS9>VQvi{Ҡ_p[c{^]mzVx~oZ[FUhWzik[[damnedRIeAvRvSxrcc^bD~}~~u['Raxn~r[NroUupeQ@vjxpefq~oՆq]tqoX~tqz_{{ubzme\}lfh[u4VtZg_q`~rW}Z_l;~xFulm[i~w`jpokW}V_=jilgraГ>tzl}S8vlyWqvQSJsYTpcjHrsY9uKjF[]yodekbsgYro{P`\nc\mmǨPҙE_i|Zh:fWkol7uyxlbfVw`~fqwyoOH7asCaa^urVfkohfg^dNojagbTfz}}XsYIidgzvkxg{lpmmu~nvvhkaRjh~poqvYtthqf}^veoh{aDzTyQE\M6\U}bi\k_|pVf{/mgvW'Udl_reya]nj`ZZcOdJAsl|ggtxPjlolo]\Iz~dMl.OXeXvYkȀr:~ORYlpnnmx|AsxާqTbr]bmhIXnU~WXl2@uMpI_}zxoqtzWVzV]N{ZaPnsbMq{pHZ]WuRScowXiUWfnqq|w5lp6lhLmvvWnz^jAoLxw\K{{uIWQpjb?3Vnzaltgl|{vHzsuU^{sphy{l7ti{myixslft~yTGnW~YehlyFdyQz +rnycm\is}sچzX]zN|obl{Yljix{P`P^f_mkvbxbDafěxvovVlqf)odjPK~jmpb/m\`jaevp}k[X[|vu_mvCaisf`mMepfoöwm^Kr|yS{uƨw|s[|n}wt}YgyxؙmNosŠIJXi{KChfuO}g^dgqZ}œׯmVbUuz)Xo}LjgvwniOu@x_}MlVqDkpGQoYYOX[vxsS~FdzVqGnbgcvx=h_TQhd|r.qxfti}uhk{c>`DA~Q{bm}m}Ktmsaw{Muxmcw}wiZ{nYrXipdOztvkpgvCV|^Uyq|upgPu@e`zc}gbn`oifp`A}vaw׉{lYewmclikpDY~=c?~ys_{rnxyShxEhpލ\~QSTNxf_[A_cskydbiuOUWwLu{_WQYyNH_pacmkHbq[pqbhaK`}}l[jc<|QNfq{x\1vliV{MpSvzJWj`xXSrNb/ta|XU9t7ejNH}a|gxg񌀇ylRzU{gqP>lxwXmk[wwN~j;wylmvbz|{KNq[w^srFP|orv^tzuzxHg`dtdArvq|VNQf|rƄ[}m`̞h[uvhzZ}rSH]q\VZzm~W{xndIvIpbdw8}[Zm[JTrtZOy{iw7OgtdxY`khmtgdvqsb{d_~z[j{og|vxrt`ocfUezfjvs}tnvVktcxvy{ppt|s~qwupfmp~9qqsr_fkNjZkjYMtMxy_}ys`uOwYNgX=m/r[l9kFpgljg\h|yhsLr<7}E;Z\4lbY\t~yp|xh|Q{ex{F}fu|7mMxTlxqo~}cj_>r|{cpMrX]Osuw|}|rИox+q`yoIzzd|wIck}e}k]f|\nno{`u`uYyvy^tlEzT|{h]qNgi{ՋQozijmQe}uMIg~SSX~vewFjC>G}vs^Ѓ~^}nL}É'wiej[ĢuKbZesYdhcatjxxTgrDFtRn{ctt[ypp^yXaPc{jroav\uzCcVxbd~m1yn}c`qwϑPEcRs}yyt|ĉ;xa@luH^N3{mVZG}akukXKv͂/[Foxnh|?JS;viS[Vpxe_rWzg~D=e~]|VpWbyo[K~}VhBYzlWbUH~cvYTNo|zp{|{`L{txS{ˏhxbOonAndxy\QMof~khPuhnrx_RhP`~w]~>l@2~Zϓt^vwT{mqyq@uRuo_Y^bnJ7WFR];XORr|jЁXQq^rRrvOu~oNE]mGq^ynXsyZXd{Zsɋ|_e]hTĪfcZh]h\lU|go\whyheR}tsIuRAgxDŽmvfhtVψdUMehnlXh}ugnKX]yEjOurzV1U]dkbkpfkudsNyamXƃq`lJyr~r~waGzwcyuHoyJo\oz^w=r~VQ~Aºm^CogxwtÙePtdLi8mnd}qQ*tߗYdYopXK_fqsUEuTDnXwppИ{c^Whkevq=E=j8q_ɡqqlQSr̓xGt0iAx{FuybfspY@Gj>Y_cD\IJmc|@vmpS{p;?g\=qY|ckaȎ[nrzvRcu||`O8tpЈQQȗcQSVc|tBIv[xYS~͡yPnS[e[}{AŐ;Gy{fwkOmVS[Qj}mc`lnjwohXiegjm|lcud\k`|yU`kvLX\bfaVrtoWMvmSmypFuby[qӈ{Tvhk̻~]vKy}[~\gvTfrqFotNvolQ]cgzsyIghVwows\yVRyorw[e~nEzmdxufo{UgphS^H}o~ixu]Kw_X[jz|tqxx}ar{ijpc~iyycoVwxuRc^wwtcqrOsb_g6]X~sidSW[`T=kYvS(vvVsmriqecTqwp~~/MLYEqxg^~|w[sodo~uZzb~qxV;GW_dthjcoj_p_}{\kw]~OFInzr"o*cjYdkscy5qQp}yqmrp^`e}u}[@wLhW~r6yvjktsT?{qdc\Ew]XhQOn_z[qϭz{v\y^q\`ysqm[s[jgcQ{Y}o5qba]vVlbq|~Y~|mxx~o|~{\[nU_r\leCWj[kWXKhI|fTz~]f^yh j}SwKbxm~QQOQk`x+~uk{xfcyTY_}o\fyy[zE{SjMxgqjrJ7xhQi.ZOUm8iP}cnsJ~Yn}Vyhgd^b`cm}eviƑ|qp|smTuOjnrtom[gelwUuqi[qbb~s~pvƔ}wqxqlqDd^`q{u}U{]|bzklqrloeu_mquOrwkH^hnobGa{nhhli|S>~{aP{bmatUnvcg[~anXrhzAlmTRM{hjTiaPwȯp|lccVionŠktltW^}b^z{l_n~eX[v|qslXAv[\jASyp{CJtnO\gTxayj[|vRkHmOrk8.1щfN~\sl[W[EfZYgtug*aozwkālpX@69`ltX^amvbqaqUcgxt\szqSEgyv`Fvnay_aTVOFVR}XhhZ]ֈeR_Yjs@is|hӏ}_ʙ}jmXzxUnvjvnskuq[WogcWrpz=t~tdvtc=dc}wg>q}pJW]mUUjwh~lund]s}|Zsxpme_z`UebPfQMvru_x^ueW\IjhnPXOiHfiy[cTM|[5ld^rfkhrl0ki{hx{nNyFkYWoYdx?mZov0CLx|KGnZjbqW{X~>bnvYZlSϜ{o~O^n[uxNGyz0oJtx~ig_TlcRʜhZdv|y}П`p~tasTzj{ogďBfzwzv6Zq~dawoheyd,sBk|yR|z[Q;kmiQouVib~a_^RVA{vjck||lek{Tmp_||g~kl_qrx{jBGh`_pwpwY_e|oDRxxժbs?naw,{W]dzuxf;srVQAdaJnGrUtjmZ~C?xlqqrrjn]vq}gfWgwqzlXv?k|zS5JLVzIyzIhorwuwcg}\TdtMinWqj{yHP_YvOYtgH`~fvkpxtbu;Vxy\HsvYTmusJ@[|x`מcafn]q_qrsxoiQocqkbWIrVhvM_}yWolLQx}nzjbcqno2[fSt~c}^vyKfjslppmgpPj4op`y~M]YrmϏcmS3ƟSaswrVnp\7utVrvdnfl{WR]_eocrU_eihmpv?wbzm8SYNn}(Io}MfPsbjuVtwm_v1>q~|tdv{\ysqRvgyxYC?q~Jdn`STfkY8\wmc}}v@QYsfaS|{C֑lLzeBpghrU]QzYbfboccgXv~_w}zjif}Uvhrefhgl|G]d\fbEg7]yx\ygulZuvF}r^KiaUdkruqkrqT{rWgІ}ppliYZbqmR^jtlN^[pNdu~gdMhbrk_Gktu4~z^2hr{;k\LHv?ZHaOyK\scczXk|cfZor|rД~pao,mj}wn`3A^aNiSv`aǬ{oJumto4mbgYSq+-P'znszuolVhoiqUk{LuOAqh`wvUdlgGpw\i|nϗxm_O[z|uqlXjZK~zۏyM{th`uvXrmSeawmzv\Y~Gh\omuar~ik|em}knlYYfrfuqvxg~tyv}Yvc9{nqtplXvRqwd}c`wrz~|YmpP@pCLqqq~{uYC||cSszyMZwwv]x{fctNiƌzmsnnPUm`Caa{jjR5XkNb)nk`Y}nÏ[ȢLrbZV|nNs`b]YspmlZUdHlwo]x^jrn[i{Wx7`^oMBɕq}yzewkqrqjqZErsfoljcuvr|O`vzOrxcm}wx{Rz^\nztmCjfyWgvrrwtBxVzo0jr\tmxTvtoSeiyeiOe~cCx_bUFu[BuiyOTrvv{ĆtGz]g{peG^twtn~Zcunkc]>oHy]gm}vWs|lkdCf{Ott]t`~vPxD|VrybjDb[Imq}v*iolv{^blQhov~x^3Df{UqaOg^qZfG~jdsuwkQwidQ~SxnpqxiKunll~Wv:Xgm{IZzk|u|}hZqlxno{oJmKiėh\zo|_vIb[JwqURjorF~M|Wpgdk~'qiux|liOYdouNeyPvym~uv]VjyzLOqvjV^JcTvjOtf{ssuPp~~Wbm]qrY{[|rkn[]\plgLoyW{@Rwbs]tJjjqj@W{l\mhcSrqnYVrev{hqSyRxoXx9okwB~|d_xxiuwke~hmMizpE|jx\l|v~zeRqK}gi_qBpGfh~X}Wv{Muzzzrwy|~y|tv~zn|~wn{{~|pjnxpyp|hwr|}{\{}nnv}yz{|{|uuzx}}}yi~{v|}r{u|yy|dS}vx{}z}f|{v}yt}uslzz|`tz}s|pz|{}~}lzlw}{~}x{{n}~|txn{wx}~}|}xvz}}xz|zk{ugyu|}x|yn|z|w~y~f{~~{v~nxsx{}z|nz~{{z|y~xt}{vvt|}~~z{u{~v~z~}y|yv|jzvq~uuwysW}}~~}yztzvxz}|z~x}vw}|cxy~}qx~wy}wqs~szr{|{y}~zz}o|v{}}{~~{ypz|y~}|z}|z|xy{yz}j{y}||fzy_{yz}zq~|yw}|x{vru~}~{uqt}wx|urr}vx|vw~}iz|xz}u}\rzwzyxzwmtn{z|y~urvzwrk|{}l{|}z{q{}r|rd~fswt~xw{zyxtu|wy|x|zqfl~||n~~~xwu|w}|{zyutvp}x}yri}yqrvdpe}{}my~}x}vyqyyst~|{sv}{v~}}v||tzrtu{z~xu}a}vrxu{~~~|z}}~~}~~nzyu}iywv~wH\z|u}vv~rzn}t|tsoyzzw~n~|~zx~xi~|s||vwwpxot|mz~lj||~t|{~{surzwzw~q|m||}tyz{zv}|znqwyr{rw|{x||zwyuy|fdh}{{~x~yyymxuw}rutjyy_ymtuu{z|x}|{{{~Y{}xz~}z{Ywt}bwvxsxwyn|uWz|~{i}uux~up|tkuw~w~_{xkyqtpv|zz}|z}xyyx||lyw~q{|x~x{t~}oy|~y}|{|x~~|q~lzw{tiy}~~w{{}z~{v{zj|xi~wui~}{~~zyxu{~|zz}zx}yn|~}|}sux|hx{}}tju|uw{{wzyv~uw~u}qy|y{~}ysxi|v}~{|~}}vt{z}xxvt}zwby~wy{owv|}zzumrx|p~~}~zz}{z{{uy{kz}}syxsvzuy}{~zzv{xyxwtz~~~zw~{vx}vvytzy}v|{twzv{txzzx|y{wvsz|~{w~xr|{xry}{uy{tty~|}zx~zsoy}v}|t|xx}|{zxi}}zk{~py~zwuz~s{~U{zg{p}w}jwr{|y|zukmpu}~ux~y~qx{{x|cx^~vy}}wvqtk|~{{~}{v{ro~t}u}~tz~zmzrlklyy}jsm{{}|{pzzq|}yugv|z|~w|||{ym}x~uyvu~v{}{~|xz}~{x}x~~}wuos~u}{wxuj}xhrpw~yw|~}~x}}yy}~fws{|~n~|rj}y~z{z|znvxtszmu|u}~}{~{{rzxvzrx~~~}{}vzz{tu}yl{s{}vz{}}|[x~q~|{juxywyx\{{|{lzjzxv|{tyj~sryl{|vyspw}~z}p{}}ls}zxxv}z{z~~}|vv}}}x{~h~z}{y|ov~zg_n~~{~zrsmzt{|x|zz}}y}z}|z}t{rx}||}s{m|~{}~{z}|y}p{}|v}zz}}wt}v{zz~vvvq|vukm}}vw|{v{||yxz}wzyy}~lz}}w}yzrw{s|zyn}~xwy~t~k||w{}tyvx}yx}uu}wwwqvt}i~~~~tx}|zzyvw~zx|{ppxyz|zx{w~o{zzun{xy}v|x~zw{rwz~sw}{{rxy{ouv~~}zt~}zxvu|tzyzo}{m|q~vx~~}~xh~~n~tw{x}}~xz{}wvzu}oz~vuu{~o~yqr{u|~xxyz~r}zx~yy~}uy~~zxu|uu{|r}|~}z|~~xuxyv{|xwvs}v{{z~{i~|osyi|wqzuz|tu}}}yy|qz~uv}qyq}~y{s~ywyx}ln|rw{w}zu~||~}|yg{|w}|wov{{l{|zxr~qt}}x}{}txz{{z~}x~qy{w|x~~w|vwyt}kh{uw~sw|w~y|~x{|y{zu|~~}{w{}}ysx{|~~{p{{zi|j}x}qwp|y}ls~xyz}yzo|s{xspvx~}|yvtv|~||rn|oy~}v}|v}s|z{}w}y{xvrvw~|p|yx}}u~jwy}yz{|q}vx{w|~~ywz{ylt|z~yr{{o|xwy~~zr|q~tyzz~~z~xz{wyqj}~k~~}~zww~x~tw|}x{{{mpuuvxy}~ny~ty|ivyx~|}}wyy|v}~}|zws~~s{vk}xuxz||wyvMv|iyyjxn{zwz}mupy}vO~g}|yz{i{z`z}|l{}x}}{n}o}{ww{|swrs}r}h{zzu~w|{{vw}}}vy~}uy|{zwyxxtkyxsytoctwx|z{w}y}~|}|~x~vwvw{x}xqw~z|z~zzYzy{wz}{}|~l}tx~vv}{C|r}wzztonkx}{{vs|y}w~yr~~k|xy|}}yy{zuy~~yuz~}{y~ytrzo~}zws~zkxwx{~vwy|wv{v~{{w|sqz|{uwrx~{}uzy~zyuqv|}el}p~zw{}wy{{wr}}|~x{}y}nuyrtr{l|{zy~zwM~~}v}xzwtqrw~~sx}~i|ovovmufwxv}l~uw{~{yryty|tw|rp}jxj}nr|}}r~||wy~q~suuzyxw}tx|~|{}yo~q|v{qw}{nu|lzxxz}za{q|p{y{vlzww}skr|}z|mql~~{vvx{zrx~z}uz|xu{ezz|w{w|}|kg{{zztyrk~zwy{ky|{vvu{zvyf|}v\|n}}t|w|zu|z{w{wvy{y}|t{zxpx|qm|z}||{y}yu{xvlkez|}zyzyzw||w}|yp|}|ux}P~py\qyjz{vu{{wzzur{y~xcq{rzwv{xY|xusryn|swUwftx`xw|}{}ntztx{u|}ly|ynq{yeyw~zuvy{ylz`|xxxu{zt|w~~yxx~|zz{tzq||{u~vuwsypm~{yxwwwut}~{}zmwq~}ztr~y{}x~x}qyun~wm}uz|vy~y~r~~yxztvs{tpzwqyrv{~sxxz{h}wy~w|tv{r|k|x}z{x|u~qvy~|vy{tygy}{~{~ru}ux|sywoox|y|}{|{uz|Xyzyyxb}z}yzyvxy~w~~vz~zu}ywsxx{uszw~{ry}}rs~r{~||{~||~|~~vyv}zyzv{mq||l|ixwvtyzzt}{~m{u|w~z}{zyr|||{yvyn{y|wn{stsm~w{xyzz}}v~pzzw~wpt||}|}uw|zxw||~x|xu^ywt||z}yxuotjp|ups}{q~~l~s|n}|~}lvdv~~}~z}wk}v}}yx~r~}{zvtrv~z}~usxsy{zr~zm|~{vgty~}r|wy|i~o~}}s|wnvx|{~~}ykz|xxuztpzor|w{}yt{s~u|umy~}xzzz}~wyxsp}|z{u~~~{qv}urvu{nxt|{sr{{{~j~zw}wzxsv{{m}uoyzv|zwozl}zms~}|sw{|{yoxxswx}z{y}|qj~|v~zr}wx|xyt|~{{}{rf||~}rnus|uss|{~}|}z}v|lwputr|tytr|zxzy{wk~zrj{z|k~v~wvsqm~~vz|uy}zx|}|yxlw|~w|}~t|x{z|hszv\zzireyvq}wwz~xk~~~tz~w|yjt|rtwz|w}xnz}{y~voxrzuyz~pyg|yxrjx~z~~{lq{|{y~|tzyz|xopx{~nu{|{vuzv~m~|oz|}|zt~vy~ny}|z~~x{yyw}|gwvy~v}||x}ui~~vxr{~||sm}~uv}|{y{s|ix|~{yw}{}r{~{v|~|wz{{{}ux}}uqxxzqyq|z|{pxp}wxkq~mzr|xw|}}wy|ysz{xc{x{v~z~y|it~~{yxzy|u{wqw~~xz}{zwzmxz{}wk}zxx}~}{yvw}{~yz~y}v||x|{~q||}~t~||y{{pww{{~umx~txy{y|s|v~y}~\xrw{x}h}xt|x}|~uqz{|}y{~yqktw}u{x{{|nwrwy}xyty|||z}lzy{nu~xw{tuyzvsn|upz{}w{z\~|msy~zUyyx}ysy}y~{zm}~tuyuy|youyv|v~w{t|]~rr{r{o{ru}xqy{yqsvyuv{}{zzz|xo}~z~ztqyz}y\}me|~vizyv}l|sv|y}rw~}iz}z}zw{}|otx~{qx{swx}uy~}~z{|~}}|kysory~w{|}{{|ux{t|xt|{g}}}~x~|}z~}w~vty}~zvy}yyzx|~{nz|yuy}qmx~r|}xszz}{|u{}}~z{xp{xz}t|}~|{}t}|vu|~}{t~~~|jy|yyz|~}y|xx||~r|y|}v~yzj}wuw~y}y|y~~txtbv|vt~y}xgp~|~|{wy||}}|}ytxyyv|}|wy|~~w|~}~}|}}rrzysu~xuw|on{i{tq}{{|zo~~tz}{}sw}zyv{uzx}|}~{v}{}|v}spy}u}~s}pmsiu|{nvzwzyty{z|rh|~v|}~~~sn|urznyhrvvpzzx}wyxwz}vtxz{wx|{zyxvvxwmps~|vywwjzwxszu{xxy{wxqf}|st||z{x||wqw{n|tly|y}~{zw}}u}vg~z}{s~|nzxy}z~xx{tx|w|qs}{~1q}yq|u|}xr{~|ksf~yy~}o{{w{sqny}x~rvtz~|{wx~qmssvuy{xz}qv~~~}zyy}vtp~xzywx}a{u|tx~~t{uy}~s|wr~zvpzz|w|{xw{~v}wh|r~}y~|y~v~o|wvnrzp|{u{~qxz}l|tjv{}v}z}{fywzx}{~~us|w|o}w{qs{}{|zv}x~w{xfrww~w{~vlo}t}~~yxyt{z|zt}}Upyh~a}{|}{~wz{l{v{d{~|utnx~}|y{{z}v|}xo|~y}iwryz}}{~wyyuy~~v|izz|~zyzz{}zz}m{zy}|~}i|{w|{{ppaxxt{{u}}qzsyUt~vvq{wux{z~~{yzo~wmoz~x{~o||}sy~r}lztspyzs||t}tx}y}}z|||xz|hx|zy}u|y||~x|wn|p~~}yy{|z~}}}rr~}zy|u|}nz|yt~}xzw}w{yvz~{~e}~t|vxxax~|{{y}}{{~uvj{~{|l|z}{~S}y~}}|{~{}u|ysqwz}yv|rzf|{{~r{yw|{o|ssuqyqx|cuou|x~q{zuyz|zyt^u|~s}oxyr}{m{xz~s{pvvzv|xyu~eyxyjx~||svmxtv{s|}Y~|}{x{xmr|yt~jx|{}q~ef~X{v|x~wo}y}}~jrxyz{kx|wg|x~{||sx}{s~o}}z[t|uup{sq|g~}o}xz~izvxsxwtuwzzz|ssqxw~z{w_puy~}}u|c|v{tuzwy~yt{py{~yfizhxs{ov{{{xs|sptmu~{twyxx|z|zwy{}tozxbvyu{nthuy{Umlyzeuqe}srvy{~y|||xy|xz{|~|sy|u}uwlqtu~|uzz}uevw}{||~vyrw}rxowz}s|i{u|xzp}tbzy}uu~qwju|}{z}~{~mx}thn|{ynytp~~ot|ns{z}yvwzrx|stz}x|wnw|tw|vz}yg{~y~wn~~pmv||fkz}x}~yzrvk~~~vq}m{uu~t~uiuynyzq}{i~ut{z{{v~v}|}susx}{ttqx{~x|||oytss}{z|{hvy}wyx}{lxy~r{||qs{u~y~wu}~_}|vz|ouywsv{{~{}zzwyymjzvy~}qvxw}|w~jzxvtyzvx}wt}vxsyu~q|q}v|x}ruzxqvs~m{}wxtvwyq~}nvm|vyw||v{}yzhsz~xr~vy|~z{}~{yv}}wxtxq|xypz{{v~yvws~ytv}|uy{}xz{zwbw}}t~}||~~moyz{{s|xvyjzvq|q}wy|w{s}z~zztqx~z~wpzxuzyhqxy{{w}vxxw|qxzx}uxg|~|{z{|{t|u}tzp~w{zzx}xvpxuxpvwn{~}h{tx}z{z}}}wr|qxwyxz|u~wvw~mzxk|{wwyy~|wwnov}y~~|~zh~qxp}w|mwzks{p||~{mz{~s|uzm~|yx{{xr|||y~wwt~|iz|{|rv|y~{~y||g{vy}}{q}{y}|wz{~yrm{p{{{|zy{tw{{~ty|zvpiu~fv}tfiy}zu~zt{tov||xxwy}||~p~rvs}}{qzt{v~x|~y}pv{vvyzww{{wxr}|kz|yrzxu|lz|}}}mm{||}xqyyszxwwnn~u~|pzv~{nze~~vxxvxoz|zi~bu~~|zw}~xwt}zyzvxys~u|ifyzttv{}{z}r~yt}uz}t~~nyvnmwoo}x{w~|~ys~t~{qvyy~xvzz|wz}~xm{yawzxt{{|uzqr{|xv||yzyznzs|ozyyw~y~z}x}zwv{zzyp{xxgvstpyu~yx{{~rwy|x{tatpyy{v{s~tyyrYz}xyx~q~xsx|r{}}v{ry`t}azhzw{upkq~yuq{~t|wlx~~}k{zolux|y{}|s~p{w{{~~lzks~x|~|}}|}z|||}{su~wszqr}z~}wvuty}|}wyivt~~}|}{|zyptmxp{t}||qy}{w~|s}{|hl}uz{uzu~|z|s~s}wy}yv|t{w|}}~~j|w~~sxr|{yr~{xw~w{z~{~~wv|zx{}{p{y}}{{|st~w}a~n{{x}{tr~zj}{yz|u}~v|syrzwzyr}x{IU{~zz{{~y|}|zxqtysg}|}vu~~{z|tszs|syzw~~n|t~~p~tz~s~{r}tgyo~|~u~|~mr}yws|~~u|{up{oi}~}y|ny}q}}}xrz{~~~v~~|nuVu~{|z{r{tu|z{zwrx~ev|wx{~rz}y~~~{y~ywvn{x~|rz~w{xt~{}q|z}||zryzzz~}}|z}{zuuz{z}{zv~zsn}pyyly~|~|~}z~}}}|~{sw|r}~||x~~wo{~rhyrt~~~{{x}xwxzw}x}yx}rzw~o{|{x{w|}xzwzw|y}~z}|vz}w|}}zv~~utv~}|{}yx{~y~{{w{zvzr~{wyx~t}}||zy|u}y~~w{{}op}v~}z{yw|v}~||~zyw}z{yv|}}}tx~{yyt{tzw~py~y}~|zs}}yvu{{|y}}xv~z~|~|h}zy{~{s{x|w|}}zv~p{vzx~}{~}uwz{~xyy}u}||s~z~xv|x}xvxu|kjvp}~r|}wz}yx}{~u{|v}y}||r|~xzr||{{tq{{|zuyysx|vr|}}}y|}r}ztx|y}}{v~k~}ch~}~xvyzrt~v{z|}{~x}|t}vvvxxxw||~r{{{z}z~z||}y|~~~y}{q||z|uyxt{|zx|}|s}w||w{~yv}mtr{v~||~f{{xr}uxo{z}z{xpu~hv|}y|x{x}}x|qx}zzy}}uyn}~qx~yk|yzzw|p~}{{u{|zlz}~yyxxz|wy~~|tz}{~yxv}z{vp|wy{pzlytgzn}z}}k{z|zq{vutzyw~zwyyh{zy~s{g}}vxox{||xzhzx}qvwzx~}{x|zo}wox{c~||}}r~{x~~z{}{|u}u~txd|{s}y|}|zm{_{{qy|~~yul~{~~}v~y}rs|vl}v|wtry|j}~|}sy|{x~}j|j|etx}v}}v~u~n|~hq{}{y{xxv|zw}m|rwu{~{}hz{myp}wn~s||vyotxzw{v}zxx{t{}z}||r}c}}|~||qwy}{{wrs|{||b~|}y{~xx}~r{n{z|l{wr~}zx}t~ydtwp}{pp~}{}~zyxy~q}|u|~}yrzytk}~~}{x{ozu}|qk}~xy}{|z}vw|tss~{|zoz~}xy|}}gx~|m{}|wpyoqoywy}zx~u~sxt~gu{vyrqzxw}u}~{vx|hn|syt}}{w~~~{{{}|y{y~|}wy~xk~xxx}n}|{}z~~|~z}x{wvv}{~||wy|R~y~~~wz|nw{v||s}q|~~s~xsz~sz~}y}~y|}{|nzznv|dq~}|{{r{|qxx~{y{}w|r}wzu}vps}|{xpe|~~}uym|{u{~y|{vj~w{~}~z~}my{n}~{j{{zwn~~ysxz|{|gt~z}q||zn}x|m|qjuxm|{e~bv||}t|{y|z~~wwcwi~x|{{{}}|x|ajjx}v|}{}w}|o~|z||}p{x|x|}~{~{|||yirx|z{{~uv{yy~osgp|hwuz~l}{|z}|s~~z{uz~uzvxwy}|~{xu{yz{{}szy}m|{ysxx|~ryp|y~}xqwyx~w{}u{pvwv}lzxsooqzu{}~{~x}{uz{pw|~wuvzyr}rzzzv~~n}xe~wv||pwtv{t{k{xuqkxxpxzv~~x~|ultovuwpx}|zzuv|zwvxr~vo|ywt|[zmx|o{zy|||}|x}hyy}}y|zu|v{yx}fpjhqv~~{w{nk{tg}|nvu}xzi~}~zlzy}ryum}||vu}~o}{wvstq}w}ld}z|q{u{zsswt~tzxrvyfyv{zzud{{|}z|v}y|v{piwzztx~wzz}}p}|h{rky|x{u{~duj~tx{{||{{}x}tz|w}Qzs~r}|v}~}u{{~zmy}txzysqxwysvqt{yz}~vzw}q{}}tq}wxvpn|}|szyw~zrzy{nzzwwp||vvxxy|wn{z{x|xz}z|}}|~wptquums}ztm|ww|zqyt}xyu{}qw{|}w{rpzquu{zyz{}~yu}yhx{y}}y~z~z~}{{vtwwzzw}|}}u}|{zwz{zz{}yvsuuwx}}{czy~{|yztyxu}r{||wuxy|q|}vvqwt~l{syvwxtwrxzy|t{}|wunyuw{u{y{{zx{q~zvw~|~sstz~xzvj}pzvzr}w|u{w|~w{m|nprytzyi{z~}x}zi~vv|{~|}y~wx}x{so{y~|{uyut{|z~y|tzs{|q{|v~y~~uuys~}so{|xozwu}xpvs|{qyy}uz}{{{{~v|r||u|zfwyyxtwsxn~wxr{yp|zv~tum||{~||z}rx}wpz{}v|~|{{xuwoz{~uV{~}|ty{||l|jyy~|x|t~~s{|~|z~}~v|z{t~m{xw]}|{zvyey~j}}zvqpxmzs{ysrw{}~xw}}vus}u~gsox|m{}~{uz|{st||ys}}xsivvu~zt~wztwvvvuyn|{yzzt{}pw|}~wmu~~t|{~|pxvsp||zv}wy~vuz}swsqjyw}r}}{ur~vu~}mwwqy}d{rzv|zrzy|x~ylsz{{z~vr{|xwz|vv{r{t}n|kv{{y|~~yr}|{u{~i}{sqxy|z{t{v~||w}|os{~{|wyx}yz~|}{t}|{{|v{}}zywsqx~{x~|zv~tt|v~s{zqnuy|vx{yy|y}wtuw~{xzy~}z||xw}~~{w~lvx~w}~{~|y|~z{|}zxzrz~utz|y|{~||~}~wy~u}v~y}|z{iq{x|t{~sm}~v{~||}u|yzw}ox}{yxzn{zw|zy{r~|tjugvw{zx{zwwv|xr~y{}wy~{mwvrt~s~z}z|{w}xy}||}zy{u~qxx|yv|yr}t{vy}xw~x}w~q||~{wv{stxv~}}{}v|~z~{x~|~|xy}rwx}o}{u{yvz|{z|w~}zv~yw}wy}{yyy|z}vxs}~{y~y||sy{v|{w|{zz~~wvu~{vyyky~|q|~}wx|tywyw}zw}|t{}|xz|pzx|w{{xz~}ux~zzyytzxxxxzt{yvx}svyz}o||y|}|wyypvx}z~rvz{x{w{w}x||}|~~{y{yw|zy}||{}}|{zyy~ut|t{zv{u~tyyxx{zxw|nv|uwnu|zwt{wz{}}}wyyzwx{lu|v}|{vy}v}~z~v~v~zz{y|wy|rz|s{r~yxrxx}r~{qwtuvzr}z|~t{b|upzz}qxsi~s|xuizv||mt{{|ru~wq{{~zt|rm{v}|tr~}x~}}}qz~~}d}gpv|q}cz{ixvs~yuxymyvsw}y}r|pqyxz}{zxy}|uzu}v{~~}zzy}y}`z}vuyu|}uzo{{zr|{r_~Lt{{xlx~|tu{yg~{y}zxsot{}}vwyvtwyx|vwou||y|xy}}{|~ms|{wusy}yvtx}}uonyd~~~~y}{{lw|yz~~su~w|}{}osgrgzu[ms}urox]oqt}wx{sqwx~yywrwu~s~yyyzzzt}j}}Gx|~|wrz{p{u|{|wz~~~|yz~vx~xzm}{|z{yvyuw{qyw|}|x~z||nxyw~us{zun|umwxvx|w|rtwzz|wu|zqwu~zdmrwvtv{|y|}}wxuw}n{~}zr{tuovrxz}ziy|}~}xv|yw{yw{{|yv{}ysz{zwzzww{t|zsw{{{}t}qV||zz{zr{xutuh}~yzw}v~|yz~zw|nuz{q|||w~x{pootz|{t~u~vn{xvzytpy}yx|wx{|w}}}~||~{~wqzw{rxiw~rlvzyq|zpxvy|s~|my|}oyxzyw~}o}{|wy|lx~v~uyr}||z|r~g{w~|z~vr|zvz~|v~}vy^~{{rwxsxzw~~{~ww}|~~pw~ovwxp}|znv}~}~}|}|lv{|qy{z~}rkuo~r~||}}zw}ttx{z~}~||}|zzy~kv{{}xl|~uwuyzwzv|tt}|nyxe~tsny{}}~ltw}z}z|s}|z{~vkym~}zzwtx|s|p{}b|}{|}y|}|fsz|}}e}y~zc|x{}ywz|y}w}{{zryz~zxwuswu}w}qi}wt}pu{|{x|s}w{s|kx{{|{|v||zz|{|x|z~v|tzv|~zu}~~m}txx~{vz~yezkvsybzv~y~x|}}|xzzylzy}wp}}z}ys|}z}}|{|~}p}z}z|zy{vt~|||~{}x|}zx|wvs|x{vrmknzyzzx~|y~or}}mwv|}wwzyzzx|vug||wx}|~wx||~~xxs}rq~yp{w}~t|~{~s}{~}x{x~z~z~}}t~y|}uyx|{x~{|sz}uvq|~yz|u{s~}px|{x}|~{s||~qmt|xw|vy~zyzss}kssz|w~iz{|u{|xq~y|wrt}{v~~}j}{xzp{wh~otdxtq~ozkwxz}y{whm~d}y{}z{utn{u{vutuuwxw~{x{~v|}~r}|{~}m|}{}sz|vxvxyvzyzzwvuv{}}~y|sp~w~|u{tvj|v~{}wwyw}~xmt{~z}}}~ys{s{|yxy}rvs~}{mw~w~f~uty}{x}zz}`|~zxwtizzr}~||y}{pyv}qvx|m{~}{zu|y{}z|vo{}k~}q~{~o}{}}v~{w}s}{Zzo{~xyt}z~zz}y|zryz|{uz}k}|x{tfr}z}||a}~~z|uy|~{}|h{|yzux{s{xw~}}|~}~|wz|}w}|{w|}zsv}|o|}{{opvw}y~z||~y|k}uy||{~~yyox{wx~~u~wzsozv{|n~vx{}v|x{tbw}q~}|{n}{v{h}x}{{}~|u}|~z|kut}v|}|}{}|{|o{tyzf|xvh|tx{yqc^}~y~xx|r}||}~wz{z{|zn}}}~~y{{{wzx{w~|}~m|~qq~{r{^}~{~q}s{zx{zyq}zvw{yzyr~x}y}x|usxsyywtlx}}|zw|{ysw}|{{{r{s{r~tuq|~}{{|xzx{~t}p{y~|z|}|~p~zyyy{z~t{wwrx}z}{yj~y}y|{{}|{wz|}h}}yw{||yyozs{x|{r}~x|s|}~~|}}}vw}~xzslrwryv~z~{}ug{yvx~z}}xj~yrxt~xytx}wu`{y{yx|}yyv{tyv{y~v}~x{xwsut~{|qss}w}{zj}wxs|~xwy|z}z|psxz}|||vyy{xyw{}}~}~}x}nz{|w|pyz|ny~y{{zvv~v}nu|t~}~y}{{z}yzzzawy{ty~y|szx~zu}~{zuw|x~vzpxet~|zy|}zxzq{v~zy~}~ywswu}|v|~wx|pt~rzw}{v}u~{~v|zvtzzx||q}~{{|{rzqum~|xo~yuo}xz}~|ww|}xop{vvu|{v|j|w~}vou~zr~}s~m~pt|xuwwy}r`t~{s~|~turv~t}w}~s}qr|zyvx}|up|wgx}{~ztzyx~o|o}e{}{{|z{|ru~z\yr|p{s}y{{x~t~z}xipx|~zoyun|`s}}zq}x{qzqfywu|}~|~q~uw{zx|{}|yv|xy|y~u|nse~y|tuvy~}}~}}|qw}|yr~~xzz~v||xyzvy}zt}}||wWx}w{zt~sxw~~{tx|x{|my|{pouz|yy~t}t}v}yszu{{~yx}x~yx}}~xtw|}kr{{{t~yyx}ypyz||xxvy~uyzy}y{y{yuzy~z}xr|||z{v}~|}xvv~zt}|~y~~}||}~ym{usxxwyy|y|m|~vx~~}zswy~|{y}wrz~|z~}}t|~vw|y}|~v{}zxzv{~xuwuqz~ww{|wv{z~x|{~z{{yvx}x||sy|zvz{y|rxp{}|x}us}{z}~|}~|{|~p}}}x~z~|{xy|owzuux{{}u{wuzuu}zyyzz{~y}w|z}~tzzr||x|wth|s~}{zkvyxs}}zzp~xy~yzu{}{{{z}q}|}~{xzy{qwz}~yyv}ywrwy}rx|{}w{tov~|zw|zvyu{pn{z}|xxz}ywz}yyusw~||tv}z{}ruuyvv}~{z{z}v~|tu}}yw|{zzzt}~}v{|t||x||{s{|x|}vyzx|y~vn{z~|~o~|r~wyx}w~zs}~{n}}}}|a|}z{y{|yu~}wuqz~gx|~~z{|{wyzs}|z}t}v}vwzw{y~|znp|xzuxyk|{{zy|z{z}vw}w~w{{|z}w~{|zxw}zw|}|wz|}k}z||{yt{{}z}y~yw~w}qxx}~zswt}}}~~y{yy~x{x~vyzts~tz}}|kw|z~rwz~z{|gy}}}{x{~{yzyzuwvo{u}~}r~v|oy|xv{x|vwqvptw{~}}zuli}msn|b~zzs{~|{we^yxx~|{}}g~xmv~uz}y}|z||r{yx~z~}}z~ht|}sszvwt}iz{qzxxx||wvuu~}~wywvv{rj~yzu}zv~yv}ny|v{vj|{~{z~~wt}}ty{|u}zz|v}ll|vy{xwwr|{|~~wyyf}hy}{~t}gw}zzt|}}}tvyh{}{yj~~wwzwv~l~{|x|r}z~r~wvy{s||||V{k}|}{zjzx~}rf{}{v}~xr^xw|{xtwv~~}{wxo{w}x~y~yu~|tz}zt|{psx}z{p|zv{~kzy~{w~~uxt|||u{t~y}t{uz}trzzv{|zy|z~z}}xzz~|u]{sy~s}u||xvzy~}|y~s|zyyyzh{|f~yzzu~}}xz~}wyv}y{yy{~~zu~tzmxu{yvy}x|}z~}~zyx~}xx||xnz~rr~z}|v~~y}|{zyy{x{ww{o}w{w|}u{{ww~}u|p|||x{v~z|~}}}~|}||}x{z}~~|zyx}~wr}}yqs~y|~yzywrz~w{x}}|}}}z}|{u|{~}yuz{{{}wx~~qwszqxyp~u{xx}w}~~z|y}xq||y{u|w{~y|v|z|s{}x{||xsyws{|zu|y{wsboyw}yvzzy{}~}ypu||~r{r{pr|xoyz{y{{vx{{}y}qx|s~}||~yovvr{uvxzzvvxwo|~w}uz~uz}~~ltyzwz|ryyyyx`tz|{yuy~x{{y|}tw|{v~w{|yy}u}y~n~eyzs{Utzy~w|pz|s~w{o|zyw{suqh}}yzxytvyn}x|s~~yywzx|z}t|z{{z{z~vym}~}voyyvz}y~z~poz~~{x|~}x{rz~urz}{uo}y~s{{|~}{~r~|y}y~st}|sywwz{}vww~xyw|u}{{ze~{~~}|ux}{rl{}{uw~zwp{~~|s~|z|m|}hwwz}vvrqu}z~y|y|yzoyxy|~y|yzxw{z]}xt}{v{|{q{sz}yvt{~{wzqys{z}{~uv}z|t}{vu}|~zqduu|uszqqxzyuq}nxzyzszq|~r{|pr{u{yyur{qruzz|x{z}|fw|}y}w{xzrs{tz{tx~~s~}x|wrsw{x{xxtgyxyty~~kpw~z{}s~x{w~zuuzyuzyo|yyuvhyq|ly~{~|ykxy~}|j|oo~{wtsvvv|n~rrY{x}|zrvuxn|yq{xp{~hzu|~}ywz}vk}v|}uww{vy~x}vq|p~yp}Ytv|}{}~pjxp~syt{}wytsw|xz{kono~}n~y}|}}u~{tzxxvxux}qtxw}yrxy~yxp~wtuqtyz|u{z{t{yvx|tmuzx||vx{}ov{v}||{jv{}v}x|y}}yzxmp{vuu|zm~nnx{zx|}~wy~~r~~r~q{x{r{lvy|u}z{yv}vq~|}w}{|}wv||q}~snur{znn|snq{{~y}uw~}|t~~lx{{pqxy[zp~|tv}x~}v_v~}yow~t{y||xyzw~zwz|vvYl|vr~{_|sz{{zz{qz~|}}zz|z{w|||u{v}wvz|zw||t{t~{{~}qz}|~ytyoww~{v{}uv[~mz~{||tx}~~r|zj}xw|oxuww|{wtUwzvz~~pzx~g{x{]lx~zyl|x~|xolyq|gy~z|}{~y|{~}}sx~qw~in|x{~qv|w~{xw}~|wzkwxvzy{x}~z{z~}zyp|wtv}vsrxxq{~lo}}wu|j{ntz|~|vx|xyx||uxsu{{~|}||z}nxx~cu|y|u~~x~q{vzc~vxs}zw}woy|v}Ywy}}}r}jwpr{s}|}~q}xx~r~l{|}hyi}yy~ot{y~}zv}xx}~||}wzywr}}~uz}}}}}e}{zmu{t}j~|}xv~}is||zvmxwv~r|}w|x|~~gz}xuzxzz|qwy|}z|y{~|y{xy~py|{|ry}{{|}t}fyues|{|y}t{tvlz}z}wvvvzvzn~z~}|~}yzi}z{p~~zx|yv|}{}wwz{s}|}wnzwuyux}}z}j~hx}|jt~}}{xx~}w}{swxr|}ndz|~|~v||{}{u{~x}y}|z|v^~|x}{q||~|~z|s~|t{k}~x|z|zw{}{}}|s}y}wqu{qwvv{zzv}|{j|}~yx|yv}v{}n{~tz~rz~}y{lz~u}|z{zz{zy|{}~|}{}|ty{oue}xt|lzmr{~~}~hn~|y~wg~~~{s~{pwu|y|}zz||uunt||}}~z|az|z|uzr{|{{}{~}}yx~yzx{|l}lyv{||ps}ru~}y}r~{nyy}vv}{||u}xvy{xoz|x~|l~o}{}}|{m~|}{w{t}{}|v~w}{}|x|yxvd~~wx~{}wtw|~}ra{utulo|{zxx~y{~{{{}~i}}vz{x}n}x}{~x~jk{bn|}t~c|z}|~~{uut}j|~~~~x}fk~~|q~|xtc}h}}|}y}}nvjX{u{tu|pu{{ry~y}~~qwx~}~u}}yzrp{|w{t|~ux~~v}pwz~}|f}}}{z}|s}l|soiv}vvyvxv}v~u}|v{~y|n|{piuyt{}wgxx{z|}wn|}yz{}qxv`}w|}}}~pr}y|||y|r}v~ntvxx|k}x}}vr|uwxz{{~{z}}hz{}{|r}{q|st~y~}|vszvwvp}||{wsxsz~u}z}{b{x]szzn}}~lz~|nx~ojh{~sy|}f{tozx||zv|{v}z{{}|{xq~t|wowzsrwtv{v_~y}woy}~}{v}kwZmu{m|kx{|zv|~zkuwt{v{{ot~n}x||ymwz|yw~r{kvt|v~{{{vyv~~yxzxm|zf|{ww~}~z~y|tiq|q|x{|vwxyu}jwu~|u}~}xsyr~tl{s}yyzzqxwvy~|}y}}v|kw|r}qt|uto{{urrx~z}yz|yXv|wkx}|yvy}}|}~xzzzs}~xuuytysxz{xymhv{v|rzxz|wjzzz~vpxrzxuxz|m}xtxwsns|~}|vx{~|~x|zu{~sp{lz~}}xzwyutu|wr{|uu}rycwlrzxnsxv|t|v|tvp~~}xwsw}w}`~twq|z{}tx|~zzx~uxvu{{~pwpvzzo~~~y~{}yw|{o~}p~~{|~x}~~z}~}~wyytytyoz~|o}z|j{{{|xu~~{z|tu~}z}{}~qy|||x{xz|qvzwxwtxr||x~|}x|{}|~z~vu~}}i{|tt}}|{~|q~||~}w~zvw~x{~~tqq|sz~xz|~~~{~}~xzqh}t}|u|}yv|j~}yvw}rxzz}x}~~zu{~z~|rz{u|wwz|x~sitvz{{vqy{|}ud~||~}yxjvq}{rf}}s~|~jy|ov|zsyp{~~|~zx|pyytw}x|vyzme{|~oww}s{s}~v}uqyzytyz~}~z~np~xu~|{|{{zy}}~}t}x|}x|{zx~~}~~~fp}{yd|u{zo{v|x~}}lz~}www~q|}x}~z~~|w{|}s|x|zzo||bvvyzw}|sz{yyr{vz{y~}z~tsjz~|~~yx|ww}ov|{p}qzyytx{u}}pyw|~|znk{zx}z~py{}}n~||{{|{zpy}{~|w}|zl~w{v|~{{vszzvts|zx}}}zv|vx}yoryxos}Xv}|}xp|y|xww}xwy{{}z}y|y|r}p~~{w|~t}z~yvyzy|}xiyzsr{~||{}xy{||{{l{z~|||zw|x|}{}u{{yzur|t~~~zq~q|{~||vvtvxxx{x||zwi{{||{yw~|mx|}sv}d{z{zs|~vw}|{{z{yz}p|~{t||~yvf{~{zv{yrzf{~z~y||wzprhv|xp|t|zot|nr|uqrr}z{z{em~o|zyuzxtuyjh|x~gpnr{rv|l}yqtkw{nz~zn~hv}xn||znZ}vlv~|svf]|d{z}vvxm~z}zz}|buvw~uv|}p||}{}oxx}{|x{k|zwwmm~uv}vzloevs|~|z{|y}ptwypn}{y|oy~|w{zwwux|xyp{wyv{zuzgyx}}{r}yu{s}unuu|s~ssuzzznzx~}ru||}n}}rzznsz{{us{~~|p~oxs~wt|zrsly{zw}vW{q}}wq}|~dyxvxxxzpq~vo|r}xjt~||~{wxv{zsy~|~x|{~w~mf|rwwvn{}yx|~z{yx}w{{|ut{x~{r|o~|ut|{i{}|xw{s~~pru~tt}kxh}~|yx~|y~vszx}|~zvy~{x~zrrr{{|}v}}|nzx}z{~|}y~z|||{|{ss}~un|{tw}qq}vz}wt{}|~}}zvz{|{w}v~uz{x{}}~e}}~tv}}tz}zy~yxz|`|}~|~{}w}|xxy{t|}xz~{{|czx~x~w|t|}}||yyqyo~}}uv{{wt}}y~}~lv|vx~}{ky|{|yx|~{||~v~x{pwv|z~z||zyz{qyp~ytp}zv||}|yzytx~~rqz{v}r}yok{y~ztj~yy|~vsw~zz|wzz{~}{|{~z{so~{t}~m}tyzwf}~zx{ntsp}z{tuqy|z{|p}v{}z{x~yw{sutyp}puuqvxq}wnnrp|zxy~|oyu{}~yyw{sz~y{{yz|x{z~o~k{|~v{d|y~~~wx|vlvy}}jyu|yzzs||}xyzt~|qu|rvpz~yw{y{xvxxzwxvtrzdxtfx|tv|zz}|~zvxo{k~w{|u}nzvsz}s}h~ql{onx|twtwj\}w}zxy}su}|yt{n~{y~p}pwzzry~xu~}|n{vxvs~|z~zvzpn|~y}wv|~yx{uzzpxw}ztyzu}|~pr{}rw}k}|kz}typxovq~}}zwqr|s~u|v}yyuz{vrtrlzl~h|}xlwry|vwn~}xfy|~zw{ry{z}ppq|~~uyvo}~|y|~{xkyzvy}~u{uzvvy{~vzds~}y}s~tw~{txt~~|{o|~rzsyj~{}yp|}~}ytoxtzm}k}s}t}s}}yyqxp~w{t~}|}lxww{rb{}z{znq~{xwt{zty~w}~}{f~}yxtxy~|u~qs{}}}~}vt|qu}|v}zzx|~zvUt~t~xsz{{|~x}zz~vkx}|vv{xjo~}v{wzywysy|xvw]v|{zzumz|~gq|}||}~{|uyy{|{wsu~rxyywts~{|y||~}yu~w}yyz~q}~z{xr}}xzt{vysyzx~}zs{}zxk~wxuvsy\~y{wwvxz|u{~uuv[ysl|~|y}}|z}w|~f}}}dj}y~}~c~tsys~s}|wvtiryo{u|~~}}wyw{y~xv{xp~t|uv~w~zvw~x|zzss{^zr{y~|wwh{~z~udie~}{suq|~zxu}x{yzq{{v}|r}yz}{uo}}yjv|}nuk||p|~}zi~r|owu|yxp|~wy}|tt}l}tz|zv|my|r{~wjhl~qv|xx|yx~~~~|yr~ow~{{}|xu|{uxq}rxr|xv}}zjx}vw|~}}~ugt{xx~||v{v{p{xuxvytxx}vzouxsrvyv{z|uhm~|i}dywq~|zry}vz~yyyjz}~kux~rz}|s}|zy|}hz{{~gypuJvwnz~{s|{h{o}~|zz}tz|}}~{~~wtxxxw}uw~t{}}rm}hf~~}}}~y~|}nr_t~{}yy}|wz|hzTpqw}|yz{~yw~zOsv~~x}}ooz{iyxcx|~~xzmy~xt}~wm~zv|yy}~z|q{v^x~|}~|}}}~~tz}mywxpv{{x}xu||zuzuju~zx|~}ul}~~x|~d|{osqf~}{{z}|}~zys|{qzuybxmz{|~~{ux{yk]{rw|~o}n|}fsryuy||y|xwpy~{w~y{~vqy~{|sz~qo}xvz}ys~{z~}yl~|~zu}mkz~~}}y{|x}}s~}k~~k|zcz{zyx{}xu{uy}{}}x{qx~rwxz}yyczyz}D}s|}}}yxz{ug|vyv|n|m~}vswz{rs}|}p~~wg|rFcwvstt}{|z~x}izxzttz|xw||ww}ywstsvs|zyxuzx}zs}}t|mwwwu~vyxszuwy|x|}xwwvz]rnxz|u|x`zvz|~uytq{wz}vw|vq|rtqn~~|p|~zq|y{{z}p}{z}w{dx~z}wzxyys~z~Svzxss~wdzw||bvz}}b{u|ywq||y}xz}}~}{xhn~{|{}`kvo{t|yy{wl[sv~|y~y{}~zs~g|ox~{fv}}tsutx{{t}|}wfz|}~}Ezvyyu|}~|~~}~sz~zykszx}||{~i~~|vyfwh}om}|`ws~yvo{pynpra~{ul}jzgw|n}{||zuuvrxmswvvrx|higpxspv||z}y|}{z|twtsnsuyz|~~Mu|~u{wonvxrt}yr}s]wyip~j^xu~~equzwz}_xqxCywzq||]~}zdxz~ex}\vn|toyoyxy\wo}`tqom|ntk{xx|}py{}t|w~lz{m~ozt|my}rzw{{|}{u~Tt}~ytwzt`{ut}n~z|{uvqvjzsfru{ztpmvx{qvh}yqjxts}}n~uaryzstdrywywwqp_v|y}wruv|~jnkxwf|ra|diZpu{x}owulr|}`{j|u}\p||y}~}Ssz^~yzjlh~|e{z||n|lv}~xu|~z}f~z}z~}}y}e{ov}~y~wv}t||t{g{|z{~}{~}yxx{tyt|x|yp{~~km|vq|{d~}rve{{vpk}x|v~u~}{}jn~{t~~s}~k~u~xzxsq{|w}wq~qh|qyvx{t~twx|h~}z{|yv|}zzp{~hz~|}v{w}ryq~v|{}yZ~|ls~v}`y}}~~x}yj||wy~{xz}wx}bm||}}{w}t{e|h{o{{|}{~^}zev{zvjxs}l{}|s{~~\n~|yyq|}~z~z}Z~zu|g~{krxv||||uivyzu~zo~|~{s|}|p{}{|yz{||~|w}|~}hqz|yvu~~vzpytz{yx{pzzyuwvt~}wv|z|tzw}vmwpu~vxyuvo|}{|w|x~y|y{vx|x|{yz{wr|wzxrzv|||zxxtx|thyzutzzzl~|yzwyuwyz|ypv{ywy}zqx|}{qx{}}uw~|}|{q|juji~}p|wurps~ywwvnu{xuuz}t|}{zg|yxzxg}}wws|{yvuxq}{nt_~~huytmiwyyu|{v{}t}zx~~~{|lkxlvs{xzyy{psztt|xzwov{|~|wyoqrt{txy}xx{|w}yz~{quy||z|w~~zz}n}{rxwyyn|z{l}||xwvryp~tvvuv}{nuzyy{zxqsvtzyz{u~~wf~uwqzqks}yttqu||zww}|wput~{pyyuv`uz~ywu|q}dvx|J}r{}~s|z|z~vt|k{|vx{{p}t{wqwr~x~znx}yrxrjzy|}~ytz~q|roxz{q|}~ut}~vzo{}||}}~~y{yq}}~|wx}krw|wt{}wy~z{}w{y{zn~wxyyxy~|ez{o|{{~~|yw~|vwj}~vpx|xqvxz~{{w~|w|}~x~}up~{y~}||xs}~|qxzlsxwxzyzz|pz}xz}x|}ry{xzzj|y~{vs~|x{|yw|mx|y|zxyy}y{yv{{w|zyt}o~t~u~{{szyxx}~ywws||zzw}szwxw|yqy{|}|~{wz}}v|w}~qz~z~}uz|b~y~hr{y{xw|z}|rv}{zlu||yx}xQ}y||wt{reyzvy|xzyxwr{|{~||h{l~|yzzzw|}pz~wy{}Oy|ys~{|~z|wsyr{~vw}~}u}~womy~}xv{{{~~or~muw|yu~yz|wz{y}~tu}}~w{ow}nx{}y~skt~{}wrsz|zv~||{|b{|}yv{fs~{nxuet|}}}{~x~ru~~y~wr{}iww}~r}|v|~|v}{{v}}}|v~{kq}}|qz|z~vzi~s~z~}w|~}}{xv{|{||~}}{|tyxl}}~xz}x~z~{{t~~z}~|{{}x}}z}|||x}sqb~t{twx}|yw~xuv~vyj|s|~}}y|ul|vvxrvzs|y~{}~{~}lw~xvxzjkv|}h{y}|rxz{f}f{n~x}}zwq}|{~yz~e{uw{utt{{i}|}t~x{|x||}s~zyx|x|z~vvyywnzr~x~{}}twx`y}}}~|}~|~]t~x}n{~|yy{~|v{u{}{xpt}x{{}{}j}|yuem{qw~~}}vy~{||}|v~xsyxz~}~tz}~wvio}x|~{}o}}}v}~}gvyh|uvwtuzsaq~zw~z{{{t}x}zwx{~si~tyxp{{|y}{}{z~~{{}ymwztz}}|{ztyp}ht|}}~}o|y}zy}xsu{{vzurzrz|vng|{}t~xo`iy|{~z|yx}u{}twv}z{sux~xxwy}cxsl~y|{w~|}~|rxwz~w|n|a|x}s|yzyvs{z|xv{qx}z~xmtu|vvwssy~yr||zyz|z|~xurvu}x}ziv}wvzrszry~||{|{|vk}~{u}~st}}{~|{w~~n|}}|~p||~|~}uzwxt~w|up|uyv}|tmmtuy}{ywz}|rzyuwwy|m~zz|x{|{s{|}x~y~p||cxstw||yqu|x{xiz}yur}zyr}uw|zs|{}x||wywwyt}~ytz}w}sx~{~qxr}z||{mvxw|{w~|s{{~x}y~zu}xyrwr|voyxuvywqz~~{ttr~|~y|vwx~|||www~|r|z}sz}}zwsn}~s}yphx{{xyqv}|}s{x|zxzww}|s|vsz~tz{|m~}y~y}vvu}~~vzy|xx|wz}~~}q|yv{}yymy~zzo~}z}r{x~xwt{w{}~rqt{t}x~}|~wuy~|{~|}suyt|~vuzy{xqwz{z{te{{qzyw}}un}~w|w|vswxhyw~zty|{hx|l~u||t~~t||s~}z}|ktu}xyyyv}o|}|s}{y~uyz{zz}~|||x}xy}~|~|~iz{~{~xvy}{|~}{~}q~}yp{xxzwt{y{w~}zzwz}xyz}|z{}{~}y~vv|}q{}|}z{~}z{zz}y}x~~c|xx~x}vzxvw}{~q}|z{zvwr{z|{zu}z{~|z{|yqvtx{{~yw}uw|uy{hzvr~~|y||}}{}{xz{xryw~zx|~w~wx}|}}}{y}~yo~{|}z|y}ysv}w}{r{{u}w}z~}zzr|~{|yv|z~tzpw~{r}~{}o{~x~|~tu~}}}~t{zz{xzxy}|}}~wzzz}{z}|}x|{y}{|vwtz~w{~~zzuz}}|x|z}~y|v|||~uz}~z|~~}zzyoz}{fqvzw~v}}|xr{v{~}~}{z{{}}z~~zyz|z|t{xiz~msztz||y|yy~uw{|wx}{|n}~x|~z}y~~v}~}}z}|~vy{{z{xy~qzs{{}~|~{xx}xz|~y~x{y{wtx{||||}~|}x}zz{{}}}~||ww}}u|{zwy~z}yuv}|zz}||t}||wkmq~zz|||kyz||}v}|zy|~t|wu{|{~{o|z{|}szq~{ty{}}}t}}{z{vpx~z{wzy}ry|~|w{|vww~||~|mx{w~p|w|}|~x|}usrww}~yz{ul~{{vs}|zytqysy||}~~|y~~y}~|{}tty|yzy|xyz~}w|yzvu}v~vvyyx{{|}{}s{zv{~z~u}|z}sxz}|{t|{vx{|y{zu{w|z|{z}||wu}ny{no|y{{}}|t|{~||}}{|z~v{~}pvqy|}~{{}{}y~~{}|vrsxy~}o~z{zsy|~|znz{y|zzs|nzyz}t~vq}}{|yzhw}mzymu}x{z{~z{}|x}~~|~h|v{y|wx}uw|y|y}y{zs~vz}{w|~{~}{y||~{}z~zwy~}~||sttzz|w{yu}zm{wx~^~s{{|}~}||{ps|jsz~|y{zxv}{q|xyz|ppzz|}svyz}w}~tvy}|}}zwi{{z{{}x}unxxxxwuyvx~u{y|z}{{xkx{z||xnwu|}~~z~yw}}xzz{{}~z}txw|~z~}z~~~y}{~{{{u~o}y|}}y{s|zwm|}|v|uvjy}yq|}{{~~~}vn|{{{{r~{x~{}x~xxnzz|z~|zz{{{}wvop||xy}~yu~x{ztw{{{|zvr~upwrw{}{{suy~{~~|~}}woz}y|uzz}}y}qs~}n}|z}y{yzv{|tt~~y}yx~{~~v}|x~yzu}|ux~{v}|zyx}t|z~{y{xv}s|punt|zo~z~~y{r~|y{{}txvn~}~~|z}~|}}{}~n{~}|yz{{jwzupy{}~~v}~|pw{{}t~zw~r{{}vv~}yrvvx{}z|{~z{iy}uuysuyqu{|}{|x|~}u}{{}w|~tz}||{|yx{v||zv~{yy~wzvt{t|z|y~j~w{sw~u|ux~|{}s{y~{z{sw~}x~{wyu~w{w~~{z{tx|y}~{~zx|t~zurxmq{{qv~{~~{w}x{x||xv{w|v|}q~}z|w{}||{zxw|dxyv~x}~{z|t{{~uwu}t|zfpzwz{}{~{z}wr}rx}s{~x~{yy{}v}v{q~tyr|}s{|z~{}~|yysp}}zz}}w{n|}y~~lw|}yt_}~v{tv{vv{x~q{vy}x|zqywvvqv||srwr{~{x_xtxe~||y]t~{qy{}zwy}sus~xz{y~zx{zy|v{{|}ly}~}z|vv|wq{ou~}|v||q{y{tw|w~z|z{|~~vu{}{y~v|rz||syzyypyj}wxy{s||~wy{~}t{fx|qrp}x|d}xxz~~pwxz|}yunz}pr~~}{wzxn}qq~|xr~lvwzqtwry}wrtwwv|r}{y}~zt}~y|{|{e{u~||tv{~zw~utnylzvsvmvw{tp}|r|z|xuxzm~~rkz{xz~{mzy{{pwzxyzz~yxx~v|~utovzyl|v}|z~zuzul}{~}}{~x{y}{}yr}xqy}yu{xn{}t~p{|t{{t}y{v|}y~z{|{u{~Xy~ty~y|rrzv{}tzr~|}nxi~~x}|{wxn{~p~u|~{v|}|}~]~{}}ju~y|||}|w{_~yyqy||~wqyv}}|{zwx{x|mx|~u~{xymrw}yw|{xx}|zw}q|v{r{y~|{~~|xzy|~y{z{vzus|ttx|~}o|}}|r{{|~umsy}mzwx~ry{{nyws|v~|z~wu~y~~zxy{{rxo|{t}}y|}~z|t{{u~}{ytoyvy~|~r~uyvztz{y|zx}{m|wyx{{yxvv|~~}rxwz|x}swzwl|kt}|~{u{}~i}~}yy{~}u}wv|y|w}}}}|~iywxzstzv|}x}x~zxqt}||~zw|x|{z}tyz{zy~m|yxvz}{}z~vxxz{z}wtv||zx}z~y||u|xx~}v~~q~}vy}zqwuz}{t}t{~|t{~zy{r{x~x{r|~yz~}}u}ts}|~~yt~|~wz}w}}vywy~}}y}|s|t|s}y}~{}{}|t~x}ppyx}}{~~{|rzv|{tw|ut~u}u~|s~}~z}qzktxyz~xu{xx~}~{zvwt|uyq}~xy~w~{|wzuy}y{z{{z~{~||w|vvy||zm~~~qtxmy{|tptx}}}xvyx{m}{w~x||{~|{ysyyz|}x}uzs~z|{uzt|}ht}F^|yz~}|xz}|js}vm}}y~}vu~x|{sbymu}ww~xxsu~z{vy~{|~~||o~vvyy}|{~s}zr{}x~|rrz{{~}z{ryx{|}zx|}~~t|l~~y}{wvo~s~}~m{v}zq}wx~wy|}qw||~~v~zz~x}x~}{x{x{}~}q|z|{zvy{}{{uzy|}}|~tw~s}|i~~wx|yyyy{x{}{~yq|^u}z|~{td{{}{s}|}{}{|vz||z{yzz}lv{zvy~s{^|~x~yzlv{|}xxz{wz~~vzzx{v|op}|tvy{zx}rx|}x~y~x|s}{|{zty|x|py{~~}~zvz|}{~|zzn|rzzs{}||{z|yz}zzzu}}{}{y||x~yx|}w}|}|}xy}w~~}xy|{}|}~vzsswyu{yww~xn|~tvz|{{{w}{z}}zo~xr{}n~|}{}~y|}}xwh}{}||}~}z|{ywwxzzz}t}x~~}ytz~|~{|z{q~{t{x{||ywz|}w{y{}w{|}|}~{~x}vv}zz{w|y}st|y}vx{~u~~{yw}~||~{v~~}{v~}kz}||{x}}s|sy{wyy~wu{|uz|}w||zw}r}w{~{|~yy}w|zy}~oruu||wsx|zwz}x|}}}vzwxxywsky|{|sw~{g{|wxzwwx}~}y{~wzzxww~s}~|||}{zy{}u|yzxyt~{ytz|}iy|nx}cy}}|v}~zyp}xnrz{mw~~|mfkw^|{tj{t}}es{{y|{p}{xw}pwzw{yv[{wywwm~{tx}{~syxx~vu~|z~}ljxzx{}ru{|~sn|xruxxs|~z{ss{yry|{}{sypyzy{{|z{}xy{zlw}oz{suuvzzax~~|w~uw}zmpuz}|pzrz|~w~w}v{|x}u~{z|yy}|t~yuyw~lx~n{|~[tx|bvys|nz}~|s||tw|vw~xw~~kzsx{{u{y}zw~}|qrxqot{}|z~tupu|{u}n{x}~wvn~{du||zw}vxuz~vpspmtyozttz|~uwzs}{~{mq{wxqe}z~~zxucy{{|{{{ttt{u{||v}w|~z}}{mxy}~zsyt}v}z|vz~~y|}~}~zyrm|~~~{|{{~}|yzv~y~x||tr{|zwz}wz{{q{|w{yxtiu~oqy{t~xxs{~x}s||tyw{~z|v{{yzy}zu|z}yzy}}u}wwy~||vuzv~z}}~z}|z{}|{z~py|{}y{}w{|yz{zz~{zv~|y~|zo~wuuyv~|~z~{o|z{~}w|t|wvz}ys|z||u|}ru|{~}}}{{wk{}v|{x|{{kz}{~z||rzy|v~ww}{kz}u}{}x|xszx}~}~{|v}~}p~yv}}|y}}yr}|z}uw}|xz~xzw|y{t~{mvzss~}t|}}k~zzr}{y{}y|sx{pxmw~}l||}ysp}||pr~~~|~}{ys~y~fxw|~{x~x}z~t|{~wv}zzxukwv}xy|wxu}~~}s{}wx}w{u~zr}yw||{~}~tz{p|w}{||~zzyy}x~~yv}~|u}}}}xys}zt{}zw{{y{}|}y}t}x~}~x}z|wy~xy{v~}|{z|~pk{~{}xuw~}ztw}|~~x{xw~z}xszu{}}zxvvxvxg{y{w{|wz||z{~lzzz|{~~|i}}|~x~}||}~su||{}r~{wn{zx}|{{p|mx|{y|~|}|{~}{{~p~}l|}}zt{wz}{{{pyzsxu}}|w{~|{}}thm|m~z|v~z}xx~vv{v}sy{vo~{{s|r{xwy{}n}pl~{yywyu}u|xuzz~wq}{wxvzzyyx|vw}l{~wv~y|x}vwz{|x~{w}qyzwyyvy~d|}|u~op}vu}}~ysjux~}}yxh}zyy~w{z|}u~|}z}|oyy}}s}y|uuuzr}{m|yqr}}{{tx~s|q~{~{g|xzvkxu{i|}uyy|x}z}{{}|vv~z||gzovw}~}{w|wwt||{vxx{u|~r{}zw|lr}z]|}z~}~svstz||y}uryx|l}w}|w|y[}w{lz|xywlvy~z{~~wg{|n|vl|v~u{wz~xx|wp|w}w}z|{r~yoy||}|~yur|n{yu}~fzozuv{|yswx~}wxzl~ywt{v|yuty}mu{u~}xxzx}~{z}zz}}||yyw{qy|}z}|z{xzvxZxy{n>t^u|x|x}{y~{r{z|~|x}~v~|y}v{}w||~wpx~zxn{truy[zv}|w}~{xx|z{~|xy~}~{xy}r|h{zwz}~t|zu}r~{{wz}}z{|~wxz}|yyy{{}x}}puy}{v|t~zxr}}{I~|ww{~|{|}yn}x~{}qyv{owywt~zt~}~p|t~vu{Zxs{}iq~x~v}qzxeyqo|s{}|uu{v{z{yv|uvt~qm}]siuYxqxw|zwor}}}s}sywu}}yzxzyawz|}|z~~t~wyycsny{rgwz~r}{{rw|zvs|l|zuwcstx|~y{{v}||||yy~}zwz~~~|y~x}~y}}}}yvwu~[||w}|yzs}y~wpnxl~~~~xx{uxzh~z|~}}|~~~}p}sy{||~usw{}zx{}zx}zr}{w~z{zv}yx~z{kus}v}z~z}~~y}uw}z|u{||{{v|y|~}~}x|}qynt~zy~w}zzoy~~z}{~{yztzx}|yry}~{}}z}}~z|u}y{{{}{|}}x{y}||y~~|zy{~twwz}x}}{k}{}zv~|}y~|x||}}xsv{quz{}t~wy{yt|{}{yz}wzv~~utw|}{yz|ux|}wy}z~{z}~}vw|zv}}yw~}{}|v{t|yy{s{|~x~}zw|rotyyuwxw~ytt|}x{zy~{~zx|~}u}xx{yz}~~~~~|v{xc{{tw{}~{}}~pz{xxxo|~}|~|{pq}{u{w|~y}{w~{|z|{phv|}zws||{~xpuuzzs||{{xyu~z|{n{z~~x{}zz{|rvy}~~{{~|yyvwwr|~{yj||{yw}vx|~|{z{{~wz~s{|v{}tyuz{w{{{xvz|j{x|~x~~yuuxy{|t~xozz}}y~uz|v|q{{|y|xv}r|q{|}ym~zz{kwwj}{~tyyzxyr|~u~ky~x~qvswmx}}|nx{zruv~{mztk}xy~zsrv~|w}}y~{}t~s}{}~lrvn||y|xzy~z|}~}zx||u}zz~z|xsyx~{yu|}v|z{}}{y|||~|tds|y}{zw}v|zz}myvxuzrx}utdy{q~ppt{~_w}q}my~~o~vx}O~~~|sr|ry|}v{zz~y}p~}|~~ky~|vzz}xw{y~{yxo{yt{wsv}w|~xzy_{ux}{y}{wh~||}p|}|qt|yyr~|}zx{\|dv~yn~|uo~}~Z}v~~i~|rd~}y|s}|pz}~y~sy{`yz|w|z|o|s{~xwz|uyyr}{y|s|w{{wzwyz}vyi|{ss|~W}}fzy}u}wzwy|s|{}vzsx|Rrrxw}~|}~z_tzp~{r}xw|uxv}z}l{yv{q}ix|{iho~wywuo{{~v~~xzyzz}~x|x{xy~yx{{|}|zy|~swr{z{jl{wy}}||}~~}s{uw}{t{zwrp}}}|wk}|{ut}}|~|gwvsx|}z{x~xw{{~~tq}}{~}}y{~|~}{w~{~|x}}}o}j~z~ttow~sz}xy|}z|tu}~}}uxn}tx{}}}~yw~{voy||}~~~|{zz|vw}{}xyxw}}s{{rxyy~xzzz~}o{y}}{}~qz|os{~{y|zr~{{x|v{{|~}zyvsz}yx~{zx~}z{rzyx{~y|~}~yy|u|z~~|}z||v{xf{stzys}~z}y|w}|}}~|~{z{zt|rx|z|v||ov}||zwi|w|wy}}v}}r}}|v{uq{~~wx}v}}{{}xzz||||evy~|o|y}ox~{z|ys~w~~{wtnvmx|z{}~}}}z{{|~wzz|xzsu{{~wy|~~x{x|w|{z|}sy~yu|h}}wxt{xzyy|vs{}{{zz|~ys|}~{}{{v{w}|{}y{zyu{|w|~~{z|}}|z|rtvv~~{||~xz}~{{zzwviwuz|u~vx~ty~{~~|~qu{y|}ovz~vwyy|x}~y|xz{}zvv}|{v{y~}t{zsxy}~|}y~j||{t~u}yz{{{y{y|zz|yyz}}}~z~zsz}}}~~zy}wy|v}{z{~}xyvzr|~~z{u}}}tz~zw|}s{{xwx~szxy}|y|}}~}~{}ztv{}y~y~|{vxpw}~zz~zz}t~zq{~t|u{|}y{}|z|}zy|}k|xtwvzs}sw~v~{ft{}u|t|vuzox~w}tt~{ktvzzzy|qyttlpun|tz}{z~y{~}sustr~}yt~y{~|}nyxx{lsx}~~{s}w|utyvx~{y~xytm~kux}r{z|}{uzz{uryq~z~uwo~~p|{t||~{yxz{t{yuzw|ohx|v}u}tfw~vlost|z}y}uczx}ywt}}qvzxsw}zw|zwwxs{}w|{~p{|~xfz|}|}{x{s~{v|zvw}wx{w{z{xrxy~~uzm~z~x~|~}qvvwzyv||muvz}nw|zzzv~u~ut~~j}{uyozy|xy~xt{m|yz~swvuv{~|wz{}tt||xrz{wqvwyt|\w}x~w{{u|~}yx{|z{~||{}}w~|||yz~{s|qy{{}tuxxtx}q}~v{x~}~y~||{|s}z}{|w}tzw~x{wtzz}}||i||{|zwy|zv~xz~~x{u|{wxz}|n||}z|~{x||r|~~~{~x{{}x}ypm{~}{}}}wpw|v{{}}pz|~~~|wy~|~zy~xz{z}|yz~}}sv|xyt~wrs{}~{pu|}zrt|~{mm|w}rz{vi|ux~zzx{|zxx{~zx~o|{{~yz|yzszxx{u~vwx{~{zy|}{ywy{{|{wzz{{x~{~w}~~y{xsyyyzzx}z|{t{vo}}|srw|vt{s}~{z~{}y|z|i|}x||rwx}yq~v~{wrv{y}myn~t}gtu~q{{w~zu~uz|u}{~x|x|wywz}|~{r~nyswy}{q}}{wzzzzxyw{qt{}}|zt~[xstzu}~z~{|zjw||}yyzyy}zt{tzywy~x|~}u~}yy{z|vv|xyzy~i|w{|~}~u~zu}{}~}um|{|yq}w}{z{yxyes}y~~zwe{~|}{|~{{~u|p}x~}}g|y~|s|p~|wz~yz~{}s{z|}qt~ystzy}v|v|||}|{~~|r}{v}}l|x||~w~~ys~y~yw~rtyyz{t{zzzyz|}|x|~`zzwuuxzzs~{y}v}~x~vz|}|xyw}{}w{|}y~s{~}{}{zwx{~o~w}{yp~{xv~w|{y{ts}u~|tv||{~~|x||}yx~zxzzy}yx}~zszzyu~|wzp|}z|{vx|u|~|}|t{x|ymy}|xv{yy|zv~yx||}xzsv}}}}zz|oyz|yxv~||{z{}{}zz~|z{zm}{x}y|w|x{jwzurv|zx|w~{|t{q{zx~yzt{}|k~n|w{{||{xtz~|}{{pt~zp{z~s{}~z|x~~mx}s}v{pu~yyz}}zqo}|v{|z}~yyy~{zy|zvr|h~}wxs~ys{x}|vm{{~v~}z~}vyy~}|mxyyu~||~}~|vy{}z{|{qz{ru~zx{~~~zz{|{oy~s}wx{v|x}x|zyyxk~yg{km{{{~~{ul}t}vrxr|~z{xz}zxzsx~|u||}|}}}y||suyz|{rwy|zw|}{}{~~r{wk~}{~q}}}y}y~wp}{~vxo}y}xz}|tyzt~dy{ru{xt}w{h}{{{u}}z~|u}~y|||z}}{{{}{|xtzz~|{|tw}|w||ut|wyq||}zJw~us}uz}~}zs|ygzuw|}y|hy{zzvg~~vwv}u}|y}t{bpzwt|{}xq|wwp}d~k}~{yn}z}~|~v{x{|z}zzyko}d|w}znuv}vx|x|~}y~~{zwu~yx|y|ury{{x|z|tvxy~z|~w}x{v|rz{r~x~}yt~t}{|{|vywx~~t~uz{||}m}xwv~z|{|e{|wzi~}txnUum~vs}{]z|~o~{yx~sx~{w|z|yv{n~~yv|ux{trzwyr}zt{~}u|x|~v||{x|xw~vuv{{n}{w~yiyyzp}~||x{{tv}fx~~~_}zz|~qw|~|zu~w}{xx|ut}t{|w~nvv~x~q|qx{ztzs|}x}}yqz~~z}z~x{xx~}|}|wt|v}y}w}||Hy}x~~x~y|vng|{jyspwv|~rx|~UxZu~}~s|{ynztt}wvi}|z||~{~zvu~x~|zr{zuwdzw{ujuzyzywv{suy{xwxzvxzu~{|y|vzz}s{vo|ttb~|{y~doy}~xt|zwx{|xz~w^{xla{n|z{qu}s[y{|s~|}sr{~}~oy}t}yt{{|zwz~}v~uz{vg}w}}}~}x~|suzqsm}~|~k{|vd|||}}x~qy|yY}z}|~}}x{mr}zw{y~uo|y}{zn{zlu|}|zsvwzz{{~oonxwz|sw~yynt|x|{}z}~}~r{}{y|}{|}~s||||}xzw{~zyn|ouu{}|~z|y}}|}~~zunx|yr||wsx}{ux|~{}{{{|yyy}m{v{}z{tz{tuz|bxzt}||z}o}}z|{{wtz~yzzx~rwwxl|u{~|y}}uunyy|xy}{vv~}|zz{zpsvv~~|~wy~v~}x~}|vxz}yrw}~{|w|orwtywwxw}{~|yyp|y}y~u|z~|}}j|yy}jw|~y}xw~ztt`}}}x~c}y}uk~|y}u{}~zw}xykzy|}xz~|~~xntx~}~}~ztssmdt{o||}~}}u}{oy}~wwu{z|q|p|}awx}{w}{}xv}s}n~}s{x||~~zz}}}~xryx}y~{r~zz}ywz||~|}{}{~~zzvp}tx|{hzx}}q|pyo|~sry|y~{zz|}~}{m}}oyu|wmw{z{t|}{y{{}ty~|x}n}{lwyz|}xy~zrj{u{y~}xn~{~{zw}~z}rppz}zi~}zwrk}}ztv~z{~|xg{}|z~~vy{tq{xtz{rk}|}xyy{ryzz|iw|sy|worry|}v{}}r|pzw~z}z{lv}~x}~pw}~~~||syux~zzxz}w}~|mwv{~v~|{{y~zzz~{w~uq}~uxo~t{~wyzu~z~z~}zyv}{x~xw}srytz|y~||zjz{vs~|{~||w{}|stv~yrx}zz}u{}sr~zs{psvxry}{|x|z~~}~uy~yr{svz~|}|{y{yu~~}zws|~~z~|{}|xx{|y|yuv{~}}xy|uu|vz}~q||xx}{}{~wxwz{{}~u}w}zq~yzw~x}~{x~s{z||}uty}}z}{|yuzyr}yyw{y|sv{x}ut}~y|w|}vwxvoxwyz}{{yzx|z{~xszuy~z||wz|x{tw}|z}}{z|z||zyu{m{~}|zz~}y~||y{~|wwt}}x~~}|r}~{{{~|}~}r}~{yx}|y~~~{xry|wlzyy}}zz|ywzrt{}}tw~xu{s{x|y|x~x{}~~s|y{rs|wxyt|z{~ys~u}z{{}{wy~}~xs~sz}v}vwyuzzuxuu{x}{u|wxvxx~zxw{~oxozrz{z}r~}vz~~~xo}}~x{{yz~xx{|z||u||u~|{{w{||szzy~|u}w|u|{|yu{u{oxuxw}|}}{{|~zyy}z|t~|}y}l||v|}|uzx|xo|~}|zx{z}~|uy~vvwz~|{u{||sy~rxwx~}y~|}|ryzzyz{{{w{wy|{}wwx{|yuxz~z{~wywzvt~qyv|z}vsx~wyxx~tuyz~z{w}{w}~xzzzrw|}ww|vtw|{uv{xl~z~}zzt{{uz{ysy}~xs}nzz}xz~uy||}zst|{|~~z~{ykzut}||u|{yw}x||||z~|s}su{|z|zvz{vyrs}~s{f}w~}}~xw|v}w~~{{|{z|x||{}|f{w~yw|y~z|z}|y|z~z~{y}xzw{}|}l{y}{z~v|jv|y|}{vnu}u~{{{v~z|}z{u}s|xyz{zvjx~~v{|{xz{s{y}wvrtvx|z{~{|~|pi}~{}}|z}||~{y|}~}|vwX~y{z|ztx~~v~|qay~y{|qyr}|}}yx{~}{p}}y}z|{yzyxxs|}}|t|xwwtu}|}|}}y}z}||~z}wq}~wsvz{uu|}~x}v~yxcst~q|{}}{}{~zq{z|u{vy{~|~|w|{wz~|pyr|}~~~t~x}y|}w}{|sw~}k}{yytu{rv}{szyz{|~v{|yvwpu}{||~{qyy||tx}pyy}u~{|}{y}y}}y}yxg|zx{~wy|~~uwvx|uyxpz~~ohv||vz~~|mz|oyws~~~p~~wp|}t{{z|uwu}u}xy|}v|w{{~wx|{|ww}y||weuw{{~vz}ux|~xyozzyy{~}zv|~xr}~wx}}{z~~y~s{u~|zwzvq~w~{zr~yqqyg}q|z~uz~oyvvzxy~wyt}t}uyqsv|}z}{|||yzyt|xz|xw~tzry~}vy}yz}yyz~r}|qy{w{t}~{uvp}xzxwuyu~zt||zu{z{owxzqyxwwy{ww|yw}tx|t}}zzzqw~vyzxtryv|xz|wy{{x{}|v{}~{u~tt~z{}x{z{~vyzur|t|tvt|{qv|o~~~|zy~{jxz|oolw|vyzw~~v|ry~~x{}zt{a}uzywr{wxs|~~{{{p}xy}yy}s{uyr~}r~vzwx{y}oyvr~q|{zu~{|xyn}vy}yw|p||xtsq{xz~}ryu}wn~z|vxyxylz|xzz{uz}~yvuz}xzzvyxx}z}zwvf~zrs||u~z|}{~x~uw}z{{{~}}~~}z{z{o{wz}zyw|m|{u|ptwxu~w{}u|z}|ww~syrzuwuz{s~v{yzr~u}x{x~~y{xvzp|~y~|x}r|}y|{u{~{{wz~~z{~|x||{{zzzqkz~~|~{||yrz{{}~yy|}x||xz}}lxu}x}{~~zyw{zw}|Wz|~~~~}}}xzy}|wr{|}~z}}vzz}v~{k~|~||wx~}~|~~~}}xowzzz|zyw||~}}~~~}zyzyt{y{}{xz||s~w|u{{}zuv|{{wve~|{x~}swv|s~yzz|v{{}u||s}}~~}~~w~xy{|}~o|zz}|g{~|v{rvhzyw|z||y|{rs||w{w~u|xxvro{~{~|~vv|z{~}sv{}{||~~v~~v}|w~i{|{~{xzx~yzzz{zq~~||n|hk{zq|{zyw}}}||yq}|t~mxu}|}{r|w|qyuyx~{w}}|}im{x{y{{}x|y~||}||}~{fw{z}xzz~~j|{~{}tz{|n}v~j~}y{tx}}pyu}}~||v|wu~}~v|~{{{vR|~y}~{}}}|q}~iwx{}}}o}{yx{~n}|||~y}m}xz~y~s}{~~|{x{zn~|}zx}{yx~{vv~z{}|xw|z||v|t|}|x~{~xst{px||{f}}|w~}zug~zx||yxd{|zx}~tz||{qs~y}wy~p~yvxv}zx}y}|x{|z}|qz|{|kvwvypuym}qx~~v|~qz{vyyyywz}}t}{{zw~{}{xs~~~{{z}~y|{w{w}{}~{|vu|yzyzu{y~xy||}zz~|yqx}uzd|z}~{}{}z|{z}v}||w{z{y}xy|z|{su~zv||zsv~z{sz}zc}}xxuy{tr}z|xuv}{}}ww~|}zyt|||}|{{}zytty{}z~z||w|}ozsw{}x~{~vt{}s~||ztz{~y~y}}v~y~~xy~t}y~yx||}yvq}xvtzZ~ourxy~w|w~~{rvy|qx~|w|{ym}}z~zywyy|x|}vwv}~|zz|z}|xzxl}z}{u{ps}y~}vxh}|yv|y~|zy{{~~yu||{~z{|o|}v~{yctvx}pyzv}ypq}{}~y||}szv|r{~qzo{~y}||~~}}x~vsz}ryy{{u{{{|s~s|}u|~zi}~|~~lsx}tx~}{y}~t|{y{}ux}uvyytb|u|{{}}z~|zvs}{|}z~z|||~qv~~{{}mz~|~{~~t~tovxt{z{o|k{|wx|~|zz}y|v~wvx~~ww}yo~y~i{ovt{ys~quy|xy~}z}v{}yz~{jtx~~}~~wou~|x}}{{w{zz|lvtyy|{z|zx~}yv{p|yurw{~}pr}y}wly||~x}{wwrwv{Sy{vz~u}ysxy|{uy}|}}yw{vsvz}xyy~s{~{{~{Ry~{{x|{|y~yz}{z}pxtvm|t~zxww{yzv{xz{}zxkyszx}yp~}}xun~|}zjx{M{z~||{}w~su~z~u}|}z{vyz|xyprsy{xw}xk{zsx}y{{xzx}~}ztvu|~yxyv|uyxt~w|yvz}{|{|yzon~{|w~~}s|{y|zxyysnwtxzyzury}p~||zrz|zwy|u|{ww~~x|nzzwowz}|u}z}}wwxs~zxuwzgv}vr}xvw}}{~~xx}~x|}nxxw}}~yyuy}{n|tuy~u}}zz|v~wp|v{~jr}|w}s{~{~|{z~txsi}tx|{zxt{~w~~|{||w|{mv|xz}xu~u{m}v~wzz~x~{{z{}zpt}}}y~w|uuy}L|su~~~~wv~yxpq|n}ryxr}{}xxszxby}yxpwzm}||uu{zw{~{|||zx~|{|{}}{v}~i{{}y}||wlpoyxyyw~wz}{|{uyx||wxy}~}|p}~~yutu}m}}~m~ztzw~}{}~}to|{}~rxx~||{zt}{w{uy|}w{}ztt{wx{uv|}w|mq{yoz|x}~x~xy}yz}~}x~}}}|z}}|}{|{yzz}sxxu}{{|~||~xrw~r~w|{z}~|r{~mw|{~y|w~xv~}|o|~ox|{}}|~xy|}}~z|v{zyr|{}|{uxv{vzyux{}{|uvo|~{|}{}||nwvw}|~}}zzx||vzi~|x{yw|}||~u{|m|s|yzw~x|o|{}w~~|~{r|zt{{sy{~t}x{ux~}}z{}}nuw}~{az||vx}r|~y~~~tvs|}}}uv||zwo~}~v|{}}x}~}z|t}}}t{n}n}qzz~yz|~yw~vxosr|y}~zzs|}{ztxz~~vvzztbzu}|z}}|y|}~iy}}trt}{y~|x|wy}{}{y||{~~u{zyy{~}{|ty~~uxy|{wu}|z~sx{xwt}~~|y}}wvx{{|}z~w{yz{~vr}w{||zuxrx~~t|~v{~{pzx{}uz{j|s~xuz{}q|}~~xx}~{~~z}}}}{w|~ty}}zu|{z}}|~s~sz{i|ryy|h{}}zq{|}|}~~yq{{ux}||||{xz}|}}~|~y}z}z|xx~uvpw~~x}r~z~y|xw{z~zyo{xw~w{v|xz{~}|{|xqvw|yy{vty{{|}rv}|vx}|wy~~x|}vzur~x}qp{}|tyv{g}~x}}v|}}~}xr}u|wu~yyzxvzx}~qvy~{|uxz}z{y~y}x|~~t|}|~uxmr{yvyszw{y~}zxxvz~~l|syw}{vzy|n~wz}|~u}|s}}}rvr}zyzyyun{y~}~}}|xxxvx~||qxw{uo}w|x{}ww|xxv}x|ytz{w|tvy{|y~w|xuyz{}wz||zrx}~{}~y|p}~~y}}~|~|yy}{{}q~~{~|pxz{{}xrp{~~|w{w}w|{{}x}~xx~}px~{ywszy~qsnts~}y|x}y}yys{}wyxwsytzz|s|z}xz~|y}zvqtpvwtyj{y{|uk~}}qzz~wszwzZzywzzyw}jz~|x|szvy|{}~{~~~{~xbzyz{yy~~|v||{{|}z~~|~yy|{z}zz}{t{xz|z{}y{~x|~xzz}|}{~z|~wtz|zvy{~~k{~|}~~}|vuyyxxz~z}rlyr}xyf~t{~{}~|~{|xz}}xz}|z{~{p}}isyz|s{~|v||uz}s}}~|~|{}q|sz}{xvw}{xx|yw{zyhx{~~y}z}}}y~vnrjuv{|w{~z|w}{}~y}}zz{zw|mys~yz|z}|||ux~l~{~t~{z|}smx}yv|}x~zozz|||vywr}{{x}wywtw}y}{~{z~yx{|w~}k}~z~{}{~qysn{~{g~v}|pyjy}zz}}|z~|{}}wzv|oz}{t}|{}~uxx}{x~||r{}yzxv~~ww{|}q||y|||svs~y|{~~zzzph|o}}y~|y~||}{ww|v|{~{zzuux|ty{twt}wy|}{~_{z}|lv~|pzs|}|s~xxt~~}n}{}~~q~t}}|z}sv{vw}|~}}y}{{nzt|||}s~~|}z}nv~~}v|rqryx~yz||v{}~{{~y}z{}qwyrzq|~}~|{x||}|z~zsozy|xv{|}z|~~xz~|}}}pzqx~z~~s}}}|}inf~yzx|~}y~}x}~{|~zw}~wy}~v|}~y{wy{ywvy|||{v~|{{y|kuy{y}yy}|we~q~zw}v~~|~~}q||~yz~~~~qp{{t|}}w~wu{wty}vvvyz{qvz{|{{|y|}~z~}wvyzw{||r~tbmv}z{|{{{~{{~wz{w||x}x}}su|xzvxy|o}}|mt~|y}{|y|~w}|{y~}s}~z}|}zm{|}y|xstxyyz{w|xx|}}{~}vwy{y{|}~z~svx{w|v|zvo{~vx|{zqzxxz}~s~v~|z}}ysx}|}~uz{{}{}}w}{wxv|}vz~~}{{}{}fwr|~}v{ttuy|~u{}~}{|yzyy~x~~~}vukw~{}yx}|mwzqz}{zy{x}~}zwzu~|~~w|v}{z|zrwjxx~xy{vfx}wz|zx}zz}vq}z~v|v|z}n|yx}zz|qz|~~|z|u~x}sx|}}{}tv|t|}zwu{x~t|zs}z||}vvk{~y|{t}~s{{txgyhy}xu~|zlvw~~~q}zzx|~pyy{w{ly}s|rpvy{|o{|vwy}vv}{r}{~xr|zm|pyx{w~x}s|{ywwoywt|~z{||yx~|y{|vt~x~{|{v||y{~{uussy~rzr{os{{j}|v~z||zz{w~u|y}|u}yzv|~x}wz{|w|~vs}}tzyu~x|rw}yw~vv}ut|x||ysvx|os{{x|~{{~~xr{x}|evp{vt}zt|u}tnstw}w|}}||tz|r~~u|zpxupy|~|vz}{|~~tut}{x~~|t|}}zxws~twv}q|{{|~{t~t~yz~v}sy~x{z}yu~yw{{ty}ptz}y}~~}~~w}||}z~v~|}~s}|{ux|z|y|}wu~x{px{{yx~y~w~~p|{}n~v||u~||y{{~}|}vym|~|~~~|rv{z{~s{{{}~xw~}~{{|y}{y~s}y|~t{{x}|yy{t||uxv{~}{wwty}{wx{}zuyzvvu|yzx|x{}zx{||yzu|y~~wuy}rwyz~zvyvyw{{|z|u{w{}~|xy~z}{|x|y}}|~{|{wrywx{{z{rx~~|v{yvzx|vu~w||{{x|z~||vy}sxy~w~~{|zzx{y}z{xx}|w{}~o}uyu~|{yo||w~{yz~~z~yw~y}ytzv{xwu|qw~{uzyzz}}~z{{}{{xu|}|}||{xx|asby|~~v~}p{}{z{uxzvoz|}y}r{k~s}||y|z}z~wy{xxvw}r~swx{{l~~z~z{xut~}}yuyyv}z}r~{|z}zty~~|{~u}rv}uwsynywrx{}uv}ys~t~|}t|pu{||w|}vv}vr{zzxoxw{}~y|uy}z{|ty}x}u~|{{kwzw|y|~w{~tz||~xv}zq}vty|z~u}w}{}{yxv}zt{|||wnww{t~{xy~{w}zx}|}xw|~vxryvu~s{{zrzi~yz}{is}|z}y}}{wz}z}~|{yg|}{ys~vtz~{ty~yv|}}xzx|y~{}v}{~xzzzz~w|v}}~{{{w~z}~|swxzsy~xlj^~x}s{v{yuz}z~}tz|zy{|y}y~xrzux}q~xr~st~}}{ovz~{z~}yup~|~~~~y}~}~p|ztwz}}yly{~w~wz|{y}vyz||wz{~uxxwy}xzz~z{tuz~mywuy}~{uw{}~|z~||l}u}~|qz~y~~}zzz~}~w|y~}}lu}z|~yty{v|g{~z}~t{{~~wz}~~vv}tp~~|wu||~x}t{f|t|owv|~}qr|uv~|{~ww~qrp{|xu}~}y{}sz{yxlwt|~}w{w}x|~}x{zvt~y|zyyu}}y~t|m~|nz{|||z|ur~us{}z}|{|z}yvi|||}{~~y{x{x~v}~x}v}~~vwq{}s||m}{{z~|zwz}|txuy~zyzz{~s}}uxu|zx{y}ww{{y~wiu}yw}~}~|{x~{zzy|~yy}w}z{~||y~~~|wu~z~xzy|~|{{||||vw{|w|xqu}{r||zz~~{yyxt}q~||{yv}~}{yoq{v{~}~||}~~ztxtu}z{}y}~|}}z|zx~wzux|zq||w~}|zz|zwxn|~|~w~v{~z||r|zz{n~}uyzztv}vyy~}|z~w}~|{xw~rt|wu|~~{wt~h{{|u}xp}~}yw}xs~~|z}v|tvz{x{|uz}suq~yv}yzywxyw~~vzzs~~z|zwu{vz{zsytyy~}|vy{zzzz{zzy}yv|x}x}{}~xz~vy{}wz{~|nz}uqvxnlx{}}~}~~l|~yxtst|wvz~y~wz|{|{z}~|xy}oxt{r|xryxyc~}{zxujxyx|}u|tyyyt|~}t~{pu{{x}nxw~|v~ozs}~}zxrv}~t}zxqzw}v~x~~xyx}s{owz{y}yp~|~r~zx{xnw|r~~}}zr}y|{zywp~wzqm|}}wz|{xw|u|{w|{p|}{u{txpr{xcz|y{h{~|x}s{}vzx~}wyyfzvy~t~|y{r~}w}uzz|v~q~}q|~tl~~zyx|v}|||{}{}~x{q|{||}|{v{ww}{~|z|t~xq}}us}}|zztzpz|z~|z}}z~zu}t~|n~urvz|}{xxo}zyxx{~l}}}|{u|wyx|g~~zzr}kxz~}zn|}~}yr~~v~w|nyp~{v|}xz}~xx}qzxrx}|w}}|v|q}|{xyzw}{x|z}p~|}xzuvqri~{{{|y~w}{|zp}}v{{}zuuu{}~wvu{z}||z|~|}~o~xyq|y|~~}{s}zqv{z||{ryu}o}v~|xuq{s}~|}}~w~x~|hzy|z~~|{wz{xt{vzz||z|{oy{{{u{vx~|xyy~|v}}vwuzvx}zuynx|ty}}|}}|~{wo~vz{x}}}y|twz}zrxztzk~|x}qw|{~|~zy}{|}zy}ztr}z|~|vzx|u{{s|v}|~v~y~~~{x|t|m~}x|||~}z~{w~pzxzz~}y}wv}tw~|t}{{rzv}{||zz{y{|||x{x{zlzzun{}x{z}y~{wy|{w~}}}zyvwo{{}hw{uyzy~{~||}z|i}{y|{|rw~zx~sy~x~~ztx|{v{{x~xwz{z{yxoyxv|}wx|}||}}t|~~tzv|{}~wy}zw|z|{~}~z~}|}uz}x}|yzy|z{w|w}~z~|w{w}{}|}{z}|z}yv{~}rz~|}}}~{t|~y}xwz}xtx~||{z}z~~yx{}w|z{}v||{|qq}w}wr|}z|s}{}v}}yzwz}|y~z|xvu}ywvuz|zr}z|yyzrtspfs}~y|m}}y~{wlwwx}{vr{~{||qu}~}}}}xz}}ys|y~xv|~xy{}~|w{}|z~|z~|wzuFz|xz~}txwvy|yxrtyz~yz|}z{tzztzw|~}{~z~zt|xy}ym|~z{uu~~w}{{}zy||txy~{z{y~}ztv{~yw~w}xrx|u~x}}}h|~|~|}ezxuwzwwl}|z|{zr}||}|}j~}tvuyk|{wxw{|q}}y|}q~x|xv}}~~u{v|}{t|xwyv|y}{{qr|~~v|{wz|y}y}tx}{t}|x|{zy}~{z~~}{{w|pq}x{v{{l}uzu|}}l~{ts~wzw|~{}{r{~u~|{r{||}{~mv~}vnx~}z~}ww~rx{~}}}s{{mx}}x|uxzvzz{|x|}||uz~||}x{z||~z~~}{wuy{k}zywzz|}}y~zzx~|p~w~~yw}{z{o|zs{yzxzm{l{~v{drw}w}s{s}uuvvuqyy}syz|yy~~yuw|ou~x}|x|zyyt|x~yz{xyxr~w{|wtqww}}}{z{|suzq~s|~xzyy|zwz}pw{lxsr}||pyw{z~~zq{y~yoy|{r{vs|z}uv|s}w||z|xx{vt{x}y~~s~}vu|{y|tt{{~qxxyt|wyd|vmwwzuxq|~vypx{t}}~p{{~z{~p~|uy{s}{~|wtvw~t|y~u{vz~}}}}u|qw|z~uxtuztvz{|yq~~{rvt}|{~||{~}vzv{yyy~uupv{}y{z~{~y}|y|}}~m}zyz{|u}v{|}xyy|~~w~wq|vy|u|xnxzxzx|v{t~y~puoz{{~|{xq}{x}}|}}|m}~wzx~t|}xz}u}}{xz~~zyu{xv{}ux||}~{|w~vzyz}yyt~w|z~p{z{~|zzxxsuz~x}}}zzumy|q|{|~}xzzsxwy|uz|z~{~vx|w|{|~v~}~r}{|~z}qvvqxz}}||}~z~}~~x~v{t}xwy{qvy{z}~{}m}z}y{|jx~}z}}zs}}{}}z~~zz{{twk{{~{{}qyz}zruy}w{{{x}w{|z|v{{vz|z~vw~}y~~}}vz{xvtwr|~zt~~~x|z~svwzxz}|y}yyt~~y{||xyu|wwx~zu~}{s~}y|}|~{{ztv|v}||}u~w}|wxy|{r}{{|z~~~}{zy~|p|wxz~xz~yxx{z~z|{{wywz{~~xu~z|ww}v|~|{|~{j}~~}|}zz|zxu{xur{~ztzz|~xx~y}~~yw~{|nh|v|z{v{wtv}{wq}}z|~~{{mxtr}}xwx}t{x|zy||txvzzotwztutxww{{~zp}xv|z}~ytt{~zy}yvz~}}rzu~y~{tzvzxy{t~y~}w}zv|{uxz{zxs||z}v}{{}x{z~yut{yx~uw|z|zuz}~}wxy~ox~|y~wv{p~v|z|hzry|}}wr}|z|u~yxs|wzzy~wt~q}syw|ww}|{i|y|yxpu}x~qtu|tz}}{}|t~y}xx}}yx|}|}z~{vyrzu|}wp{u|zu~u~z}rw~m{xq}y~yyw}xswntvvvvp~v}|rynyyk|}}~~~v|xt~z~s~z~xu|{}yu|yw{zxyzw~~{kzxy}|zm~~ysv{xzwz~tx||}y~~~yyyy|{z|}|{{{~~|z~d{{|~x{zpswt}zsyy{{qt~{~||x|w}{{vlwu}~|uvwzxtxttqtw~|}{vx}z{}vz|svv|zu{qywy}~ru|w|~s}vuvvlw~wt|ww}uwtyx}u{|v|y|vwyr~jvz}|ty}uw{|v}vzyywpsx}{z{}}u||x||}{r}|ypxu{w|xzyr|~vpzzs||wx~||z|v{}{v{{x}om~rz~{{}m}y}uwvx~{}y}|km}{}|uxy{~s{v~}||xwz{zzx~}wq|x|}wy{|uyyx|~pvw~{t|u~}z|w~}yw~r{ts}y{u}s|u~}m||~{wqgyzwzznyw~}wzqw{xt|zq{{yyso}svw}}xx~p~k~}u}w~zx}wxu||jzxrutzuzwsyx|tw{zwyr|x|ywx}{w}~}v{vrw{o|}xs}|zt}{to||~vzvwy{|{pw~uoswx~utvnzw|y}yv{|zqxyzsn}}}yz|{tbs{w{~wx}vziy}|uw|}~|zuvv}wuw}ws~~~}|yt|}|ty~x}}t~~xvuyuz}}lv|mtzy{zt|yszzxuz}{i~w}|p{ztw}yn{yz}yqx|zXycy}~t~{zltr}~uwv|}|rtw{z{}~{{~y|v|{~}~ysxzyj|v~qatshvuxw{||}v|qx|ztpszvc|yz}qz{zv|~zzy|{vwx{{stl}z}uw|{m}~z~lqxrqoy}{|s~{n~~xv{}}vywv|rwjy}t}wx~sxrj|x}~~vyzz}{w{{|yrwk}o}uyxzzx}~n~|nyzm~zwryx{}wu|~y}yrjwtytvmxy~x}~}|qn~yz}w}n|rqz}w{w||vw}}r|{{p|z{}ww}y{~q}sv}}~||jt~xyxvw|{}yy{zxz{}||x|{u}x}}uyxz|u|u{{y|{z{osy}vyz~ot|u{|f}}u|z}rzrw{}wz{yz}~qt}uyz}~z{~mx|w{|v{v|~~x|z|~yz|ztz{{}ss~wy|txv~~zyr}x~x|qj}zk|yvsv||~yy}y|~x}}s|}~~}uy{|x~x{|}|w}~{ywb~}x~uq{}x}{}}{z{yz{}xnwz{~txu~{v}{}}||}|n{zu~tyy}yyy{~v~lx|v||~|z~r{x|syzz}}{}nzzv{y{zyzak{z}~~yv~x}|wxvx~}wz}y~|xsou~tsy|tw{tsh}w~xz{z|ynxye|wtzr{{|~wu{yzz{x}z}~{{}w~yzv~}|||z|yyu}||z}wxfzuy|zxt}~z{{}|xz|z|y~}}}yyxw~}}kvzv{~~z~tyzw}z{dz{w|~~~y|||xu|v~vz~s{w}z||{{~r~~||{s|zyy}u{~yxv}~}x}yo|~}y}yv~w|}}}j{}~z|vz{{}xsz~{~~|}y{qww~|}t{}}{xv{Uwyz}}zruz{yy}{}xpvx}wx}}z{~}x}|yyr}~wt~}{~v{zxwtzz~ux{qdy|tz|x{{y}~|s~zrwy}x}}wy|[||tzx}u{p|mx}yzvo{}{v{y~~{|x{\~|~{}vxvtv}~yxyrz{~}}zzpwqjze|xzv}~|up}o}w{}|x~{u|wqx{wm~q~w~|{zpwx}w{{xu}srn}|{~}yz~}rxoxzz|{|uv|~xz}~xxs|}{z{p{{}mty~t~o{vz~{ct~o{zyy|y|}uv{izxt|rry|{x}z}{~|ly|qyuykwz{szx{~}~}}zWqz~zxl{~y|w|z~]o~zpztR{|rz~mxssxx|~{{u{}|y~~xyy|~~s~x}|rz}~w}qw|xy||~~zvx{z|{xy~qy~~srv}vw}|yvvz~z|~}wk~}yy|{y}r{|zsv}~|}ow}z{{~uzv~{rzyu|qz}~r{}xz~sx~t|yxz}rzw|{}|}z{z~|yy~whzzuuzx~}w~xw|}}}wu~y}xxt|t~wyv}wvz~w}|wnsxz|pxz}{}z|}||u}z~{tx|}{~yvo}u|yyxt~{u~}xx{}~{{s{z~zjt|{t}~zw~zwy|my|yu~{xwzy~uv~|wxpy}yot}|u}x}u~}{~|yu}{}}z{}x~zt~{~|txqzvx~{}tztwzu}y|v{yvqo~z|y~|w~x{w}~zz|{w||}~t~|y}}|~zzb~}~wrx|y{yyy~~rz{uu|~xzzw}{yt{{z{{q{wsrv}|{}}}~zyv|{}}xzxw~|{}~z{}|r~y{xw{uq|o}zxyzw{{qx||mqy{|x{|}|x~}~~}{}y|zy~xy{|wr~~vw}{zysp|mz}~z{|}ywrvsw~y|yu{x{}{|tq{w}y|y}|~v~{r|t}z~|~xx~|~{}y{z~w|m|x{zso|}v{{}}}{}vzzvz{|vwq}{~|}|~zo~|x|}{{x~zyurtwuy~|z~z}{x|ivx{{x{}v{q}~||}z~xv}xtp}}{{x|{{{{wwyz{znx|}p~|~}|z{yzwwsyx~}~}||zz|s|z{v|}m~vp|}|~|v}~yitzv~|~{~}||t~zv~z|wwzrz~~}~{z|vuzwxz{{t}xuz}{zzzsw|}y~}~xzyu~ts||qs~}{}w}ys{wwz|zw{x}}x{||t|x{zs~uy}|||svs}x{~||{vt~v}~u{{vwy~{|~yxtyz||y~|wz|~t~xz|{{}~szxs|~~vq~y|xrzxw|~z~~~}y|~|~tz}{x|z~z||z{{}~ux{x{zou}{v}w~|{~|w|xz}ww}z}}}w~uyz}|~|otzzv}|z|zvto||~r}x|s~z{yvw~sus{xwzy}yvyv{z}v}~uk{}y}umwzx}~~q{|}zv}w{|wyyq|w}~w}|||~}~{xvv~r~~|z}wx~yxs}~vzut~ax|~{x{x{w|x|sxx}rvwa~{wv{n{~y{x{t}y~{v|x~|}}wy~|}uyz~{yttzxuw|zw}xuvyuu}ruzy{~xu{yx{}|zzw}|{|z{}}zzwz~vz|{zxw{x~o~~zxm}|w~t|}|}{zy}z|{~x~}~ve{|woyv~tz}~~~u~y~}wx{w||tvo}{}yytx|}wx{|x}~|zxvur~}sw~wr|t|rx~{zx{|}uyv|zzyxyy||~|puwyty}vvy{~{wx{~|}{}xypv~y~r~osttv}~r{p{}ynvz~wz|{z}gzzyw}{}vzxts~xvx{}{v{{y|yz{_x|vru~x~z||z|vz{~|~~}~}|prpww{y|wu|{{{|z}~xwuy}{s|yzqyz{txuw|r}w|yx~p{y{q{p}{v}|{tw|xwyquyvy~v{xwzntzw{q~~y|{~wywz}}}vx|}vy~l~vuqv{{xw{{zwt~rz}}~zxzx|zy|wyu|wx{pvnvttrp}yop~}zyzzx{}w~~~~w|}{u}{joyvy{|}wunyzxxz|zwnzry~~}~zz~}}z}}y}yw{y|vuy~~}nu{_xxu}yv|~rfz{uxsr}zz~~zu~t}y|~r|d~q~kz~wv}o|y||zxyo|v{ww}}~w|z~}x{~|}w{x~yxv|up|~vz~w}vxwrv|vvov~|{x~zyw|syu}v}swxisz}it||\y|yz|}}y}i~yz{lvz~}v}xrxrtor~~z}{vzz{ywz~vzqy|}}t|xwZ{{xu}x{{xvtz~}}|ous}s{}}}zztwyutxt||z|gx{zuwzztw}x|t|~||yvyqssro}v{ortavf|z|z|}y}y||zy|x~wwyyvrw{{l{{z}{my{zu}vls{|s~}xx{~{m}z}}v{|{r}xy~mzrvy}|vus|s}~|qw|yum~szux|zox}{xvtz||}||s}xssyxu{xkyj~uy|yu|vzpx}gjuyx|izvxn\}}~r{zzuw~yr{{x}uu|s{xruwzsoty|{zzybz}e~{~w|q~ruv{l}v|~zr|xzruzh{~omquerz}{|z{w}~{|ms~{xy]}z}wpruqmm}vvo}{x~yizizruy}|y~{xmst~}vz{wyyuuy{r|}o|}~x~{wv|z{p~zox{v~z}u|zwvlsuuzy|{}}~x|}}y~yywp~xzupx{{zv~yhvu{||x~zzu~~|~|~~}s}y}{vwwz~i|zzt}x|yvz{z{|vzqjysx}|}yx}|}oyv}~t~y~s~xxv|}}r~~}s{u}nxy{un~{|ztju}{ws|p}{||{zzyv{{ry}y{r{{}zpxw|~{}~wy|rsxtxrt{zx|r|~|{rzwyu{|g~}zszu|z~vzww|{{~}o~x|}vwzys|||}r~qww~}{z~oq}|wz~zxyy|rx{|r~}~{yu~}~{|ttss}~zzhx}w|~|~ssqxztsyswvyyz}{|xy~~|{y}xqr{~}}n~p|~z}j~x}r~z~}z||yyx|~y{~}z|~~y}|}|~|v|j{~}zur}z{|x|y|}zx}x~{{zvx|{xe~}{|xz~{~~txu{yx}yyx|u{{vu{yt}vxyy|v{~z~y~wzk|||zw{wz~}s}x}{|}~~{{u|}x}~w}z{q~y||v~yz{xwu|}xiz{v{y}}y{~|{||wv|uy|vxzw~w{|{~}vtv|}~w}{|q{~wvso|t|}|u}|y|wzzgx|}||y}~~wr~w}y{{y}yo}oxy}nzvyw}zzxs}}~zwz{}~{xz}z~~pw~}}y~~p}~t|zus~xwzxv~gutz||w~}|vuuxy{y}x~z{v{~}||}{xxo|zy|yz}tw~}zy}|~oxey}v}y{|}zw}wyx}{~|}vrzxzxv~|u~t{tvu~y|~~x{{{}y{s}{v{{}|vy{|~n~w|prx{|}q}{yy|w|vy||}|yx{}{uuz~xq{~tyw|szr{~r~ezz{v{s|}~}vwpzyz|{~z~|{u{{vv{{z{n~}}xxz{xvx{}ow{~xxzs|wnx{{sz|}v}ts~z{|}z{yv~|~zrzzzz}~{w~y}s|{zr~xyw~w~{z~zzzz~~trrx|}~f~}~}{{}~{|o}uy|{z~fx||}{p|{yw{z{s{~z|zuxtm}t{~wut}}z{}}qux{txy}uw{{}}ptx{|xxzvw{ykx{~zy~{y|z}w{tzzwp|}yt~~x}zxw|{~|}|vw|yv|yzuv~}~~x{{|x|{yyzz{|~yu~~pr|uzz|yuzo|u{{|~}|~y||~~x~}}}~~{|~xy{{vxyvytyyrvmt~{ww}{v{}{|v~~~v~wwswx}w~q{~}|~|y{vw}~x|w}w~yzxz~|~zw}vx~xv}y|{k|v}~}zwi~x}~}wxx{{}{yz|}u|{}s~~~wz|{}}~z|vy|}|yzzz|z}~|~}wszz~py{y~y}~rrz|{zj}|yz{{z~}{w}}py~v||~|~}xs~{mz{~~|~vu|~qy|p~q|xy~~u||r}t|sz{u{~~|~}|z~tz~{|s|||s~x{{z}~}~~~zuzy{xxmy~y|{|{p~~wv\z}tu~w}|~~{qs}~t|x|~qvz~}|{vu|{|}|v{y}t~~|vw~||~yvu}x}}yzlxtr}{}z|{y{q|}zz||{}ctwz~t~zr}z{~~~}z{z}x{~}}}ryz}~||}j|~}|wxw{{~~~n{|r~y|}|}}s~o}}u{{|x}~~~{{}{{zmsvt{yzv|v{~}|x|c~u|n}{|}~~x~t{{}}j}x|}{{z{sfu~z{}~{}snve|x|z~z{vw}p~ll}|y|y{u{v{~u|y}y}zzuv|}~}{}x~zty~zv}|{|{|zyw}|s}wy~~~y|x{~yw~~|{~ty{xv}~yv~}~|~xz~~~wv}pj}w{xwysuv{vzvy||{~{zz||x{w}~|v{}}nz}s}us|y~{wy~zzvpwz}{~x~{~yx|~t||}jv}zu}}~|sz{}zy~qxnw}{v{swuwzy}my~swyx}vw{x}~{~yvw{|{~}~||~|w~qs}|}ywu}}y|~zs{s|{{}}||~{zs}gzzwt|z{{ko{y|sw~w{}{v{o}|{~x~v~y~|{~}y}{~|zzuo{mry~|{|zyt{ywj}}{}}~|~u}~ovzu{quv~xx{~u|l{gyzy{~}~sz}~~sy}xu}l|tu}{yx|q~}|}x}vzzq|{{u~vz|x~xx|ot}xyw}u|xyytyvh||{{y}{{{zv{{|~zu}tz}xz}{|v|z~v|u}}x{~}{{zyywzyv}}z}{{{z~}|t}}~~{zz|}yqy|{v~|zzzz~z~pv~z{|~w}|wx~}w|x}txy{v|s|zx~~z~u~{~}|~}|{z|{x~~{|}}|{~rztv}{s}}|||{xu{wz}}|zzq|~{{vyzw}{{{|x}}{vn}{~|wzz~nw~|q{zw}|yw{}~z|~s{zx{}r}|~}{xz}w~z{xwz|~{~yx~vyv}u|x~ow{z}sz{{~{xw{yxyzy~ywtz{}|t|wz~sx}vx{xw|z{}xwtyuu{{}{w{}{z{xt~zu|sx~u}~z~}svxn{x~yw{|}|}|~}z|q}}q|o||ut~x|v|}{|zu~qu}zy{o{{zu{v~}txvy{}}u|{{yqw|{~x}~yst|}z{z}z{~|s~|{xrx{~|v}zw}xw}x{}uy~~t{{v~~t~vyy}zuy}t|yy|}xus{yw|}|z~~stx|}{vw}zuz}}}yy~w~{qz~u~tw~}{~}w~t|~x}rwy{u~|}xl~|}{w||~{yzuv}{vz{|ztxyqw~zvx}}{wv~}xw~|x~}wqoy~}}}}}y|xxt|||{~|}u{|zu{{yyj{zt}xxx~zzx{{~w}}uu|~rt}zym~|z{~{w}z{u~~iovw|w}}yyw|~|{{nyz|wrp{||zzx{~svrt~}t|||{s|i{w||{syyz{zzux{}y}|~w{~wszy|yr}|~nxy~}{s}p^zyvwfz~|s{u{zx~|z{zvv{w|z}yr}wm~~svyxtl}~~wzwzky}xy{v}szy~fuq~{fy}|qzr}~{}yy|tq~|upzvwqm~u}}}yz{~|}go{y}s{~{}f|}sz|y}w}|bvwugpuqy}{l~f}}{xzrmm~xwovaMw~rzzpxz|p~x}vtr~{}|r}|x}w|}sx{z}q|ry[g|vz{x{r}~q~u{xo{{yw|}h~}~nv~}zxuy{y{|t|y}u|{xz{~lvzxz}y{~zuwqu}qw|t~zfsqz}xrv{pyN~uk|yvunslkuwwx{wy{{{~w{|w|k|{~hs{wty|zw~qzv}vy~~}{yz}zy|~~tzyuy}wzz|y{|t~x~t~{z|r{s}}z{u{{~x|y|}}rpprx|zy~~zqyw{v||zz||~r~z~{|us|zzzsvwy~|ou~~vywx||v|}}}zizvzxyxy}zvursvx~|}wm}zz|~mrxx~~v{uzxk~tz{}t}}rw~vzl}zzxr{ys|~}{z{z}zzx~{{x{~~}}~z}xyxv|t{r{xyx~z{yz}sixxttU|p{vt~vsezz}zzu}{xl{~~~tzgzz~}}|jzxzzx{|x|~|z}~~~yy}xxvrvo{vr}zuz|~|}zxy}zzu~tnyz}yy}ywyxzzv}zvpz|y~~uxt}y~zx~{~{otp{y|~|syvx|tzs|~n{{|t{vxu}ny}zxxyv|~}~}qzw~~|yz~ytt{z}x{}|{Nkx}sx~xzp}w~}uyx}}f~x~nz{|t{u~|u{iq~p}st}qs}n}w|s{|zzy|ys}}yq{v|}qwtw{zz}xrzq{xhwzxusxy|{xve{z~wv|y{}|wy{k|uy}||p{n}bq~yvw}yyqszc~|||wutvn|{y}~wt||ln~~~vvvypr}|v}~t~|z||xyy{|}{}y|rzx~|}ws|zi{z|{{|zxk{}yw~jwy~wt~z~}{z{{y{}t~xoyj|w~tex{x|}u}}}r|}k|uzx~vo|xz~y{{~~|rx|{xyw}}{yzuy{s|{}s{|{~quqpz~s{}}|||uy}h~}yzt~uy{w{yv|}w}}qw{tz}~|}~y|zzwxw}}su~uzw}}zv~zg{zt{}z|{m|z|}{|~{zkfy~{y}~~~w}|s{~z}{}{w{ynx}~w}t~|{r{x{yy}}}|zw}|~tv|n{{~}zw||jw~|xw~~{{{xxz[q||yt}|w}z}~}}wpmz|{}zzu|||zptv|~|}||z{szi}z{{}xz~}ti||ty~}{s|y}pw}||{{{yy}y}ztwpz|yxz|tzn}||t}v~|w{||~{xxsz}w~oqxyws}qy|zs}yz~{|{x{ov~j}y}~rh}z|}y}zx}mx~kyn|y~wyq~}s{|wtvt|ws|{}uw{~suw~}x}jqy{|z|~rwqy}wzx{~|qtt}{|~xtv}xr|xvmw|x{{r~ux{{wvtx{hw|t{{vn}j|{{}n~tn|w{zvw~~x~qouw{wn}~r}~q^z||wy}|~}uykrig}yqizxvs|xxrxuzoqmyzrmy|q~yz{|lo|tzvx{wwuzxjzutvx~r{|vyz{}xvy|zx|y}oyy{hs|wq{yhu{m{tvvqx~{~kwe~y~uztzk}||ttytnt}xvis}}dz}s~x|~|{|}t}yw|}xwxr{\zycryx}z|tyyx{}|}_v}uqy{tt~||~{{y~xcnuyyuyy~}zyws||{z~~}}}}ixuuwztzv|}{y~|u|{}rwz|v|vyyz{{~t}}l}~||x~wupsvw|}{|v}}{z|{}z{}z~r~xuxyy}}y|wrzwzwvy~~}xw|ytyvsz|jr~|~{{tx{}}{v|t}{}}u}|a|yyw{u}~|qr{t|}r~u~z|w~z|b|{~z{y{{rvv|xzr|n{i||wqvz{wyys}|t~z{t~~~]~t~{z~~w|{{~y}~y{x}y}w|zzp~}v{z{l~|tl|{~}yy~z|z~}qu}vx~}uy~w}{{uu{zvs{zw~u{ww}}}|k~n{}||{zzsu|~z{yrr~xyxuyynuwyytwrzwYvz}y}zltbzxy}v|~wz||ylyt}vs}t||}rk}x|vsvx~pr~t{x}n{}{kp|j~xz}ywxwwjwt|~ym}pw{iqzu}~x|vyyox|wxxfzyz|yupw{}v{v|tyr|t~}o}}}tqr{z{}|~s}}pzyvu|o{k{izu|}m|zsz~p|x{|tu~zyq~}}kyxwy|tusy}}zs{wpuwuzz|ys|||z~zosx}r}u{|{wjvyr~rfv}ys{|~z}|yulzvy|{|~{p~}qxf}}{xpzyw|{sy|vt~ou|{|o{|~~xw|{}xT{u~b|zu{t|u}p~{x{}yvwxoy~~|zn{s}|}uys|t|{s~zyyxu~|w~x||zuyQud|{zzk~|z{zX{{}p}r{r~}z}wz}y|wv|}z~pzw~yyty|}vx~vuxywyxz{xr}{~x|~}~}z}zzv~}zt||~}{s|w~|z~}y|y}|xutzw{u~~}|}ey}~uy~r}sqy}}|zs|p~|y|{}|xz~a|yy{~rw{}}y|~w{y}{{{z|~|yt}~x~{tuy{z{}vy~z}y}y}}w|w~|t{u|}zx~}z{r}}z~z|~u}v|z}vyy||yv~|x~{v{xwwz}zz{z||}{}v~w{{~{{u}~z~xuvzxu|yu{u~{|wlryy~ty}{oyp}{~}uz{v|}zszyy}|zx|v|x{k{vyyzwx}~}w}l|y}v}zy|z{{{x{}s}|v|{yi}|{|}o{~xr||wz{}~u~xr}u|z}ypsux}y}~{x{qyyy|yxr{~z{|{yw}}}{{vtwq~usvxzuu|yss~|l|{{tyw}{z}~yv}sz|s}zvx|txs|l~x{zqzz}~u{zorlym{~{~|yszr|uzyyvjrvwvysw}zq||s|z[}ryxwu{}b}{~ozy{|z}{t{x~z|~yz~{|zz{{{oz{u{m~wuyuu|{~~v}|ww{ow~~w{zzw|}yz}{}}yszzp}{yyymtw|vuy}yuyxzx|usv~wtt}y}wy{{mv~ywuztqu}tvvv}~stso}hw[rv~zw|Znvtxv|o|y}uf|x~vsv}f~vq}pywz|{zx|~{xypxzx~}yzy~z}|uz{|~}}stwr~zuzqwvyvu}}zumx{}|}{y}~mvx}w{}{ur~zuyxx}}zx{}xzt|}}z|~zxuvxy}}yzn~|}}~vx}p~~{s|zu}~ym}}|}zt{{zv|{yu}z{z~{~}sz}|yts|~}}~k~ppvx~zw}||t}yw~~||z|zqt|}y}vqww~uy{z~yys}qx{xuxmnywxsuxzxxwzur{zyvq|y|}zz{uz{~|{}w}yyz||t}x}{}z~vzxzy{{x|yzwnzxywsv}}{|}|x|tx|stzt|xz~|}z{~{~wzx~|y~|uzs|x}||y~|{u}yzx|zwvl~l}y}r|}uu~|w}w}~vqy|{{xzm|}nzvxn~w~z{{yx~|}t{yz~|sx|}pwxz{{|w}|yq|x|x}y{|~u{~|tz{t|zm}jw~~~p{~uyrs|to}|~z{{y|vz|y~{~}y}~~s|wt}{{wwzyzv~~~y{pw|x~s|~yyyi{}y}x~v|yqxzmryv}{|}~}zxo~z~~~y|uvywyv~}z~~wz}yynxxy~~w}||x~xw{~}s~|yo}vzw}u|wy~z~~~q~|}v~zy{w{z{y{|m||v|zz|~xxy~x{|u~}w|x{x|vwz~}}l|~w~xw|{{rz~xw{py}vv~}}v}tx|{qz{j|ozptuw{|}w}|ruyzty|zxt~~w}~}t|{y~{xwwx|rx{|ym}|{{~spu{w}z~[{v~~uwvy}vqxxw}{r~z{{u}~{|{uy|yz|ls~{x|i{~~tJ|~z{~{|w\zxq~{}{\xux~{yzots~zy||{{txz}}ynvkwu{}~~{~y{~}{og~q~~uzyh~w{w{ysx~{{tyy~vrzov|two}}{xtzum|||~x}q~}w{}y|{||y}}yzn}{sw{u?~x}yxw|{rw[pvwrvy|w}z{w~u}}w|zb~z}yx~|}}{w||gvzvx|wwsug}|w|wl}|yr}x{z~|~wx}w|xjww|yD||zzty{w{{{|zzq{n}t~z|z~v~|yu~|yxr~|~u~wuz|xyu}{{r|~xv|x{z{|{yz|~}vvt{rux{{vw{}v}}}v|}wtz{sx~y|kt}~uz}|w{|qyvz|xzx}u}z||~{}}v~zz}|{yuqz{~wxmwuxwv{vxx~}uwvz|v|y~{{v|y|~l}~}~{xuty{~qu{xr}yrop~}pyz}{v|q{|x{zt}u|{~t~zv~||sv~}}y|{{x|u~}vvz{}|~t}y|}x~zv}o{{y|vyyy~|~y|zxz{}y~|twu}zu~r~|z|tv|tyyy|}{}w|{rzrzyx}{p}}}}}oi~~|o{||wwzv}s}}r{}u|x}{w}o}o{{s~xz}ox{|{{xz|z~z}{g|{wo~n|w~wy}tw}r~xnww~z{yt|rx}|yy}{|wm|opn}}zrys}ysuzqzn{}`|~zuv|swnnoy~syry||}x{y{{lx{v|zq|v}{su|uq}w~u~|t}}|~y||||}u||t~{}on}~pw{xgyy~wxv|ozu~wv{{}yty~h~~~{y}|}|v{z{|yytx~ox~wy|y}z{~vvy}}wo~w`{{y|y~xxz}x|{z{|}pyzz{~{t|~{~yuu~xzi{rzzyw}quz{uvsy|xt~uxvr~}}yz|t~zvyz}u}y{xyzz}{zwuwzsus|yb~w|{{zzy~{jj||z|wt|z|~}t~ktyzrv}luzzyq||~tr}}|~w~r|{|m|to|twqqT}sru{u{zszvtzxvnvsw|y{||ry||uxq~{|{wuzv{zyw{ysy}}v~yvy{z{~~|}tw{uy{vs|vx{|~w~{r|y}|q||{o||xqvz|{}{{{wywzzx~{{}}}z|r}}y~{vz|rypxt~v}{yy}yy|}}zss|yt~z|uv}~vtzwxxl~z|{|~}y}upy~ywty}~x}wzr{xyvz{|x~{~z{}|zuwv|w|{uvstuz|~z}x|z{z{plu}yvwx{p|}~}|{}~{wu{{}q~y|w~k{vzyy~zz~nxxzop{zw|rw|}x}wx{}{w|{|~y~y|x{}}zz~z||oy~wv|}~~{~zz}y~p|}{{}~sy{{|yx}}u|~~zu}y|}~}||w}{y{vqz|x{tsszw|{~|w~f|vwz|~yz|{w|w|y{w|xxttypeyy}{|x|y}ix{|||y{yf{{|xy{|xt~|z}}u|~|}_w|{|z}~vrl~}~zv}yx~}}v}y|}m~w||{||z|}}|v}u{y|yzyty|l~{k}~~~||yr}x|ywz~qw{fszz~~wy{f|x}y~~zwz{uv|{xz}}~yn}rszo{|}z|}z|x|{}w~{~{|~}l}{yz|~}~tu|}|x{z~{qy~wxzj|{vx}{y}{||~}{{ut|}z{{}}}}|~zy~zquwy~~{|t}|}}p~~{ywq~z~|z{wx{}{~|yz}uw~x}}w{y~syz}{~|~oz~xyx||v}~{wvu}{zyn{zy|y~yt}||~vw~}~{|z{}{{}{vs~{~usz||w}y|z||}{x|uw~w~u}|vrr{{xyyvy{xxzzyzry}|ys}~y}v~}{|xy}yxqz|q~}|w}}x{}xwy|zu}pu|{vx{||ztru{}yvu~zko{v~yt{~wvs||ryqy}yl~|{y~w|y{y|}w|}z~}}yuxt}~~v{y}yn|yzz|~yxwr~}|tvu|z~}u{}w|vqz~z}wzurw}w}~|~z|zyrx~zxy{qs~w{|y}{vzz}q|xzzv|zz|zsx~~h}y}}|}~uv|xzttx|}}|yz|z~x|x{wx~zrs{wwxxx{uw}|{r}wyou{zw~|w{}~vsw|}xzt~|z}}}tyzw}yvywvzz{zm{s~umz}{xu|z{rty}x}|vy}}xz{{{|y}z}zy{w||z~|y}z}{~}k{x{gzxy~w|r|l|{u}ty~|x}vy~||vzxxtz{xrvwyrzvswyr~~|yo|tx|p~q|}i~xsuyvv{z{z{{x{|}|yu{}ywzk}t|}~u{{wuu~|j{~yw~y}tt{tk|qrw|{{zzxnrnvr{}lux{~{}|p{otw{|{zx~vxtu{{}w}zls|wow}}{wu{|p~w{~||uyuyu{~{tzx||}x}{ws~|||u|xx~{|w}n~yw}~qx~|xvut~|r~zyw|~{ut}rysr~|}|x~}yu|{tz|tztkoy}}y{~xzz|zyy|ts~}}y{|w~}vsz|{~uyq}{t}y~vozw|~|x{z~rzy}zypzz|wx}i`{~~|{x~vtrx~|zu}}uz|zz{u|}}oz}~|}wr{}|}}wtqwroxynuyutmzv{v~{~xz|nr||uy{xowzzymztz}~z{~~y~||w~|~{~}wyy}vuyy~~~z}u}u~~r~tzuxyvw{}~yn{yv~ywy|xoy}}ns{sw~o}z~yz||xo}v}||{~yzx~~rtwn}yy{{z~wr{x}~}x}}}otyy{|vwv{zy{~ypywwy}mw}~z{|vm}h|y{||tv|yx}vzxyzs~}zy}vz}xuvz~ozzxm|zwy}xrtw~z|m}|vxx}{|yy|y{yyx{|zyvryxv{t~qt~xrspn|zyxwyytqz{t|}x~znzso}yzwu~z{|v{zzy{~{z{}zw~z{z|~x~w||{s{stsu~~tz~{}vz{~v~{~||}xzv}|z{uy}{q~wzux|yy~p~|xyy}p{~xw~wwzu~~zp~xwxy}tx~uvz|~}yzt{xy{~{~y|y||~}xy{w~{xy{y}uysx|ru|}u|~v|wup~}~|}zxy}{vx|}xzzy}{poz|}{x}xvnz||u~{}xtz|yst}v~tx{w}zwt{{zz|wj{u~~z}zz}x}w|bu~yv|wyvb|sxyywyxyuv|et{||z{}yx}|||yz{~z{wwk~}to~yvuuyzy|~x{znyzyz|zxu|~z~r{u~|{}zwxz{~~vy{{tz|nzn}x}pyzyv}w{w~}~w|z~ygz~y}pzyw|{{q{yvv~~zx~y|ex|v|~nyw`Zqwr~||ut~wy|}~ppxf~s{tk{|y{q~uu~n|vy{kzt|uo{vtyw{}}}ywvv{lyszzum{||y}}{x|zp~||||b|{|ovvxit|z|ui||pev|{}ky~}w|l}vwk{|v|u{{jtx~~wuzv}|wyz}z{z~}|vw{ir||jzuy|qtmkvxzu{szt|hznr}~|yrezxxzwv||~~}wyyv}}ow~q|szty{|a~p}pvzy|}yuyxx~uxzzrq{qv|~|{ty~~}w}wz~~qy{}[ls}|x~~xkw~rzxtmyt|h}}}vi}x||}{~}y}}y{{w~}~~~v}xz~z~yz}}xwwt{qzwws}rxx}~}r{{|w}q{t{u{pyw~x~x~||{||}x~y~~{||v|w}ww}~ztx{}yx~wz|tuy}|{{~y}wu~zz}{zzz{p}|w}~y~zzw|~{|o}}{{z}x~~zwz}}{|ytvs|q{~z~{v~s}{|y~u{wzh{|}yv|y~|~}yu}xyyzvx|zztxxy}|~}y|z|zzp~zs|}s~{pu~u}|zx}wj~|}xwz{nyx~}|{y}{{xypu~~yx|l}qs{z~u{~|v{y~}ww}zzs|ytqty}{vz|}t|y|z{wwx}~x~|yw}yq}}q{~{{vwzyy{|}|{|x{wy|~o|~|{t~zt|p~}xtye}z{{|}|{|p|rk~{u|y}y||xw{|y~{yy{}xz|u|}t}{wz}z~{}{yu~yzz~~wy{zy{ys|zv~|xw}{|t|xv{t}}{l~{{|wwzzsznzw{|~yru}zy|{}xy{v~vw{}|~}|}~zyt~wzzz{|||x~~ssz{|}|{zx{qz}w|}r|z||~||{{|tvw}y|z{vi{}}}~v{x{zwuu{w|{~}}z}{z{{}wv}xzyw~v}{}}~~}xw{}q|uzzz}{|}}w}vu{v}{s~wyyxr~{yjxx~x}}zt}u~~|ws}yxw~z|{~}}zq}}~syyy{{}vy~zux~x}yw}{|}xf~u}|}sxxWpj{s~xx|qzyr|uquo{Yq}w~v|wvy~nyqx|ykyx~s{}{sp~zl~z\}wyt}r~zyz|wr}|v|sP}}{zknv{Qyx{wyr~nx~{|z}iz~ht{ywuv~{}~r}zzyyyzxsoxz{{}o{z{|w|}xu~mzzm}zxq}{b|v|xvzwpx|~~zux}{bw}`ww~vWw|~r}{yp|xw~}wq{ztvv}}zysCrxe~~}_|yyzfzv{||zl}w|q}yrtfu~z~}z}sx{xwz{uZr|}un~qzvly}|we|y~mpq}}yrv|ywnhyors{Yy~t~yjnwwuv{y}~}r}rz{wvyf|fgqyqpuwgyszo}}w|{zy~~ywqy~~{sx}}|}z~~vz~y|}}wx||}{qy~{xp~{}m~}~{~{~{~zy|yf{}y~}y}~z~rw{|~}}t{}o{|}|tp}v{yyu{{~}w}pyl{u~}yzy}u}}w}wr|w|}|~||bu{{|~{~y{{~|zu~{z~|}|or~|t{yt{|x~w|~}~~y{~z{y{||s}uq{~m}}yy|{x{}x||zuxw~xzu{z}{wn}swk}z{{|pxvww}{}||~t{~|{~~|zxtw}z}xzx|p~u~x}kv|}{}rv{t{}twy|t}y~u}|szov}tz{xzx|}|{|~z~u}y{y{~vy~||{}{w|{ur}zwx|xxz~|}}{||t~n{yvzx{{|yy{|syx}}zx}}wzu|w}v}|s|yu}vwxy|wuvr|~vx{y}ryxutuwr|~{~{x~xy|}sxz}{zx}~u}}}|{yw{s~{zyzxw|s~y~j{v~}|~{||z}|y}z}xzxyx{~{}q||zw{~}}x~xy}~}~|}~z|{r}t}t~yx|~yu}{y}}z{yrn}z{|~~y}lx{~~|||zzs|x{~}}{|{{{x|z{|z~{n{{}z{{yx~ss}x||zu|}y|szy~}~wuyy{zwz~yxWvyq{~{~w{{}xtxz~|wrzy{zr}y{uw{|y~wy|{|yzu}}}}wz{vt|{x{||w~y||wx|}|s|}}x~w|{|~|xu|}zy|s~{}s~~u|}oyzw}xz~uz~||v~~l{y~}~p}zz}zy}||y~~{}u}~v|rk{~~~|}{|w~{lzz~zzw}~w~|}y{}xz}}|wy|x~|{~~oyq|~v|}zutq~}|||s}zu|u}}}zu{{j{}ruz{~w|r~~|z}|mw{~}z}~vvpx~||{qzzw}yv}v}|sy{r}pqh|x}|}||w|{~|txy|o~zu}{}{|}~u~wvz{|}owf~|}|wv~povyt}zqw{uz~}|xj||}t~}~w~|u~r|~u|}xwwy~r}z~x~~xv{|{}x~syus}}xzuxpk}u|~~wyysw~sqyy~w||{w~xv}xxkvx||}v}yw~}}|{~~|y}u}uw|yxu{{x~ixywpvyw|~|rywxvzxzzzkv}|v}y|mht~y~wu{ot}qo|~~wx|zmu{uzzoytvw|{z}s{~y||~z~w}z|yp|~~ys~wv{w{wxyz{p~x}{wsux{~|z|otz{y|kvvr|u~}}{s|~{yv{t|x~}||{yv{hwx~}|~{}yyyv{{}n}p{zvo}xw||x~~~rzxu~xzw~z}}{z~s{}vvx{{~|z~z}|}yriq}|ort}z{v~z}z}zuzn}vrx{~~|~|{zyy{lw~wxou~qu||yznvx}|yyy~v{uk|~{wyt~{|zkv}vurpy{y{}z}yezt~zg{}}o~}~x~||~}wxz|x|~}}ux}xvwo{s}~~~|||||uxqr~y|{xwpz|x}qvu}{|~u}y|~}}~{~nx~|~z|z~{v{vl~{}|z}o}wy{z|~~x{||~z{yuzyx~~|v|~{s|{{xw~u|w}~}|x}x~{{~z}sy}y}p}{x}z~|wyx|s{wwz}w{s}{uz~yyzyzzy{~{vz|~|vw{|~iz}~z~z{||wszx{~|}xn~|{}}yxz|wzx{zt}yx|~|}xl~{mt}}|y|qzy}|xwzr{v{w}xy|{~q~|~p~swwi|ys|y}}k{}x~w}~|z~{~}oj}|x}{v}{{~v|}|~}zv~~y|{zu}x~{vwuzv{zsuwsutxun{{{|b{~swyw~{}{x|w~{x~w~pz{w||n}zr}{{{}}|}}}{}s|p}}yzyzrtzz{|v~wzm}{nu|}l~|v|~|~}yy{yu{{u|~}zxxwx{~}v{{x}wt|{yq~{~{{|y|z{tyzvy~z|~~x|p}}}uuz{}x}}}}~||z}t~w}|||~}yyy{{v}zy{}|n~z{vumyx~yq}t~z~v{yxlryu|yxuv|}vwx{p~zyws~|{vv|zx~q|zq}wzx{zp|w}{txx{nu}~|yw}s|}~zzvxqrxwx}}vqz~nt}}xyw|zxy|}uz~u}sx{{{zzy~|wyysp}{x~z|nuyuwz{|y|z|}{~~{}z}zwy}{|~vyrp~{y}|{p}|}z{zzyw~|~}y{~|zo|y|xypyvy}}wwzw{~{~~vz{yv~{~|z{{{x~x|ytxw~v~~x{y|z}xyw}}}|}}gs{w{zusu~}~{{~{v{}x|u~s{z{|}y{~y{xyyx~{y{}{|vl{z|x}y|ps~xpz{xz{zz{{wr{x{}}v}{yztq|}||v{xyz{vy~|z{y{sz{|{yy~{{vw}vzt}x}u~|wx|sz{~~wzp~y}{}||z|x{~}~yxw|{p{}~{|kx|}t}|~x}|z}w|{y{v{|z~z}~ytxw|xu{ws}}o|rvyzii{z~o~{~{i~|}x~zrw{{{|}~}u|yw|{zz}y|yy~x|~|v~|~uz~{{{}xri|uzty~}~z||v}o|rx{xwvw}~}~|{m~}u|y{~m||rzz{t|zw|~zxz{||}zy}w|{|zw}}|y{}w|}}}wx{}}}}~uoq|}x~}~w~}uwyturzww|zz}xu~zrzfz{zuwz|y}||}s~||~x{|u~~|~z{zx~u~{|{{~hzbya}h{uy{}znvwqp}}x}~t}sxw}~twvs{v~uux{dvw}{z|w|z~tr~ymvs{}ytyyy{v|yex{wz~}ywi~}yzu~t{b{|m|tx~|v|y|z{wto~||w|}wy{||`ex{||w{~y~|{qvyP}ys||}||}ozzxrs|}yx}y|~s~xwwx}w|v~k}{~}|yv}m~~}wx|{uz~|~~~~zj~xxs}|{w~~|y~l|~zz}|n~{u~cz}}z}rvu||}}||t}u~yy~k}y}vsz~}|y|}yxx~~z{~|}|vtv|~}}}}}yyzq|sk{{}k}}uw}q}t|{~wx}{zy|s}{vxsvv|~o}r|}|zyw{{y|~~sy|lxvxz~{zyzz|z|~}|w~}}q~~|w{}~v|{xw}}|z}j~o}u~r~zyo}zz|j}v}~{xx|yuxxy}~~}p{{zkvzvz|xkq|~}}{}~|z}}}~vy~~uqwju{|n}~}q~~|~vx}||~s|t}{|x|y|}~~{|{tz{}{}|wryw}xowvz~~wyz|~qq~k|y|t{sy~|}{{zzg}~{z~~zq~|s~~~~w~x||xz{{|{|}jknu||}tyl~||xo~vtzzu~y{||muzz~|}{~v~~~tz}{|~z}|ur|z|||{}t|p}qsrt~w|~y~u|z}zsxgztyr}zx~~~{m~v{|~w}{wuy}}y}{|vy~y{y}y~|{x|z}}|~}xz}wx~~~z~x~z~y~}x~s}{~~|qw||sz|suxvww}y|mu|{|s~w{y{y~v|zyvv~y|v|yxuyzv{pzw||oo|{ps|}~zx}z}|}ux|~x}x{{vyz~z~|{}u|}}~|||}{y}{t{~y|||qz~}y|{|~y~u}ovvt{}w~r{}yo~|y|~}y~z|~{|~u~~~wyw{|yz\ezyx{~y{y|}~rw||~{v}|y}vtut}|{|mt|}{|z}vw~}xw~{~{{}{z~zzv}|xvz}x|w~u||mo|~z|}}zt|{wxxxylu|y}|mwyww~y~~s{ux~}ozxuyyzyow}|yywzzvsyztw{}{~{{yq}~tzwwsr|vz{z}xs|zv||\}}|zxxvwvz||{|~||s~~zr}tq}t{~|t}~x}{}yy}w~}v}{{}{xtnvuxpz}}ozz}|w~t}xr|wqy~{~|w~x~~ty||{}t~~}|~y{~|yur}~ku|ty}xyst{yywwx}}r~s}{v{zv{~~xw}~t}}vzx{{ux}wq{~}p~}{{oyzp|{x}|}~{}q~u~{{|tyqvuxv|~sxv}rz}|v|}~z|}|~zy|{y|zy|yw{|suyx~{xzx{}}~|z{u{v~~zzvt||sz|y}z}{~zvt}zyqy}xz|}s{vw~zryvzvy|{w{~yu}w{w}z||mx}v{|y{}}~{w}z|vy}zz}u}tv~}j}t~{tz{u}{}}yr{x|~z{~w~xqv{z{z~{t~|~~u~zsx{x|z~{zu~vu~{x}zz|}z{{|w{~yum|h~pv}wyz{x|uzx{|yuwz|zzvou{wyz~t}}}z|{|y}x{{vy~p}}vy~~}y|y}||w~wzpo}~z{|zq}wux|~u{v}~izw}zyxw~z~|zylqz|xsvvz{{|z|uzt~wm}~}~vqm~~~x}~v~}}~iz}||}u|o}]t|{w|{z}{}x||~yzo{z|}z~ww}zxz}yz{{{yyyxv{|r{swsx|vz|vt}~wuwvtu|~{ro|x}v|r~x{z~}wuu|~{xyt{{{|~{}{u|||}zu}~vex~q{||||r||tz~xvpzxr}}r}s|z}x}y{{~}~|~s{nxzpxvysu}u{z|~v~yzvt}|uzu||w~~tt}y~x|ww~{vs}zrzyzkz~x~m|{|xwy{wx{z{xzlx||tyq{{z|}z~}}z~uwxzwyt|yr}qz}xzywmyuyyy}}{x}}{x}}{~}x}|}yr{z{~y}x{{zx{ttx~|x|w|}{|zo}mg~|~z|vxn{~{|t}xy{y}v{{xxxz~||}yyzsvs{~xz}y~|}z}f|~v{t|z|}|~}ty{}t{}{x}z{wu~{txzz~~y~y}~~ywk{yzw}}z~}|z~~|zzruz|pux}xt~}zz||r~x|vuyx{x|||}~~xzt}~q|wz}|~y}bxt}zy~|{~zzy|yvyr|}}|z~z}~v}s{~yzyt}~yoy{}y~~sxmyz{zzi|{y|w{unx{{p}{}zryy|{urzxyuszsut|{zyvzy|s}~~|t}|yzw|yxuyz}zzs~z~|}w||sp}zy}{}}}|}|{pzz||}x}y}gs}}uyt~o|~{yw~ysz|t{uuws~}xy{pytj~tz|y}zwz}w|{x~tw}|r|{zxw||zyv|w}zzx|ws|t~w}vx~z}w~xy{}{wvw|t}wy|j|zvzzsv{|y}}}txzrxy|trx~z}y~s{{{|{~px{w|z~pl~|tzysyyu|}{sw{~{z~~~z|}x|w}r{u~wz~y}wyszuyyywyuyz}x~znzur|qp}w|vz~|z|s}uqv{yu~txy~twvpuyv|}~su}{|~~zyyzy}{yyxv|zw}||u~}{y|{~}{~||{}{}z~w|v}~~zz}z~|~yxy~}|}|}y|~~~{y}~{zz}|}x}}{|wuz~|z{z}w~|~{~z~x|}{z~}}}~}u}{|~|~|zxzo||z{w~~}{}x}|{y|{z|}|z}|~{~zy||}z}}r{~{w}t~|}}~{~x{|yz~}|wz|~{zz~}}w}}{z|wz|y~|v|~}}|||wz|}{zvv}}w||{z|v}{||}|{z{~}}}}}}}}|s|y{{|||~}~~y{{}tx{~}zx}~w{~|~{}{}~}||}wzw|{~{yy|z{}}|wx}~yx|z}{z~u~joo|t}x}qy||z}yms|v~r}ly~~}}rr{z~{wupzwwoqw}zvuvqjv}kzj~ot|vv|x|gs|uw~~gzwwx~pqsgvy{zw{vv{y{yk|yuwrw~x~b{i~wxz|ob~}vyvvwmtvx{v}wzozxww~uypzynqz{p}quwt}~s}shupu|yyxK~x|wu~nrdt|xv{y}puzux}w{q}hy{xunttwwz~{zzztzhy{|~|xnsyizpn}}|v~v}{{|qve|kidy|zy{o|q]z||nxzjzy~xvwz`rkrv{dlzo}uvw}Qxztzu{y~f{z}}o~}z]z|iqrsxzhuyrsnlwxwzqvkw~px{|}{~u~}wot~]}{|rt|zhwjzttM}z}}{}y|{|z~skvy{}wwvz{ms}}x{{z~}|{z~oz}}|{u~uym}vyw~y}t}~yy~|{x|}x}zz}y}{}{w}q|{~xwz~zxqz||p~~}~vyv}}w|{|szy|{|xlxy}t{w~vx}z}~{|x{wwy||z~zz~||uwz}~v~||~{|{|{~t}vms{y~~x}yx{}izz~z}pm}{ztw|yw~~zyym~z}~qz{z~|}u||{}qwyw}{~v{}|~}|y{~~uuz|}y}uy|}wvwxwr}zxxy{y|~~|~}w|zyuyx~~||}yv{}}{y|x~}}}|{q~zyy}|{z~xyu{{~}t}|y{}|}~xx~}yz|{ww}|{~|}zq}~y|x~{uh~xtjy~~{|}~Ko}wmmxucltt}|jzq|}l}{{z~m{rz{{vuszyyu{zzxsvqvwo|||ow{nwvyp}iz}nuzT^ukyfy|~W}vzmyor~qy|}uuzo~w}yi}~~|uqtwcvyv}ttqml{qx}|_wynukx}xyws}||z|x{xtur{z}t}Wruz~wxsusy{uux}}z~}|t||vuqkqsyzvpius{w|yk~rqz|{twudkl}syq}z`{j{r~uh}}tu~zzvvzzzmz|~|{|sus{y~~xx{vwp~or}tu|{s|xz~{ziz~|{t{sy}w|ntw~vf|s{z}{^z|zsxxuxvpxu|}|wmx{~}h}{p|l{lnUw~}|y}{s{ywzzs~v{|zz}}s|rq}sxq~}z|z}z{{vwzw~vy}{|wfw~}v{{}uxq|uxyy}z{{ttzz}t~y|{~vw|{v~~~wxtzt~zz}}|u}r}xw|{|{y|uzztwy|}~~~|}x{{r|v{symr{|qs{s{~vw||q}h{{j|uww}z}{z|r}}}r}{m}}y|{`~~|}zy~xz}y{u{uqz|~}xvzzyzp}|x~vrz~uu}{}z{|or{{}zytzuy}u}vv~|szu|u~||s}p{|~xyxwzw|z{{|trsyozwx~}z~z|~|{zoxwu}z~|z{s{|yvvy|srz}u|s{x}t~{um}y}{}~yzn}m~{yu~z~x~~y{|n~{y|z|x|{{vx||w{{q{|zuz}|x}zz{tl}}}|yvtrz~szy~}z~}|zxr||wxw{}~}~oy~zzr~k}|xrdwqz~xz}wxz{uwz{w}|s}|yx~o~{x}wtyw{o~z~}{|{{y~zmzxxs{w|qh~}||~xox~q|}|wjy{~}|{suvr~yvv|~{}x~{sft~}|y|p~x}p|{zz~ztv|p|}z|~||~x|rs}z|}yyz||z|xz{yz~|zy|}W~vy|z||ryyz{wzrw}z|`wrx}|{{x{y{~u|u{yozu}yuw}{zs|{zt|}~zvvy~zx~}zzz}|sx|xy{{|zz|~x~{xz}|zwx~|u~~}{}vz~}}{||xx|xt|ryyz}~~{z{~{}m{{x}~zuz~|m}~wn}w{u~yy}z}}{w|~y|p~|pz}}|w|z{w}xtm~v~~{}vy{zx|w}yzz|z}z{z|}xr~yxry|~y~}tup|}|~{{}vz}xu{{{z|~}~}w~|z~{|{}{~}x}z}|z~}x}}{z|z{vs~}}{~{~ox~yy~|vz||}~zxxrzyz|}|z|q~|~{|yxy}t~z{~w{~~xvzzsy~v{|kv~{t{{z~vy~}}ysv~{|x{}|~}{{y{x|~w~~||sz}~~|{nxwtx|~sx~~}r}|wx{~{yw|{y}zk|r~w|~zw~z~|u}~|}z|~x|~}{v{z{|~{|vv}z|{y|~{{x}{y}|wh|~zuv|~{x{}zz}vvxyrz~yz}||{x|{|}}y~z~}zr|ww~zo{ruz}w}}x|t{v|~vy|~|yw{w|}}k}y~~|~z}zwxuq~yuy~~|}|xz{~z~zuz|{iv}|z}}x|}|x|q}}{s~}}z~{{ywy~v|w{wx}{zvt{}~v~~~{{yqqu~wqv}}u|{}|~}wywzwx|{y|}{z~q|~}|}|{}|~y|}}u}z|}}yu}}uyw~|~}|}|~y~zo|wz{{}{o{w{}y~}vw|vy{|uy|{~yrzuy~yy~z}o||~s{s|x~wyz{r}}}{y~{v}{~~~qy{v|ryyq|~~pzwz~t|wxss{yl~x}xz{{sm|}{~}y}}p|z~zx}zu{tnu~|k{{xu{w}q|z{{w}}y||yuzxx}}r~qwtqr|{n}v~{{{yys{|{v|v|}z~{s|xx~wzy}z{}~y}~}|}vw{y}yoy{|}y}uxwu|u|yyzzv{my~|{|w|~xz}vz|tyk~kwv|w~}uy~yvwtvz{s|}~|x~x}xt}xuxz|r~z}zy|vtw}|ww|qx{}}h~xx~|}xz|z}|~}w~}{~wpywyj{w|vrzouy~}ys|rxyz}z{{tpvu|{z}~~z~y{}~zzzpw}||{zw~}ruyt{trwuwrx~yzzws~z}|z|z{uym}|wwzv~}|wi}qs~{}yxy}{z|w}}{|tswtqtxu||y~wsn{{|srz~}|||}zx}m~vx|~}|}z|}}vy}y}|zv\~xk}|wq}~uzw}y~zuyvs{pyvx~us}~{{z~ew}z{}u~ydy|sux|~~z|{}}}yvuz~{}~{}~~{vw{|mwp{qv|}b|z|~|vy~zxvqxyyx~}o{}tb~|}{ywuu~}z{yz{p}~|z~{y{|}u}w~zrr}|~~}}|~~~}y~{wyowz{x|{|y~zyw|}}{{~v~}~}y{wq}p|zz|ws}y~~xvv|xzpy|t|sz|~{z|~~}|{u{qv|||xwjxufs||vyv~yv~~}pyzzxyqv~|}|}~|zyw{yu{z}nwwc{s{~q}{|{v}~x}{{wy{~~}p}~|}}xz|{}~u|y}}}xvrz}u|{v~~z~t}}xxst}}v~~s}}xvzszz|z{~s|t{yn}~~w|x{}z{vzy|{w~|xwzy~x~{z~}~vz}}{yzz~~zy~y}y~v~~yx{}}uy}wuov{z}{w}u~wszxx}{yu{zvk}{|}{}}tw|vv}}~{||ur~~u{wx~szvwy~|zyy}x}}xwx|}xx{{uzr~y~w}{zy}|~z~usu~x|~{ox}v}p{{}xp{xtzzv{z|cv}q{~|{|yuztw|}|zv}y~xx~u{}xz|}v{wyy{v|{yz|z{~}y{l}vtyyy{xwwvyz||{|u|vz}v~{z}{o~~v}{zrx|y{tuy|syyn~o}zwz~{~}||v{{mw}s}{y{~~}}y}~wwzq~~|y~}|w{zxz}uvx}y}|}|ngyz~|}~}{}y{~vx}{|{||{|}uyy~{|{~|kzyy{ww~z}v{~x}ty{z}y{|y~{{}~vn~x|w}{{w}}twty{{}~}|}|{}xx{rqyw}z|e}x~w}}zz}~|~|zx~|}|q{txltyx{y|}yv~~s}y|z}{z|{{kxzqw~|}{{}~~zyzyz{y|}z{u{|xz~~{}zy}w{y|q}~}~~zuzzju{{{}ztwz|{{}}}}zxyj~|~{|~|}z{|{t|yoz~}~t}{st|m{z|z}zy|{z|uz{tuw|~{w{{x{zrx~vwwrtxyo~||{z~~}zyx{~v}x~~}ywuyxx~z}y}m~t}usZ~}q{~}zdv}t{y}}uyzv\~ys}z|}uuw}~~py{~{{z}y}wx{|~{}v~{zyw~~xvn{ww}}v}z}}z~{~rx~xxt|w}yzy~|x~wxz~}}}u||yp}y~zu}~zwt|w~y{ww}f{}x|y|zu|xz}zp|yx|z{ix{wwvu~{s{~ut}|u|}~y|y|{{u|}v}}}zk}~z~xw|{put{|{~|}~w~x{y}|z}~y||}{||~}y~~u}~rw}}usx~p|v{v{}|{}zw|}sz{uyw|v|{ww}x|z}{ww}{v}{y{{~zx}|}~zz}}mxz|v{z|~z~v||wxv}x~koxt}||ywu{uv}x|py{z~t}yy}z{{z}{{zy{zr~y~z~~y||w|}y}}~p~zs~vr}~xtv|w~xxo{tz{|}x|wz{o|gu|uy}y~zx}}}}{y|x|wz}xy{zw}}|{x~~uy{z}}x}ut|~y~w}|{z{|z}~yy~}xnu|r~|z~||x{|~{xw}p}~{tuz~~}{y~~umt{{}||{xx{zp}|~|y|{{ys{z}}xxx{q{xx{~wv~ysx{x~t}{uwu}~|t}}zxv~}w}{}|yrmpx|yzy}zv~szz}}zv}w~~}s^t|j{q~}p{~}z~ww~|yyz|w|gwwm~uyzvos}yvzyr{|ryx~wutwy{}zpzrvzvxu|~~ww{xy|~sszy{yzc||ztx}xylf{yx}xx{~|}yG|x|}w}i|zmu{wy}{o}{|~~}fzf}o~|ny}y|ewrxm}wytz}wKyzzw}v}xu~~~u|w~~{}|zoy}t{z|~{{u}uv|}x~|{|}{{}z|x}y~y{}ywr|m}z{`uny{}wxtu~xtt{{x}s|{~{z|v{ry{~}}~wx~{u|}y~~|y|v}yyx|uqs}zwzg|}g~y{~|xy{z}~wvz~|y~}|wx|v||}vsqyrt|~~t}|~~|yvw{{|{{x}w|~vtut~x|zrxp|z|~{}xy{w}z}yzry~x}trr|~zv~m{|xwu|~y}u|y|x|}{}y{zpy|yyv~s}q|u}}uyz|z{t|y~zwrzyv}~vy}vx}u|{vz{{|~||}qusf}qm~y~|w}|s|}{xx|hzztzw{u~xy}z||}~~l~u|z~t|wwk{yx~~zz{~u}vy}zw|xux|~y~zq|vx{~|ypwu{u}||{~wucqyv|z}wzz{y}~w~~txvqo|}x{|~w~|z}~}zyt~x~z}~~w|~{vws}|y}ygzqyyq|}jt~z{z}{wzu~||z{}z~~}~w||{|su~tuv~{{||||z~|~v|~w}w{vyy|z~}||y~}{|~{t{wk{~}}wzxy~}v~}ws}|}ytw||z{zz}~}}}x{{}~zz{u|w{vy{{~wz}z~~~qv}vstxy|z~|zz|~|v|x{u|vywrzz}|{zxx{~v}}z}x}uo{{}}|z}~pu{z|zzzpwy}~v~{w~~{z|w~m{~|zzxw~|zzzzz}~~{}upx||{yywr}}v|~}w}~x{{ysuvzvz{}}~tt~u}u|}x|~vuw~{y|z~z}t}|vz{ztxwyzvyx|wz|{|||}}xxyznx}~}{~yzyxpt{|xyu~w}{v|uy~s{zzy}yv}}{xt}zy~{w~yvz~s|t|ys|wr~wz~{wzw|~}{wyvvyzu{|ye|||}|}}{|}p{{{x~yzv{z{|{s||}|}}zxy~zvzx{}x{}fvqu}}|vyz|{{~y~uzl{{yyy{{xy|xw~~|svx|{qy~y|wv{syq{hqsy}w}}|}y}|}r~y}{|x{||uzz{w|qps{{~y{||}}yy}vyzyz{{u~|}x}t}}zz|y{|qxw~}}xyouz{~ty{~ty}zz}vy|vzx{{{}z|yt||}u|v{vv}}xysv~}y}y{xt|y}{uy|x~u|~|~vy}yr~vpu~x{u}~yz}}v~}y|}zyt{{||u}|{x~}~{yxt|yw~|w~z}v|}~z~{p~tk{|q}}{{{w{}|xus||{n|||m|y|wv~tq|}uyzt|st~{|~{vm{}x}zzts{y|}||txxzu~x|y{tu}{{w|s||{|}}||~~s~|~}}zx|{wu}xz{{y}|tx|~}{p}v~|z~xz~~u{yzxw}y~u{{jwpy~p~y|xz}~~~nsu{y{}y|}|w^s{n}||yyv}{}{~{vzu}y}z{|~~|wt|x~sut|}w|v}z}{{y}nyxwz~w|zxw|szuy~|}{y|z|~zryyrtvn~z|uzvz{yx{}~{}~z{{}{j|z|~}y~|{zv{uyosy{q~}{{~wwzy}}zzx|w|xv|vzt{}~~~ptwz|}~w|xoyzms~~x}z||yv}z}yp|}~x{}~}vx{u|u{y~{u|z}yx|pxyz}{|}r{~t~x{{}yzvwwx~|{ww~}{}z}{|z||vvz}||xs|}|vz{t~~~{}trpxtyy}{vy|xrx|{|w}{z}v}|wwu|xyzx|wxts~~}|v}x}~n}zyu}xv~yrzxy~xzx~|{un||wuyx}yw{yvzz}}zzn{{zs|~yxzw||w|zxx|xvyyyyy{zu{~|w~zzy}l||vu|}}xt}yxb|~xw~}||h~{yx{}~y~}w~}|ty{wtxxrwvu|tx}~||vv|{p}~~|{}z|xz{}{xy||~}zzypy~xuxv}~vw|x}z{~zjv{}~vmy~}y}}x~{||z~x|~xz}|~~{y|{s|~}}w~~~||}xqtp}|x||~r~|w~|~{q~w{|w}{ww}zs{{{}{~{rg}}~}}{qw{~u}|x|~vyz|uzxxzv|}|ytz|~w{py~|z|uzx}}}}z}~zyy{}||u{{~}{}|~z}~|xz~z~y~{~z}y{~wzw~u|}zp~u}t~yu}xtvw|y~v{u}|z~yw|{{{{{pyyuz|~w{z||{{}~}w~z||~}vty{~~{puy}wzp|~z~}}{{~s}{}}vz}z~x{}~v{{~}|r~|x~yvxzezy{{~}zy}}~w|}~xx{w{{v{}{{}w}{ywzxz}}{{p}|wxsyquz~~ry||{{w}wyw}xyzxy}z|~vzszr|~~wy{zzz|ztx{wy{}xyz{}y{r~zw~x|zpt{x}{~uvwy~yug|ox}tz{tww~za~}{|}~}{~ww|wuzhv{||s}{zyyp|~ps{wiq~|~}}{x{uxs~~~~}|{z|xuw{kw|xy{w{W~v}t{xz}{~uw}}v~svr~|r|}q}s}}~}zu|xx~x}vrq}{~~}z|yw{}zvzu}~tw{z}x|{~|y~y~y~}zw{yt{v}xr|}|~zy{~t~z}}r{yy{yhq{rt{mwwnz|x}{h{{xx~v{|zvys}|~}wx}{{tuuszyjwhzz|}{nxqxr~|yz{~{wks{}||zu{y|~q}tw|p|u{r}wu{yz}}zzx~v}z|xv}yzzy{{w}}y{~{||}|z}z{}~{w~}um~||~s~zx~x{x|}sz~}Yz}{sz{ox}x{{tx~yyy|{n{ty|w~~|ymq|y~px||{yy}|~|}}g~yyz{{vzv}y}|{~~vz}xu~~{r}{xw}~|}xyzy|~s{v{~~~|xzy}z{|{|}o}|{u{~}|z{}z}~v{~sz~y|qwz{z|~}~}|xy}|t{xz|qwsyx{yzzw~x{{zyxwzw|~~y{~{~{zz}|zxz{~z|}wu{~w{z|y{{{nq~|u~~zxwu{nw|pu{zvx}|}}||}{y~~w}~|_}~rz}~z}t~v}z|~r}|}~uv~~}z}|}wxxy{|r||~}}wu~xw}zz|}{rwy}uzt~s{|o|~~z~{{k}}y|ty~{|z{|u~{yzw}{w}z}g}|xq|~y{syz}|w~{}}v|~yz~|~s}}|~~}wz}x{sv{}~~xv~{y|{{h{xvx~|rxw}w~Y}}tu|uy|u}~}}t{~w{x|}|kv|}~{||{}|{~|zy|}ywu{zs|{|{z~|{qx~|}{}uu~||u~|~~y}}}{}z{zx}zvz~}rxz||}t~zs}{y~xpw~xtuzt|s}zxw~z|~{|}y{u{nwvtn{|{}~|}qyp}|v}~{{z}|}rlw}~|wvvl|za||u{zv~}}r}{qywv~x~j}zwUv|mz}puvt~{o|~swypszz~yxv~psxey{}zlor{{Ztw|~}ws}tcztyuwu{|{uwzwvwwvunp{|z~z{}yσr|wst}{z}z~}}uz{~o_||ykngv|}]zotym~iudp~w}~xlt}sut|ktaw~wpxw`sun~znvt|xr{|yew|x{t|~~m{{~}vzw~}t|||y|gqmw~{nzys|xwr}v|}|~w}xmi}znp|xtocwytf{sm~|~Uy~}yk}wz|}}yyzX|uz~~||q}zmjxz{~{uz}tw{}y|j||uzwxo{{]xzxwbtzn{zr{v}zyxzs}~tw~~}}}n|wp{|}w}v|vh}xj}}tw~{u~yt}~t}v}{}{yzt|}y|vv}uuwvks{~}uz|zy{|}yt}zux|~~qzu}~}n{zy|}xuyu||u{{yxxx}}{yv{~yx~wx}v~u|{~~~~|{|t~}zx|~|u|{ywhx}n{|xx~t{v|t{}~x{{onx|s{tvt}zz}y{{xrmu~{y{rzy~xy{{x~r{v|{~z|tu{z{yw{~wzvyuz~~{|r|{~{wx}y|~}~{}~w|~{x}v|s~~z}~ny{}x|yywwy~uxxz{kp|xxlusyz{pt}~su{}~~{|~gw~|x~}tz{~{w}m~v~ow}ws|w{{yvopw{{]x]vxv|yyy{{zwyy|~~|z}~{|syx|~u{w~xzsx{s~xz~|}zz|t~wy|}zy|vxu|z}l{u}|y}~pyw}}{}w}|}}||ur}u{yw}x~}pz|vw|{k{|tsw}~}|{{x{x~x}}|{py{n|||zxz~yw}}|w~vmv}y~~x{xyyp|u~{v{zy{qxpx{|z|}}}wuw|}~s|||yxz|~|~`u}{}g~z~yn}tn{swqzy}{v|rx~~{p|zvzg}v|im||ua~w~vz~||{{}t}{zzys|}|}xz{{tw~zu|}vu~~}z{~sz{w{~vx|~{|u}}{}|~wz}{z|oz|}|~ytlyuwgwY{~}s}{ywx}tkyz|t||zyy~vzv{~y{vtpp{f~~~{}z||y~}zu|~ss}{~|~hxwwyn{~{}|x||v~pz}z||v~xx|}|}}w|y{q|qmq{xrt~~~wx}|r{~v|x{y|szjyy}|s~syysdvy}|n~|wx}~vzvv{wwtxz~|wy}tvx~|}j||u|t|tuzvvy|}zgv|S|vyr}yzwjt}{{n~sz~rx~{nzwtzp}{zu}r|o{z|{l~xwnpvzz{{x~yo]~ytxywxkpwr|ywqztwn|w~wz{z{z}yrwz|q~rvtq{}t~}iwr~ysw{v}w{mutw~|~{|{{xyg~t{}tzv~vwKwxyw~yz|uvq}}}tw}yzs~uzy|[ukx}pmyn}~{{z|z|}qs{s}}vzpyyz~~z|yw{~vzz|~|x}}}~zzxz|~~o|zq|~yw|{zx~z|wy~|}}x~{w{~zx~|s|y~|zx|x~|}wy}~tzk|x~xxyxxt||~urvv~xy~{wlx~y|z~}xwyxvtvy|~z|wzytx}z|z~h~}{|yyzu|}wzxx|uwpurk{|yzx~~}uzy|rr~y|z~zvz~vwxvzx~zw{vyy}y|xyyutxqzv|~{}~~~z{svq}w~xyvvw}xz~wx~x{~sw~~yz}zy{zw|{lz{wtz|q{|}vxzxy~~|zzxwvvv~ss|jsv|~ztyxwzzyz~}zyfxvysyy}|~z~x{z|}y}v{|xt|syk}sz}~|}}rq|yuy}}{vn~z|~~}x}}{~}z}|~}zy}{}y~rxxv}vy~|x|yxx|w{~yu~}w|h~mx~s~t}|}x~}{|~sd~|tz|{}~y|y|y{zzu}~|yxzz{{tv|x}zzq}||{r~{}u|yyl|}{zy}~vzsz|~|}||||y~{~{{x{{z|u|}}ywuqx}z~|{{t|}y~~||~~y|z}|p~u|qu{{|||vpx~|~~|~zwp{~w~xp}{}{~|xxz||o}txz}s~vx~x|{~{~~zpo~}zx{~{u|z{~h}|}~{}~up~~z{x{zvqu|v}k{z{fp|t|~zx{zyp~yt|p{msk}w}zz|||}|y|pw~yx|vz~}|yu|yyy}z~{|{{i~syy|zyqszv~zs|{z{{}y~|wx~~{|}}y{zbv{~wu|||uzix~wx{vpz}~|smy~xv|}~|{w}{~{ziuovz}x|}{ys{z{tov}|j{~ztlxzyy{{w|||{~rvzz}~}ssnzzyuv||k|zqyz}z~}|~y}opy|z||||r~y|j|e}~}fzsouuyx~zt|~s}zk}xpx{|z|}yj~zvsu|~~x{||yxduz~x}t}s|y{~}|y~~u}_vyz{}y}|mzw|}{u|z{~{}wxmvvxwzvv{|uqwos|~|z{y{|~|}}nuv}{~wx~r~t}{~xv~}z}xy|{zg{}w}|{|px|{zq~{}z{{vwq|swmr~zr|}|zy}r}xnv{{x}}yu}wo|yx~k{}w{q{xw{q|q~x~||~gzq}~l|z}}y|[zyruyzyt{x|yu}xt~q~~x~{{xv{|x}vx{yx~w}|yxyw}||{x{~~}}z}~}w~~}{jw~~|z|~}}}{u~z}z{}y{t{~tpzz}}}|vq|~{zx{{zyu}y~|~n~}xq~zk~v}v|~|{}zx{~u|{|~zz|x}swxw|{ty~y}|~gzzyu~}x|~uo~|}zzx}}ul|v~~~|x|}vw}~}r}yy~v{}z~{nwzyzzx{}z~{|y}xy~w||{}qzz}~|z}r~q}xxzv}|y{{|zwy}{zzkx}~zx|yn{~~x|wy}{|}~ww|u||~s}|~~l}qms~t|w{|_{~~k~|~{rjzw~|}n}~~xz{}pxw{}uyzwx|~yz{kmidu{rt{wzyuzv|wz{zwvv}}ngxyvv{}~yj|z|}xyp|}~ozozw}xnyz}~zn|qs~~~zw}r{pt~}~xutu~~u{{{}}j}w|tt|{~x}|}x|oyw{{{~}{w|}ls}{yttpux~{v}uxpxowzxy{vcvs|x}}rzrjy|{xvx}xux|ts~v{zy~r}|kwr}|~ysz{vmzy|zzpx}s}vzo|||z{xpsyxyu}|v~un{x{{uva{}u|~xq{n~{|tq}y}{^uyx{{~ws}vpr~~qstnr`{}}m|o{ux~syso|zx{ox~v|xuqyxv|zxt{yvt||cq}z{~qtl}}~|o}{|y~}vv}|xx}{|w{yqpy{w{~s||yx_~}{xf~zy}{}z|dvzn~t||xvu~tzz|~xq{{}x~~|sz~}}{||~xsw{rzz~x}ryy|~z~ym}}|vz}|z{xt~zz{{}~~}}k|x~~}}xx~{}{}npy{z~t{{xl|x|~}y}}|~{{~xr{yv{|{~x}|z{{w~{|z}vx}zxztvt|z}~~~}z{zjzm~tl}~{n}~mzx|}~s{z}|xxp}w|rp|u{}~|{rz~hq~~w|u}u{|zv}}r|v|{||v}~t{y{ym{{zf{yv~~}w}yys{qr~q~z}y~||qp{{t}pwxzp}}v{|n|~q~vv|{z{|wrsxz|ym||y~{qz{xvw|~{w{~wzwuy|z|v}xz}x~x}yyxy}z{|~~|z|yy~s|q{}|x}q|{z}}y|zyy}~ssuutzyxy{zztqy|y|u{|w}h}{{~tx|yy}{uzyr~{|}~}zr|~t{~r}vt{{~xvmz{xv}s}~}wt~nvzyy|z}zz|sw~w{yz~tw}y|wx}|w}z~xx~|xx{|~xvz|}zj{x}z{}yy||}}{xzy|u~}|ynq~{z}{~}|syww}}us~u{}}~vxw~~~~yztq|r}~|vyu|{~}~y|z}zv~x}|z|z{v|vx~z~t|~|}}|yhv}w|z|~~}yv~{zx}vyp}mms~~{p}~x{zyxw|{{xz~v{}y}yyzrqowgzyzzz|ytu}|~~yzv~{zu}ywy}kyv|j|sx}{y}y}~x}l~uu~wzyux~}s~|_u~}wz~y{}q{vyzy~u}vx|~~}~}m}{v~yz}w{|qwvzw}}}ts~~~qrz{z}xhmyuzwzw~{}{|z}p~xvmq}{~}~~}yrx|{~~t|uigx}v{y{|~rx|~ryp}~z~tn{S~{t|~|zxt|xxzp}{xwyq|}z|z}pvr}zxz{|~xz~rzzw}y}ys~}rp~wtpozp|nsvjpzuyt{z{rv{vw~{wfxoswy|zzx|x||}y}{v}|}vzu|v~~y~}h}ysr{y~zvt|z~~|{z|~v~z}zyy{u|~xx[u}{~{y}yu}x~u}{}|t{|{vzzn{}ywvyrx~~xyzx}||}~~{z~{yy|}~nxtt|~}~}}~~}}~z{uy||||{x{u|szv~}|yy~x|yx{wvn{yz~{~}y{~~~~zu~xu~u|xwye}yw{zx}~}wz{v~s~|p~~yy~xz}w}y}{sy~y|~x||y~x{}~ztysz~}xzyxwy{~z~z}|~x|{{|{}q{v~zyxv~sy~z}zvz{|~w{rp|~qtz{y|~ru|{{{zzz{~|v~wr||~||}zt{{zzx}}z{r~z{~nx{w}tx}{~z}z~{s|ty~}j|w}~y|~{|~}p}w|wz|{}{zs}~vty}vz}vxwwuz}|~|~}|u~|zyzm{z|ny}v|yypywxxy~w||~w{|~z{sx|~y}~|us~qsx~yxv{~~{|}|~}t|y}wx~{}~|{y|xwvs~t}xyuzxy|zv{}yw{y|zq~{y~{|y{etxwz~swzzww~}s}|~zx}xzwx}~|v~z{{y~lwx}{|}~ytly}u|}y~}|}|}z~{~{}~{|}pv~sw||~y{}{yy~}smx~~xvu~u~xky|xuz}r}t~zxv~xz}}my}}sxmxrxy}ty{z~zq||z|opsq}x~~x|vszzzv|tv{}x~~x{yx~zyzt{|~zxt{zzszmd|q~zspu}}{|}|{k~}~oz{vg{zs|}sn~~yzvw}{|zt{{}~{{zztzp{zxz}~|p}wnzz{r}}||{}}}}v{{xv{~}}|~}{~yy~ywax{~y{z}|{{vhb{v~}~~pz~~|}tnu}{s||v~vap|{{~mys}|{}~w{vy}x}g{}ysv~tym~j}u|~u{qrxzx{}{yyz}{w|wzz|}xtz|x~~xcy{y~|fuur}n~zyx{|{yvrz}vfyk|{vlw{|~t}vy{z{tzw||wpz{{|yuyu~zxmjzx}zx{|uzyzrx}zyyzr}v|pwv|jo}wqvzwxwzty|{}w~}zvryvyuyr}}r|t~x~x~xupUy{Hoov|~m{f|~w}vsuwt|~||z{}s}ay~x~|z|wwzyuq|fs}}~|{zzv{us~p||x{s~P~zubtw~}ut{{|yyyw]{}z||zrtvx|}xsxytvxl}v{{r{z|}z}[{u{swz ~q~t|zh|sux}{x~x~~yw{{z}~}|uzz~y~us{u"wqsyusyy~y{p}}||yv{~{ztz|wnrrx}x|q{{x{ut~xxt|~w}{s}u{ww~Pz{xvszyvtvwz~w{syzt}vus{rs{~}}}t~p}Wupsyzlzx}zmvwxtp||{{yu|~~}x~wy{s{}y~|qzosw}t}|ryjw{sx~z|uzu{|{uxt|}yvwjfVv|x{xyw~w~xwq{p{{vwv}t~x}zzrxx~|{zwvws}}|w|tvwtz{zqszx|w}sm{uy|x~~}rx~z}xs|sy{py}~z|zzx~|zulv{|y|wxupvokw}nnsut~p~zuz~sxx{sr}~|yvzswmv{}t~qztwxvytytwy{~y{zt{|z~r|w|~zy}|{myssx~yz|t~~z~u}wa}|x}yo~sv{uurxzxovy~o~~z{pwz|qq}zZvxs|z~z|wtzu}zszz~|{y\}s}uv{s}x}~||}zx||z}x|{{y{xyrz|xxy}xpz|wz}}}y|r{zyz~~wrqy~s~u~}zty{}l}fxxy}y}{~w|}z|}ysx}k~q}~o~}}}}kw}uyznk|xx~ts}vwuvux|}v||~~zvw~ms~yyz{rt|qz}v}xuy|{||z}yu{w|uzzzv}rk\|z||~|}yzt{|q|xv}m{{~v}}y}ingzv~uu~{y~~|j}bqz{{~{|{y|}yyv~yuwvzw}y}vpwtuv~n|z||}vz}piz{{utw{|xwo{tz~{~xuywrt}}}yz|svsvx|yx~|xn}{{u}sz~~|v}z|{xy}wy{|xkzwtz~syqkyxy{{sw}x}}|yx~zzw{|z{|z{}{~{|zs|{t{~m{utZ{{u~|~~z|}x{~x~|{w|j}}}~y{~~}|y~u{zqxux{qzz|~{~rtx|z~|q|}zz~{t|t~vvuzr}}t~x}}u~{|~yymx|y{wuzw|qxz}|~uuow~y~{}ut|wy~wx{|s~z|}vyt|x}}||}{y}uxl|xt{}{zzyxw|}~~~~}~|xzw|qw~~||~y{z~u|}zuzw~~||nzzu{|xv~zz{wx~u{vuzxy{{q~}|qxy~{}z|uz{~||xv{}w}v{yo|u}{|~z}zqzyqw{}wzzt{vrz~y|y~z~{yv}|w}zz||xu}w|{zxnwu}x~}|{}yzx}{ywrzzxyx{xwwy~~prw{}{v|wzvxz~~znv|q|yvn~z|y~pyxt}|vz~tzww}uusn}vvy|y{s{}~x{|{z~|yw~}||t|zzqwtt}vv~vz|{{x~ypvwry{|{|~{x}x|}{{~yzz}}|}wz|}yxtz|yw|{~zz|r{vv}~qxz|wqz~|xx}ps}pt~xz|wz|y}umtjz{{y~y|}x{yuw~||{z|y|{v}}|~x{{m~{w|{~b}yxuzy|w{|{ox}}vxx||yv{u}zz|wun}}|}}uzzrnx~|z|z}{}||z}ru}|xzz{vyxl}w}}}y{z{w~|yur}z}{|r}zwu{{zx~w}vwt}tz}xss{yyvz{y{v|xvo~kvttl{v}v||{||uwv}{|||w{{p~z{z}rz}~uwvvxx}s{|p~}vvr|vxy{x~|ryp~|oyvv}qv{~r~y|}q|{|s~|~{||}y}}sxwk}oyx|q}~~~u{}~}~s~x|~~zy}}qsv|~||uy|~zv~vq}~yzxz}|~}p~}zx{~zpzxx{y~}}|}wx|}~t~~z}|wy}}x}y{}~xx}{yyvzv{y~~xr~{|y||zx|tv}yx{}y~{s{}yzxs~v|~vy|}wy~|y{|}sz}~~}|u|q|zj{}~y|{jzxm|}tv|oyzy{{|x}}y~}wx|{}}}wt}w{~uz{xyxy|muywv|{zx~wzwzr}pzwxy{~u~~wz~zyyw{zu||uz{lv|xzur~tzzz~n{vy~}xww|x{{{zv}u~ut|}|zzsyy|~|||~r|~}{zr{{ywozuz|s|v}wzwyz}|z~v|||{qt{v|w}u~y~x}qy|z}ntrzz{~}y}r}v|~z}yt}p}}|y~y{w~n{|}t~{z~x~|uxqz}y~|}|||~{}~v|z|}|{x}r{}}{{||t|~zz{|uwyoux~}w|u{x{yt|z}~zy||}z|z}|~~v|xyu{p|x|}}y}|u~z{zxrw|wmz~|~|~~yvz{yz{kqz}}w}~}ly|}~}~zxxq|}~v|}v}~owuy}zw|u|{y}njyn|xw{w~||~|{|~x||o~~}{t|}xqw}x{t}{w{{ww}{ozv{|wwx}zys}y}}{~vvss{|r}|{f|{]|{q}{y~}z|~o|v|n}zzvr{y{{u}y|y}tvyzwuk|zw|v}~~z}zqx}|t}}u}}z||zs}v~{{s|~}{||~{y}w{w}y{{tz{}ssz}ww{||~x{|{sq|{z|}}}x~}xv}y}q||{y|quj{}z~z}{~z}~zvx~xqx|v~|~|uvw{|vuwxx}{~yzvw{~~~{w}t}yzxyywvx}}~u||{tzzz}}~x|}o|kypyzzzzn^st~}ou}z|sw~}w{r~{|x}{vzx~xpr}zvz|~ypx}ktyyw~|}w||tw~y{oysy|t||s|}u}vt|t{vxtt|y}pu|~}}z~t~vvuxy{|~q{v}zwz}y~zt~y~t|w}xr{j|~s~yyr|}~{}~~|y~}|y|zzy}y}|yy|zlz{nv~ry|vr{r}{~}~|}zz{x~~v}|{y|s~}z~hx{u|wjty~|s{|}~~|~{wv|y}z{~{~wu|~{qzlzwwv{}|}|~su|xwzw}z|y}wj~t~y{}~z~}~p{|s|||~|wz}}tz}y~|pu}x}|~vxvv~tuvrr}}z||zy}q|}vtzb}ls{~|jq~z{}{t|w{uwsv}{t||{}}}|zt~wyv|s}}z{l~}|}~}{}~}zl~~{|}xy}}lw}}x}{y{zz}~oq~zw{{u{}o}{ty{~}|z|uz{{zywx}tztv~x{~w~~n~y~p~|y{y}{~{{qzz{zt|t|}z~|s}~}vwu}}yu{~z~p~ywx}~x|~|yx}|qzu||xx{z~||x|w}{|{~}xxz{vw}|}vt}x~z}y~o}}rt{w}x~{|~}~xusw}zu}}xvzmwz~|yzzz}}y{wx|sywzr{~x{lz~|~{y~~}zt~qy{}}u}}ys}~|}|}x||oz~|}|{zuy{q{~|z|~}xm~~{|}}}x~||}{z|||}n~|x{xx~ww}wwy{|||~||{|y~~{{y~|{x~om~|t|{~y}s~~}v{y~ywvzz~|{~p}}~y|{v{{x}vxz|~rrx}w~y~||{w|x{wu|{y{}z|}xzzuyy~t{}~{~~zxyxzv{|~{y}t~}}s}}}uzpw~z}~}{t{rtxs}yz}w~~{vu~|}xx{xq}w~zvxx}uy{x}|y}|t}v{{{l~{v|{yyx}tuy|qvy|x{}{yy~~w}~wy{yw|{w}uz~u{}{x|vz|u{~~uy}~{}~~w~nyu~r~u{y{}}|y|qz|~}u}}y~}z~~{}z{y{}{zsw}}v}{xruvnxwu~z{|yvy{|}yxx}|z}v{}v{s}lv}~zzxzx}{sxkp|zx|nyzowzyyuzx}}|rxq~wy{}y~x~~tx{}z}~z|}~zt}t{y|xz~{qyy{{|x|}ty|w~urxr|txy~~{r{}wz}~us~{wqu~}t~~}t|~~|~|}}wyv}yr}wnz||rpx}}v|w{|vz}{|{ttt{{o}~z{|w~{~{{}xzztv~}|}uvv|y|~}z~|wuuuq|xzux}x{svr~}urvp|x|~|||{xuyzr|q|s~~w{yuzyxq~~w~}~}k}u||m~u{|w~ztwwsv}{x|~{||sf}|m~}{v~s{xrwzqzz{y{~||}y}nusu}{u}{~zyxxyv|p~~|z{m|h~~r}xp}z~e{sv{}z}~yz`}xy}put}x|tw~~z~x}}xxtvqwwzzuz|}|xuz}~jss|yw~~x{y{x}|x|vy|zm}wx}~ylxt{s}}}~|vu~|}twtwpuwu}yowxyt`vy}|vyzuxqvzvvy|{z}}uw~}~xw|p{xhts|uus|vr}zttry~||yz}yxz~}q}|}|yruvzwpy~zwpus~}u|qryz{~|{zwtxo~y}yvuyor{|ytyzzw}zqy|~yy|vtxnw}vxzz}q~h{zszir}~w}}{vxzxyz{w{njx{{v}k~}|u|yy|v~vrq}~~ur{tz|{{|~vw|~~pzywn~~{yz~sv{v|}uqpzs~{}vzz~qxszs|zw{}v{t|}z{v{~yx|yunz~yqv|}w|qzuy}zz}~p{|}zhww|ntzx|nq}{~|u}~tzwsx}m|ty{jwnv{w}{rn~txu{txj{~wz~ns}xr~|wxkzznzo~p{wuwx}~xqu}}ox}|z|uy{tyt|pr{~vtyrwwyoqx}}}|zy|~y}|v}yuztu~f}t}vuz~~x~{{}|~z{y{y|wvzrmtsz~{v{|}y|}yy|{l~x~~y|u}|p~{xz}yzy~xw{~|~|{zs~q~vyzo}}twxt}|x|}{z~~~ztz~z}mu{}}yx{~wxt}||v{~{}}zz}roxy~~x|~|}~{t{y}qy}}zwy}y{u{yly~}zyn|qo{{|}~|o{}{w{}{~||{}|{yu{y|yw{~vpyz}~z{~u|zzzzp~u~q~|||}~zrx~{s}xy}zs{}sytwvs~z~{t|x}~|sz~~yxuuzwz~||{v~u}}|x|zxyz|}{w|x|zw~|~{w|x}wm~y}{{zx~|t{{{x|zwvsp{|wwxzy~~{wv{{v~{{~~}zv{y}}wz~}s}w}z}z}}~s}t}}k{vuz}uv~r~}||ytxq{~}y}zwz}vz{rmzzv{wmuup}}vtp}t|y||l{q|v|{ysxvt{x}|}uvzrwyyy}jz{|m}~~|z{||y{xsxqzwx{z~wvp}u|o}px~txzsz~|u}|svw~||}|xvuytz}z{y}{}|u|x}t{|xtu|}zr{|}{~}z~lnwxa{~xv{{|~zx{~tnvtyy|tvu|vyz~|svxzntsv}xyxzz|y~v{}|}uuzgj|}uyxxos~uqqtpy|~{xsvwww~x}{wgzq{zw~zr}w~o|w|}x}x~{x{t{yryzz~~s|||y|{{xn|}~}}{~}}|}vx}y|xzy}~{{|~~~zz~yx~z{{m~j|xs}y|z|}w}|{y|}xx}{{wz~}{y~|y~|~xyzxu|z{z{zswvzx~{{zvty|}y}y~{|{vww}}}{ttw{~{z}xx{{tx}{|{|w~|u~{y}~}~qsw~{vyzzx}{~~v{~wxzy{u|}{t|~u||{}z}}}y{}}w}{y|~}z}|}|}z{~yy~}w~x~z~|}|}~xx~zz|~{||w{}vz~}}t}|v|r~z{v~ys}{~}{tyw~ww~xy{}x{||}y|}y}v}|x}{w~yz~zy~wy~zzx}x~{{~t}~p~zv{~{z~}r~~z|yspt~zqyyjpp|wxsxy~nyq~us|sq{}{~zx}rp|vzr~[w9zuw{~tsz~uz}uz|~}}}x}|~z~wt}y||~|l|}m|{||xr~z|x~|w~|~z~}{}x{}~|n~uz|v{w{}~~|tz~v|wz}x|{{|}}|ozz{}vy}y}{}{~y~}p{~yuvt{~|||{vx{~xxw}{{{x~xyo~}{yx{}x}n}}lyy|{jsz~st}}v~|mz{{{|z|~~~|||zz||~y~~}|{|}y~yzy}{tr}y~}tw|w{}}zvw~~zzyxi~x{|}{||swxy||pv~}vz}y}z}x~zwppr}zsp|}u}wsy{x{w{|~|}{ujrxr|uwq}|x|~{|y~{||uz~ysx{}vvuy|y{|uj{yj~{{u~|{}t|u|vi}{|{v|}|}dp}~zw{y}}nslsztrq~~s~z~ny}{y}z}||ztrkr|}y{}uz}}||}xz}v|~y}ot}|~~}y}pt}}~p}|}~z{uy~r~y~|y|}vvx~z|tzz|w{y||{n||n|~x~ys}yv|yz{yu~{z}yzw}yzxnuyux}ty}yw}}{~~v~yuu~xzzo~zyqz|||}sszq{~}xzyxqk~yvyv~|z{{swrqzyz|p~vwy}z~xtw~zswz||~wwx{mzzwz~|x|~|{}|w~zx{xqzzy~y}~v~{~u}}~}}}ryx~x{{{yxxy|x}}v~z}wvxx|uw}tx|}y}z~w|~~}}|}u{v{xt|}[|uvz~yq}}}||}x{|woy}|~}{}|{{v|~y|}y|~{l}vu}~}~~y~~|z~|rz~{ro~ur~|{u|{vp|ywsv~||z{z|wy|}|}{|~|tx}|p{n{puvz{u}|}uyo}|~{~}{~wz}|z~{|qz~vvztyu{z~{z{y|y|yy~~||qy}|s{l~}|q}a{z{{{|y}v~~y{||{~~}|}y}}~~|}sz|{y}x|{|}|z~n|{r~}z}y|xxz}yt~~~{|}{z|{u}|{ry{x{ct|~x||~x}}x|uj|{q~yyv~}}w~wzy||vyuv}{|}{r}{}{~vo~xvx|u{x~{{tz{y}zsxzzx|yz{~|{yvvxs}rwv~~}|t|vxy}zz{`{ogty|}||st}w^zzw}yvn{}~|v{~t~}}u{~|z|s|}w~|tzyu~||}}ph}{~z|~p}vz{rwtz|zzwuzutq{z~}|}}|x}y{~xyuso{ww~zvwp{{y}~u{z}t{||vvy~}|~}p~z|vv~{}khy{~zvzwo{m{xxxtxtym~sxvwtxwrzxuypy|wy|||syuz}wy}u}~xtnz{|m~v{w{uz|p|~x}}}y||z}q~w~~tvus}xyyx|s|~xpy{x{{x~{~xxyr~o}uzz{ywet}v{{|xz~w{gxwu}}rsy{}v{}}~{|{x||{l{}tz}{vuz~|t{yplqt}tw|y|y}|xx{}||y{pyz{|zxpzzz{sy{{}{{wz{r||zzzvx|}}}y~~j{{s{w|~~~{~}pyxw~r{vyqupxxz~xvv}q{px|}yw}xiv{{}vv~e{y{jz|wrwv}xzz~sw{yxu{{||r}x{zpzzx~zzv||xkz|xy|~w}yyxy{|xzy{~~xnow~z~}~~~zz}}zzm}r~~ryxr{~xryuysypqwn|nvxxw||utrxsy{~}yw|vn~y~vxxx~pm{ht{~qrouvyx}|{{tzu~}vsu~|||x}uy|p{xzy}w}x~x}|z}wq~~vxozz}}x|wxyw~v|x}|z~w~z|lp}|t|~x}uyxzqw{zz|w~yw}{~}yy|wz{}yqy~|{}zw|{|r~u{wwuozw{~xu{zv{{{{}ytyu}w~~~|}|}}{}x{xvw|{v|z~x{u~{xz~qywx}z~zwk|}x|{yuydv}{z~x}~|~wr{xyszzzyz{~}v}vx~x|xs{xsr~qy{~p}w{|~z}zz_|~zu}|}~~rvwww|~|{zx~~xyr{xq{{{uy}vsp{x}y|~{tzy}}u{}{ytzzVw~}}~r|~{~uxyx}||txzt}yvz|~t{xu}u~xm~}p|xu}y~}~qv~|z{xy}}usvz{z{~|rzs{yx}yv|w~w|vx~y{|v|y~t{|zteu~q}~xt{x}vq}|{~wt|t{u}z{k~|m|{uwy{wu}zy~|x~iz|pu}{pwl}y|y}x}}{||wo~}w{}z|~{~x|{uy~}sll||z}|~}|}}xzzq~|||}{j~}zx~qk}v~yxx|~x|u{vp{{{}{~r~~|yz{zzy~}~x||x~}zz~oup~{||~ywzx|x|xzz}z|z|z||{}t}~uo}~u{|s}r|n|~}rp|{}|s{|wr}u~||x|wzt{xxzutkyz}}zyy}py~}v~u~uyyw~v~}vu|}n|yszz|y{|x}yx|~p{}{|}{~~wvyxs|{}}~{syvz{vwvj{|xtv}tz}{}xv{vtyz|ww}~~{r}~x||ryy|xz~u}~}m{vzyxuv}|{{x}|uzwwxuy|zyy{x|uzu}~uqkyq~|}v|{{b}x{~}kxv}~v{}{uw}xz|o|y}~}zxhx|j||u}w{w~p{}{}xw~{~l{v{s{~||zu}x~{pm~{{qq|{y}w}}{{vvr|~js}{ut|z~yv{wy|t~|{{{||xs|y}tww|y}}kz{sr{|z{z}}{u}w|xr}uqzz|~{m~}zw{~~w~x||z~{|{~w{}gu~}{{yzt|{tj|rm|z}v|q}x~~w|yx|sv}}|{x}~{zww}}vo~}~xyyo{yusvsv|w|zx|{vyu}}}{z~rw|{}~{x|{{o{{~}{~lut~{pkpq}uz~z{wxwxq~}}rx|wx{||x{~|f}~uu|~yt}r{~|~w~|_|zu}~~yy{{~z{}~||zz|~~v{svzvt|zy}|}zuz{y~w~y~y~yvqw~}|v~}{z~{{|~w}|~m~z{v{~{~v~}|{ztvw}}~}x{}y{~{w}|z}{{ts~{|z{~|y~~v|zyx}vfxz|||z|}|xuu}|wy_zv|||}zqz||y|z{x~}~p}w}~{oz|u}y}~~}|uxq{w}|uyxwxtyr~|}vx}v}~xwz|}z|u}{x{}}~q{~}}x}~~}}}mi||xyt{r}z}gy}}z}}}|qyzrv{|y{rz}|vz|}rq~q}~r~}z}}kvx}{|}|}|zw|{|tpvy}r{yyy{}~~~}u|}zt}z}y~y}txz}}}}ww}~~~~}~~~~s{z}}}|~|y~y|{ww~}w|}|v||zw|y{r{{yvt}y~znw}}v~x}u{x}{}~{~}oz}k}}{||~rq{{}|}y~|}||{y|z~}|{pt}au|~q{|||{~~}~q~{x|u||~|wrx~~r~zoy|t}~xv~{w~|p|}yz||}x}ty}zu|}z|~w~~ut}}~~q~xtvqu~~x|zy~z}|}w|~v~~u}{~p~}}|w|x}xuu~|}xx}zyxz|t~vw|w|z{v|y}vu|{oy~{xk|}|yuxyqq}{}uwwz{r{z|~}z|~~|yjz{{z~}z}p|us{ox}z||{w|^w|yw}}|sz{znuryw}yy~k~wo}yxu|lvwj~}szt|~xvzykxw}{w||~yyyvuusxqz~{{o~q~vtwz}y{{s|vwz|uu|y{yt|~{||yww~{z~|~}q}yzz{{|~{~ww|~u`~vrz~z}w~z|yv}y|x|sutv}z{vy{~n|{y|~zxz{e}v|zqx~{t}x~|yu~v}x~}|yo}yX}s~|vxyv{u~{~slw{|z{|pruzy~phwyp{tp}uwswwx{v|z}~{}ztq|z{}|ry||ywx|px~|y||{|xvt|txwtxott}w}yxy{yvowxy{vyuxzz}jyv{y|}}o}tk}m|zqxct~ws|z~i|odt|x{}|szqyzyny~}r{\zn~z}vpszou~yttqy~wtuvwuv|x}ow{w{xpanjYzy{us~Qx{zz|ouzociozyqvvy~~szUk}m}xupz|}Rn|njv_hplqxfovv~}u|ht|fg~}{{tu~{y{kd}~{zx{tq}ovy{p}z{l~zz~x}x|stzw|u~{qw{xfu}znlgntizb|qzy~}~u{to|wx}{wm{y~|u}~tq}u{}{v~hvw}|t|}qx|x~~tvrp|zk|iuu~D|j}duy|zugy}}}vz~{zqrtvq{s|otx~zVy}uz{y{|qzfywyt}x~z~zxr}|tz~o}v}~w{}~~w|{|{}zy~|ytvw}s|z{}}{|}zzv|{|~|}xw~~}zwt}|{|yw}|||}l}~{vouyw|o}}{yz~uw{xr{w{|}|{|{xy{xt{y|ts~yy||{}zw~wqxzwwtvw{~|zw~u}{q||}z|}sz~~uxxuvx{}p}wovt|uzvy~{umwz{x|{}|vv~o|y}}z|y~|~vyw||}zt}qt|}~~xz|v}y~xsquy{}~}zxx~wxx}}~{ws{}~|skzsrr~n{}z{}|~}}}{x~zzz}v~zvzt~wy|}}u~qv{{xz~{zyz}{u}~~~}~~}{x}wxu{{pyvz~{~{}{{zyzy}m|sxvo|}yztu{|~r}tx{y|}{uz~~ts{~xt}~|{}|zxz~}|wwy~{zt}s|y~}|xnfv{~}vy~z{}yz~nl|{zlyqy{}}z|}p}x~}z|t~~~wx~~}|}yryx{x|oz||zw}ztu~w|u||u~~yz{tzrzymeo{ys}{z~yq|z~|xs~{}|}|wvx{t|tywyz~l{{||}yxw~~}sz}uz{|~yrfzw||~~{ux||{ytw}yzw}|wq}~x}vzw||yr|{u|{zs|z}~{zwyzuu{zzxvwzm~{v~ztmyxut|~w{z~r|x{~x{yom||{|}~yyx~yy{u~s|r||{}||y|}xzy{~ewr}|p|xwtzun~||zx~v{x|g}{r~{{{|{~vzvsw{}ut{{l~}iy{{}|rr|zcjz_z~zq}~}ui|}~y}r~|w~y|y}{{~vny||y{y}{zy}}suz{v{|bo}}tzzcxu|yz}~|_{s|tu}}su|vr}|z{{~|r{}sp~~}|~}l|y~xzvb~xv|yq{~s}|~~|os~s{wy~{{~z~v}|~r{ykvz}y{znw~}~|~{|{|xy{y~yx|{zwz|q}uop{o}z{z~zo{~y~|}|{y}vyzvw{ww|yr{ztck~t~v}{q~txvu}}y~u{~xz{zu{}w}~v{}l{q{ty|us~p}}{{}|yfwvy{r|||zq{i|r~|wo~~~twoz}yu|}tz{}{v{wy||}x}|tx}yvr{}|y|}yvz~|uy|g|~}{}z}x~zzorz}}}x|z{t}~|}|w||ws}y|{zzy{~{}x{|ys}z~~z~wo|}yz}t}zu|q|~yyqz{|{~{v|yvz|wzuy~|t~q}z{|px}y~yw{yt~s}}}~p{|~y|y~s|}w|z|}}}ztsfut{{y{~q||tkz}{v}~~{yn~t|{~t}}qxyx~~~~~|}}~xy~{~zxx~}~vnu~~|{~s~kz|y~|{}y{|yy|}zyx~zyr}yxz|z{~{xzz}v~r~~~wv~y{|x}}~pz||r~{}q~z{yz}ouzyyt}{}~zz|r|||~}yzyx~{puj{{y{~ms~{{ys~v}w|p|xy~{}t||t||j}}~{xvss|g}~r~{~|t~yt}x}s}|zz}x~y|z{}|||~~zx}{|}~{~{~zk}w~t}}q}{yzx}www}~|zs|v|y~qx|~|{}z}|wz}}yxy|xywz||}|z~~|z|w{~v}~~p{w~{|x}~~}~~|}~}xz}s}{z{{v|x|~tr}|xx{|pyu~}|y||r{|o}{}{}}tz~~~x||}z~x|}t~zw}zrn{u|y}}z{w~wwyz~x}sz}unz~y~}}}|}pw~|z}qrwvu}|w~{z{}y~z}~||y}}{y{}{vjv{yvww}w{yxxvyu{t{}ww|u|w|{|y|{ywz~zswz{~x~uyw|}~x~}}y}~t~|}{|z~{~|a}{|}x}|l{|z|z||{|}ts{y~{xxt}}}zlz}}t|v}xuzyjxi|}~|~{u}w~}Yg|q~rs~ws{|{w{~|zz~q}~y|vzs|{{n{|hl{l}{|v}|qp}~{x|~u{}ny|x}vxxyyxw{}q{~}}jyy{ulzr{~{rxw||t|~`|vlwy{s|z}}}|s~x~}{~ezvewyug{yxqz|y~uwyvyy}oysy|t{wz}|x{~{v{|t|~~~p{kzw}|~wxwz{xz~s{~uyzwz|p}zym}y~xr|xz}n{vw|vsyzys{xmz|w}ytkwx}v~{y{|||{w{~z||p|{~}q~z}{z}}|zz~n|rz|xqw~{|u{wz}x}}~yy}{~v}|tv|sv~vv|~|~~w~vuy}o{z}{}{z}xzv|}}|~s~zzx~wv|~q}z}|~~rv{zly|zzsx|}}wy}r}}{~s|}|}x}{}|}z}~q~vt}o~|~}uz{s|~vy~x{t{~wo}y{p||v|{vy{pw~p|}}w}w}ix}{y|x|}kx~|zve{~}{|}y}~{uuw{tvo~yx~}~ku|{qzxwu{qyvy{}}{{~|}}|ysuv~x}~z{z}vw}~}|uz{~{w|}yy~tzw{up}~{zzy|}}yz}z~~||}m|r~|}f}uz}~ywy~wy{~}~|~~y}x|wy~~}vy{{~xz|yhy{}vy{w||w~{~{~~zzxx}~uz~|ur{yu{}u}~zx{|z~|}vy}xxv}{}}~}xzzyzz}r~{{|uz{z|}}~x}|zu~uw~wyzuy|{{}x}z|}z|{wxz~}~}}y{z|y}{}{z}y{hzuz|~yyv{y~{xt{z}}~}xzwds|}{zw}y{uz|||~z|rux{|||~~{x~t|xz}~}~xz|{}{|s{~ywzs|sz|v~{}}|k}wxvws{x{s~{u|}z{j~y{|xwt~z{}~v}w|zxsy}z{zvyz|x~x|wzwx}zt{swz}m{uz~|]tx{hv}w{{{ytwr|}x{||||xw|zx}zxz~|zrv~|xv{p}w|}}x~}v~xu~{qzzvwy~z||{~{y}y}~xxu|{zw~yw~{}|}yr|xq}v~}w{s}vsyx~|}z~|}}ww}v}uyzz||}~yr}u~xzzwyxvquwzmw}zo~}|rxw~xytz{yz|wy}w~}y|~uyz{{}q{v||zz~{zz|yxy}~nx|{}y|u}zy}||xzwzj}ywrs|uzz}|{wvywyyw|~|~|xzxsy{}ex}|{vzs{w}~~~xq|r~{v|}}x|{zv{{~}}xy~x|{~y}}~~{~vuysz{u`xvyu}zxw~zz}x}{{{~|vv~yy|uyy|{~}~uzwr~ky~{r~~t|~~~|}s{~rx}zy}}~o{u~{ou{||}|tx|{|~x~vyz{}v{~{{|~~{~z|y{v{rwyut||v~w}xww~~z}rwy~~}uz}u~~tz|wzzox||n|}s|zyrt}sw~vz~nw{y~{u{s{~{z{u~x}zuy{xzy~|z|t{vsy|}}uvx{oy{x~{~{y~x{~~twyz}|}us}x~|}|xryp}~vz|zzv||xwzyvt~wz{uvx|{~q|~ux~}}y~k~|{|yzwxvy{{ww|}xpw|y|vxvs~}s|z~|~uy}xqyr}o~pt~}yx|tvysxz|sr{ov|~{x{q~q||}~tz~}oz|zy}u{pw~x|}y{|zyyy}~~|{{y~wv{vw}p||rz}r{w{w|xuzu}{y}~w}z{{|}}}{{st~~~}}z~wzrysxxs{||xytm|}}~]yyrvvo}~{v{xyyyu{x|y{tqx~|}|zwvj~w||{}|}~}|{yuwu{zxx{~|xxvy}~yv|}{|{u~l}ys~y{|~|{yy}wzyz{~}~}k{{~|vy}}z~z|{dvkz~{{{}y}{~|{~~zrvtxtsz{~~}|lyx|~uwts{yxzw}y|{qu{{u{~iqu{y}~|wfttzu|x|u}p|~{vy{|{z|{}d|xx{zu~~y}y|y~h]}lv|~|z}~oy{{u}~~|~|}ozzwez}~~pqx~}zp{|o~}z|{|{sr~zxu}{tv}x~|}v~~{{~y||rwr{v{y}yzyyzw~~uy}~syzwyy{w{~}|~{|~z|xy|~zxz|ux}v|z}|{|v~z~x~~w}kwsqvvryv}lt{~{~|y|x||{zz||zw~wk{x}|qwy~wz~yv|{~qx|~v}}}y{qxyzz{w||z|z|x~|{}|}y}zx|~u}tx}~vxymy{fwz~v{~x|u||vuku}|m}~t~~}yyr}~xx|~{v{nz{}lmy}y{vyqv~{{|vvwxyupxyz~~z|z{~||~o|~x}tzt{y~}}}vu~s~{~{xv|{tztz{{{oyyuuwwz|~w{yx{{|}}u}|yy{zst{yxyyzsyzzw~y}p~|x||vv}v|w|{y~`zsv{~vrx}~z~~wyy}|wnzzzsw|z}{xxv~uy~}}o}|s~|}u{v{~|u{~~u|x~|v{zszy}}|{z{}}|t{{z|{x|xv|tux}jzw}||~}uwxw}jz{~}~}zp{v{vw~|{ywwz|swvvx|~|z~{}}wzn{x|v}y|{tyx}}}~{{x|rs}||wz|~zyxxx}z|~}{zw{w{{w{zz|{xd}vxvxmvuu{|x~|~}o|u}y}~{}x~~x|}}}uxr}y{w~xqxuxs|{{wwwz{y}{m}x|{~zu}v{u{{xyw|yy~s|}yzyjz|yqxz}|}z|v~~|t{y~z~yqvdvv}n~qw{yw{~x}}}xtq~{~{~r{y{|z{zw}yn}|}xy{}z}|sv|}}z~|}pxx|}vy{xyusy|y|}z}xy|{~x}vz{yu}{|xx~}xw{w{rzxxoxz|y}{z{{yztzz|u|wvqozq|z}wxzyz{{x||~x{vs~zyvxuxxz~}z{x|w|vg~w{ozyy{~zy~zy~xvzx}y|~w||~~||v{~|}un}}{|xy}zy}|zzxx|uxv~{|}~yrz|zy~~zzx}x~}uy~}zzzzv|~|you~vn}}~}q~o|~|~~xzy{}}^zy}o{rz}}rvz|||w~yzosuxw}xsw}{}ov|z|w|x|z|l{|gv}|}~yzhzq{{w{~|x|z|{y~u}}{~}kzupy}nsv|y~~b~up}z~|{vy~u}y~u|{kt{{}|y{}|~p~||y~y{~vy|{}}x}|}~|{}||w|zq}xyx{|~o|y|zw|n{vv~wy{}|v~~{z|znyrz{~t~vm|{z~w}}{wxvuyl{y||}x||}so}}{}t{~{~zz|w|{y~}r|x|yz{|}}|aw}o~yrv|x~o}{oyo}~}{vtyzt}}k}~yp}}|z{xwzy~y|zv|}yiz}zsz}|~x~~~}|yv{}yv|z{|x|s|x{|kik}z}zwzo|z}zx}x|w{{y|~y|y}{~{vxtr|t~w|zt{|}zx{y|y}~yw}vx~}|wvtz~~wpzzuw}q}x|xwxxu|~zy~yx{yyx|pq|w{}xvnyuzszs}~y~w}}s{pzzu{q}z{x}s|{|}~wxyo}w~s{ku}xztty}}~~ztvy}|{~ut~p|ux|z|x~z||{~{yznzrzq{~~x|sy}xzuy}{yy|~xr}xz~|~xw}v|~r{y~}xz|v|~xwvtz|w}}z}z}kx{z{z{zwz|{{~sz}}}{|~nxx}yzws{|w|}yrwyn|~|w}}s|{z{~x|~w}|}m}~zzymzxwzyul{{}sx}|w}|jxrx~sux{|q{}tz|hvqo~{q}vq~{twy~}w|x~vx}zy{zzz|z~yxz}|yx{xx}|||{~|u{y{yu|}z}{~}zz|{mzzzx|{}u{y~z{{~y~y{zp~{xyz~~}}zuv|wyvoz~w~v~~t}{~xys|{z~}x~{|~}{}}|wz}vyn}{zzwxxuvsn~~z}vy|tzvyu}||y|uy}wx~|tz{xv|wyqxv~}uw{~{u{qw|wju{q||yzfryryzy}w{v~|~|z||ruyw|q}|z~{q}xty|t~tz}}y|x|}~~}~}st{y~}}{v{x{uzwy{y}|y|my|zzrrm~xxz||t~yjl||~{~}}pstx{wuwwzzs}w}yh{uvz{u{|pwz}y{z}zw~z{y{y|mfm~tqzt}yzzx}}}yw|}{w{{|{yy|zz|~xuv}uy}|~{{~|}v{||xy}~}zyu{~x}v}|||iyj}v~}uqz~zzwt}~wxzz{|zuyz}}}yxkx{wz{wx{~w|}y{}}zw|o~vy||~j}~z|zzv{}}}}x{~u{n~z{xs|xu{p{z{z}{x|}~z}|}|txcvs{}x|~x}~x}}}x~yu}n}v}{~tywy{s|}zxw||y~||}y~|x}{v|wxzt{xztx{wut{~zw~|tr|y~{{}v|g{yz|y}vy}wvy{v~}~{ru~r}s{vxxu~xyo~}|zrytuy}~y~~}|vmxzvvt~xwr|vvsvyq{xusw|{zq|r~{}a~z{|ys|sy|{vt|zvzurz}{|}yxtxz}rq}w}swq~}p{s||r}~ryvww}lx{}}zyyx{{zvqxz~{qu~{|xy{s|v}x~zw`vn||uvyzx{xgxw~wpqw~z||v|xxrp}~}q{{{y|vq~zyw{~}}{w{||o}yv|qyz{{~|~vzz~wy~r{z~xy~|mqow}x}bo{}trv~vt}u~zvw~}txyxw|{}xaz}l~|}}}w}{{z|{xzm|v}s|{{v{vzy~y}{zkl~~`q]yu{x}vuu~v~q{}}xkyx}}}uaxsrwzzo}zgtw{~zsttww|{ywwz|nyW{|wu~{}{wzu}z}}vy}~}{~~{w~x|y}uz~xyr|~trsows||~s~{wx~ztxy||y~z~rtyz}w}y||}yyp~{wsvx{}z{}uqz{~}wt|}yw}v~sw}{yq}zv{xyqu}{~mx|vr~y}u~xv|uw{}|v}wszi~{{||}s~o{|}q{{tzxzqwtsy{t~|l~yzpyywxqmpxw{}u{yy|vw~v{|zv{wz{z}z{xwux{z{~n}|~{yw|{{}u}y{xv|z}w~~~p{|z|~{y{ysvzsztiyz|~|yx}x}|mw|x{|y}{ywuxvwz{y~rx}zxywv}}rvw|{u}y~{tzzv||k~ttomxy}~rz{zz|{{urx|z}z{tv|y|xyu{x|szwy}}v}{~kzyzyztm|yi~z~{}~xv}{}~y}y~~zyzy}r{w|v|~p}tw~~{v{vtxyzz{z{{wow}~xju{{|ztrmvzp}}z~z|}{~vtxx|~z}}n}{zu|~~u{{q~zzkz{}{xux|krvz}|}{~w~}v~~w~~yw|x|~||~xy|xv{{wzjxs{~zt{{~{~~k}}}|tyzwxs|yz~yzrtx||yysu~z~vyty|yvruww~zzx}|}z{yo|z{zxxv}tz~nt}||~}}|wv||}{w~|vo{~xutj||||tx}}x|vy~}x~y|}}|w{z~p~yvz{wtx~~v{tvx~yx}g|}~q~}}y~}pu}x~{}vx~~|{|~}zwx{|~ts}ry}vjzt{wu}o||~p}br|ps{yz{u{y~{v|u~pw}{z|wy{up{~~{|y~|x}w{~|~x|tu|zu{}y~uvzzz}zy}~~}{yxxy{pw~vzz}t}|z~w|v|z}|{z~r|{x}~w~wqpxy|zzy{~tx}~xwz~~z|tmq{w}|}~x~~y}u{~w}~~}{||xy{}~||u~x||w|wy}||}{zixt~}xzz~xww~}{{vuyxvsy}{v~vqxv{yy~~|tw{~xz||}~n||xxw|t~~x}wy{}z|xytr{}~two{qt}|xtu{yu{|~|w|~zv|t|z~yy}zn{|s}}uu|pxvwz{}xl|~xy}uvu~wx{zy}my{|zwyxvw}{z{|yx}{}z|v}vwxxh}rw|zy~}}uxwx~|{z}}{~vfwypt{{qxzv~ry~zq||y~yuy}w}}}z~|tl|}z}z|{xt{y|}zy{z}|qq~~}uzo~{ik}yq|{z|t}x|~~z~{mm|rvp~zyww~y|w{}{v~wvto}~su|{uyozx|uyy|~o}{wz|{v~{o|yy}|wz}y}xxx}~s|tz|{|uuyuyxy}v}|~yx~uv]~e||y}r~xyw}uvuw{x{{~w|~|y~x|zt||z}zxyvzrvv{|yz~||zuw}qqxvx|z}nzx}x~}~zz|~|yxvy{y{yzzyz|}~|}ov~wyv~xt}~mzv}xvu{}~~||xyyt}|w~~ty|~z|{|}~{}{~}{vysz|~|yoz{{}zz}}yy}~z{p~vz|x||yl}{sy}~ww}~~~n|yzkvtu|}{u|nt{zz{z}||t}xv~t~w|y{|t{y|{v{{~|y~|{|y~~}{t}|vtwzy{t{pyvv}~x|t}|y~z|~vzx|zzr{xy~~~w|{~z}s~p}ww}|up~v}|v|{~{{zy}r|zzju~wvv{wx|~n{{y}{y|z~sy{|trus~{vuws{vW|{|y{|}~~yvyz{xwzy|z}yl|o|pu|}|zs|zt~}xzy}y}vyw{t{yh}qv|xyzx{wruvw}~v{}{x}~y||}|{u~x{uu~vy|}wv~|{y{uzy~zyvvz{w}suw|xv{zyuy}{z~x}rzo}}x}}|~z{{|x}y|xyo~zz~{}suytv~|{}t}|z}{pirzs|vx{x{z}|xwz~~w}{ts}x|}||}xy}{|{yssv|w|}}|{}|r}vvrtm}{y}~x|z{zrz|ww~{w}|zrl{v}|y~xoz~u||q{w|quxzzzw}y{x}zzlt}z~{|o{unn}|w}{}w~}x|}vz{{}~Ysx}k|e}}x~}~v~~qx{~j}|~owt}y~|yxz|y{||}{}~qw~}zy~{{}vzyu~x|}}{p}x|}yz}y||p{}x~}}~p}}l~yl}`~}|z{|q~}}q~n~Ux{nxq{zz}x{z||y~{~{ty}tzym{ty{y{|}s|~}t~{x{|~xzqvsrvs}u}~w~}{pz~yx{{}|}~y}|zky}~|tv}}~ox|t{u|}{}{z}|x|uyz~z}~w{v{}y|t}u|~yy|uz|{ze~y{{h~|}{~z}|mm|x}{l}x|z[~}||}~|wt~u~x{}wu{|}vzxvpz{ty|}~~zy{}wxown|{yrosxzwyz}{z~ul{wy}vyvz{|{ywz}|}~uyr}svu{zzzu~yyz~|}~}ywzvwvwvrv}{ux~zzuy{mnz|{}~}wv`v}xq~iz}tx}~ty~zowt~w~z~ytwu}|}|{u~yy{}}{zxozm|{w~{zwx}~zzywy{}xowxyyrxvvvq{ywmr||t|s|uzz}uvyv|{m{}xzn}vru{{tzx|u}|ny~jouzt}vo~yw}zzypz}h{|}zqv}{vrn}~uxvxuz{}z~yptw}z~v~xs}t~frsz~}o}i|tsqxzvvvx~z|}zww{zm{zwz{{oyy|~pt~zuw}{yy|xy}vi|yy{jwzz|~ztyst~l}}ownt|tz~wy|t~wvswlpr|xwxpvqyjmss}r|~~z~u~|wtzucs{u||lsu{q}tuz|}t}pt|x{}yytr~{}w}{|vo{y{zxrty~z~ujxq{}|}oyrwyu~|zo}w{t|zqszww}||ux}~y}}t|ws{sr{yrz`s}~t{vy~_y|v~zxu{x|}q}Zvupm|qsux~~r{x~|{~yyul}u{|ytxu|squvwxrwxwpyz}u}wmy~sv~pl{u}r}yp~s~xzxjy}wnq|}x|q~sy~vvsw}~~wnx}xy}uz}vz}u{~w|}}~~zw|wx~{|y|zxyv}xu{~zy|v|w~z||{{xx~|{txi~~}}yz~|t{~~ru{~z}z~tx}y~||uzv}~vc|wyzdy{~y}fvkz}}zz}x|x}z~}ux~}}z}y|z~~xyy{~w|{||}wwdtxwz}|~wwvv|xr}qszuzz~~sqy~}v~~yk{~~~~lpnu{v}~xys|zzs~t|tvtxt}{|||yyt~|~rxwypq{~w|tgy}{y~}{}{r{s~xzww|xw|}|}q|}zu}{nt~x}}~~|y~wq~~xwjyx{yz~rvuz|}}|uv}~}vu|{qyp|~}w~u{|w|{{~}wvw{}vsu{zx{~zt~}yuzpzhvxx{z|~z{v{u{x}~}|~x||{~}{y|y|sw{~xwuuyw{~so{{xy~}q}|~u}}x~~u{yx}x{}siv{{|}z~||{z|}w{}}{yw|z~}zv|u~x~y|}nz{ww{~z}z}svxuv{{tyurzr|vx}}}~|y~x|zw{x||~|{|zx|yw}|x~yy{y{|v}|||xzzz~|yz|u}xy|x~u~y}r|}q|}x{|ut|yv~x|}~p{}y}w}nzxt~|uvxyw}~y}}}~{yw}{ozxwzy~ry{{|w}|}tx}z{wzzys}ty|v{|quov{x~}}z|~wz|yq}rzu|uz}xwvqxsy|{v}trw{lgywtxu|~|yx}|~y|tw|{v{}x{ysp{}|y}zz||zwr|~}v{v{xvw}}w}}yu|wyjwo~yy|xw{iy~z{}}}}~r~z{}wo~k|}~yu{xzzt}}i{||~}zxzz{~|rxxzxxyy{t}uz{~~}x~{}|w{{s~|}}z{|{x|{xz~wx~{}yfz{z}z{yvx~zy}s~||{{~{v}zzz{tzu|t~~~~y|Y]z}s|zx}|x~qx}tx~z}|zz||~xwyuxq|}{xt}|~q|u~w||s|w|s}}|}zz|x}}~w~x~v~~wq{pn{|uv~}w|yy~{z{|~y}~r~}xxh|{x}vwuxs}{tsvwz|u|}zuy|}}z~}~xsyz}w{z{}zw~{vx|ww{}~}y~|oqvx}}~xuy{rz{y}x|wz}u{vp|{q}{y||s{x|~|~yzv{z|xy}}~zulxuswwz}x~}xz~y}w||}xyjpy~bw}v|{qz}|z{w|~}{t|~|{{zu~|}{|z||y}{qxxzpy{t}zy|}~|x}wp~o{x|||y|zx{}}c{p|~~wx{}}uy||zy~}zp}yx}w{xsw}~}y|~|}{{}[~i|{q|~yx|~{{}|~z~s~y|v{d}w{{}}|zsxxy|vzz}|{~}z}yqu}u|r{zxzw|wxu~yw|v{z|{~y{m~~y~~~}{yzwpus{{x{}z}yywv{{x^zrv~{yy}u{{ytt~tu}|yr~|zvw{y}}|{y}|{z|u~x|~{}z}zwzp~{}ko~{|{|~|{v}|{z|~|w}|x~v|}zx{{u||y~x}zw|}}|~{~{y}wy~}s|z}x||x~z|y~|}}zx|{|}}z|~~sv|r}u~}{s~m{~wr|yxt}}~}zzy|y}u{~]v~}x|vz|v~}{y{}~v|zxyz{w~~|s|xs|}y}~{||}{tu{x||{}x{sz~w{v~}}|}{|}|{tvz{{|uzk}{ubxv|yq{z{qyx{z}zy{|ywzwu|{~xz|vz~||zx~x}~}{z|}y}|yw~{xxx~}|zv~}x~{pxzg~}{||y}}y~z}||yy}wy|ww{l{}w}{~{u~~qz}{y~{vr~}{||y}wpyqty~|y{~~||q~z|{v|}}{x}wuz}}~xt{s|qwz}y}|{~n|~{sp~~vzzww|zt}y|~zsx}~~yvs{}u|x|}o}|~}~|~vv{y{xx~zz|w~|y|{|~~~~m{|||q{~y}xytttz~xm{}{|y{|}w|rv}{s|~y~s}}|~|ixz{zzxs}{z|z|zz}u~xosz||zrx|}vpx{|~}~{|zwz{}{sqwz}|z{~r{ryyp~{{~s{~{|}|{sx|r~{~xzw}yurz~{}y|zx|xzu}uy~zyz|}xxz~{~}{zv|krz{z|{}z|}|z}w~}y{{y~{t~|t~zy|r{z~q~}||yz}z{u~v|z~z~~zyv~{|dx}z}zy~r~yvzzzt}zsw}}{~z}|}qu|{}s~tt~j{t}|yt~wp{yz|z}xw|{~~ryw|}|tytuus~}}}zol}{|}}{yyv|}|~x{|}~{vo{~wv|}}~~~|~p{{oy|x~sw||usn|}}vw}}~{kx}yqy}w}{~y{}|~~y|stut~o}}{m|qqy}}s{|~}}}~zwntpz~yx}}{{xpy~nv}~}}~|t|}v|{~z~~}|v|~{t~}~||~{rt{zuzs}~|}|~vxuwzr|u}lxx}x}t|v|xv|r|~}z}yxwwv~z{{}~z{u~z~~su}xsw{}w|}wuvr~wyy{txiunys~~{q}vpyykt~t{}x|{zz}yr~z}wt|v~qx|{q{}x~|u}w}s~s|}y|upwlq|z~~wul|qzzvi}zz~}x{r~yxotjxxyy}q||swvwy}qdqppr||{{}[}p{}uszyy|x~sxw}{zr{xoorwrp~~~w}xqjwwj}}ystj{ow}m{xww|t}m{|}sp}z|zsryvy}xuo~}uwir~y|~gr~}tww~z{m~q~~tz|g}wxzu}{|km}}}wv~yyzy{z~y|~{|yo|w}v{sw~|cw~u}wxr~uo{y}sips}nzw|yv`yxn~z}~y~~x8trw|tuzuuvt|rur|vw{|}rwryvu]|zp}}zywzyuvsqy{|unt{vz||~xyux}tz{|yzz~s~|{rvwy{}s}xoz{|yx~}wwyx|~~rsvz}~}~}|s|vw~~zx}w~}|ywvz}i}}tts~svx~zyt|ty~}|{{~}oy~}mw}|~{uw}y~}|zy~xruz{u~w}|zw~v{~|~zuxyz~{s~}xuu|zz{xxzz|}}z~{|pv}{syvi}{{uvyry|yo}|yu}xzw|y}uyvxz|x~y}yr}|||{x|z|}v~x}|{}{sy~z|}{v}~{yzn}~}~}|zq{Q|wz{}ry}ovx|}u~~|{}~jww~wbzy|zztx~vvzx}y~{}xurzyzy{wm|{{z~ywuv{}zxz{z|vvxz~|}y~|~{k{sz{}uy~z|qyvxv~wwys~uowzw}x|{vvy}y~p}smze||~yrr~{yz}vx~{z{rv{ztv~s{z|ty~w~zx}}s|z|rzwyy|~}z}w~x}~s{~wzvx}~{y{vwymwy{|r|xv}}|}zs{{{sy~|yr|}v}}wvpyuvnu}|wyx}}zuu~w|styz|t{}v{vy|z{y|vty||}v}t}t{zwxrvy}zzpy}spyyyvvu}o|~uv||~t~uyzy}|w{t{w}|zy|xl|zwuy|{z}}p}}~vz|y}vw|zwyz}v|yr}u~y||qtxxrz|~vysw{s|r}}|vultvzlw|yv}~{s|||z~zy}~rvvzxw}|}~zv|xx~w~|{~wyx|}u|u}z{~z}{{wu}syxs}z}~x}vwy~}t|xsw~}~{~{}zzz~z}}yvzzp}|}y|~uz{~|{~w|uyw~vr}|xryuzxp||w{|v}~|r|u{{wu||t}y~x|zv}y|xwzzzxz~~|z|y{}|}}|w|||}trz|||~~v{|{|{v{|}{}r||zz~}~}{||zt~~|~|zuwz|tt~|{qvqxyv{qxz}~vyxu~~w}uz}r~unuz|u}|yt||ys~~}v|swyzyv}xz}{|ys|~{w}{}yu|}x}yzgwz~||yz{}z|tz{s}zttx}zszvtzx|~z}y|zz}|x{vy~l{{z}~t|qv||~|}|{pw}|||x}x{x{u}x|zzzzmu{u~}~~~vv~yr~~zx~zzz~}|}|z}{~u{|oz~}z|}}{}t~u{x}~x{{wzxwzwz{~~xzzu|}~y{{w{{x{vv{|uy|vy}}wzz|yw~oyz|}w}{y~|v{y~~|{vvv{zw}x}s|vz}z}xxzvoy}z~~s}|~zzx~xv~yz}u~xu|ztv}jvryy}|xz|~{}y|}}{uv|{v~z}y{}}|}xxw~xx{{{ss{|r|~yy}wx{x}{vzty{{z~zvt{}||}wyyy|zw{|m||xroxyyty~q}yz}{xew|~~}yzyu|yyyv~yr}w~~wz{|~xx{t|y{~~w}u|z~}u~q}zy}x|}|~yxru}ytxzy}pxx}}{~||z|t{}}~}{zy{{~nz|t}w~~z{~v}{~}|t}wyvsyz||jv|||sxywrw~{n}~vy~}|z{uwwst{|{oy}ywrz~}{}x}{sn~uzz|{u|xlz{z}zy|hy{||||{{tn}vwp}x|r}|{}ws~yi}|txzyzyzuxuw~lx~}x|~}xyzssuz}~}|z~tos|rx{y|qvzt{|wyzu}{~}zyyxxy{n{nw~u{{}}x~z||yuyys}{tyvyv{zy|{v|y~zo|wst~}~ywxw}zzxzn|~{szyxxwx~x|usu}t{|zvhp|y}wtym~|yqt}w}ww{x}y|wxp}~yx}zzz~t|z}tzx{z{r~{z{v|~ww{~vz~}tr}|{||zz~zu}{y~{}|~kwts~tz}m{~}wzz|zu}xq|z}{wx}}osxvyy{xyyr}~{xy~yxyw{z|yzxryv}~h{r|y{{szy}y~|~ytyzvotz|}xlzzrzw}wy}m|s}p{z}w~{}v}}xyzqxz~q{|}{v|w{}~{}x{y}xvt~t}v~}{z|u~zy|x~{}}w|{w{z}w~|v{~}v{zxz~{~t~~us~y}}}~}}~{}fz|~wu}|v{~v~rtn|x~{}~{|z||x~y|||z{~||qz{|{}zxx{z}}w|}zts{~zzs{|~|{hwypx}t}~ve|~z}{yww|}xvx~~~||zz}zvw|~s}}}}u{xyy~|jrwy|||r}|~}|fz~{z}|yx|{|u|{|ztz|x|zvszx|zxizw}~wz~}zz|w}y~~{|}kx}{~~|q{|~z|yz|}}z{x|~yxx}x}wz~|w}{y}}v{w|yjv|v}x{j}y|yw|s{z|{vzx{o||zu|zywyv~~|y~|z|zt~~u||{~}vw}{}z}~x~vty|sxuwz}{v{~rsly}||{v|x~zxwz|{z{y}{}|t{vywlw}||~xy~{}{|~}rt{|tz|}z||x{y}||zz~qxktt}v~||}~xuwz}s||w|v{x~x}{vz|xz}~z{}wwyv|}xz}z{y}}|r|pystq{w|w{s~uyx}|||{u}}y}tuz|~{}{z|}~|rvv~}r||wqzzp|y|pt~n|{{{ywk|z{}|xywpru|ywvxzw~}{vy~~}z~{{}rzr~~{zy|yy{wqy~~xyz}|zy~u|~y~||}u}uu}{vzxv{{ytxsq{x}}}z{{wzwzz{zu~{y|{z}{~zv{z}xqtw}}}z~y}x}dzz}}u|n{}yt}}}}||t~uzszov|{}mw{}{}~y}y{~}v||{y}}|xztu|v|{wy|{|}|zx~uztqzu~}~}x}{|{|}z|z}|}y~~~t~zpr{x|}ix|}~azxu|u}}|~}v~}|}xyz}|~v{~vw~{}}~{w}yy{wx}~}}}v{||~~~}}v{~m}~y{~|}}~|~{~zyy||}o}{|w|x}|z}xw~}}~}}~|zzzxsv{}t}~|w{~y|}|z|tws||}{n}x|u~m~}}yz{}|w~}~yzrx{|}~||}{x}r}p}~xoxz}vvi}x}}|{tz|v~~|||xz|z{~u~|z{~z}uy~}ywvzzr~y}y}~h|z}}u{}~~u}d~x}oy{}|z~y{~y{~sqy~v{}{sx{~zzxy~y|~zzxrx}ws{v~|}yr~q|z~~t{}{}xwwq~~ytos}trv}~|{~{v~|{xvxy|qyw||}t}vz~~z}v~{x{v|{z|}}}vu}v~~zp}}|}~z{~}yvy{v|z~}|ztw}zvxu~z~{}t{r|{{y|{|{|q~yy~||wvwryy{zz}y{x~xx|{{k|z}}~}z}}{ri}||{vt{ryyu{uuzw{{}vy|yq}uwz|zvq~v|}|zwx{o}{~wxz|~ywz{}r{}zzvoE{y~u{v}vs}z{yz}~}}|}x|u{w||~{{{wzz{{z|yxy~{}|zyzmv~}z}y{oivw~x}wt~{}xrq~v||yy{|swvv|}~|}}}z}usy~|y|~w||s}ns~{y{}~}v}~~wv}z}}zx~z{u|xy}yx|~u}}u}~rvywz}t|{w|u|y}x{zx{u}~z|yx{x~{z{yz~}yu{x~~|o|uz~vy||}~x{~z|}v~|tt{|vwxzm{|z}nzz{t}~w}hznz{yvttzvoo~v~y{y~uxv~~}|}}{|x~s~uv}}}{{{v}|x{zlz|s~yx}z{wv|s~`{|~|z|zywl~}}~lo{w~|xz}~}y}~}}zer~~}|{q}otjn|zy~|{ykn}}xw|~y}~w}zxx{|}|~}y{}||v{|zx|x}sw|u{x}|{ut}w}~txuv{zs~y|yyz}x||~y|z~|v|o|{}Y~y}{}v|y{x|}z|~~{{~z}{x~x|yy|s~wx~m|t|}{}ztu{y}wy}|~}~~{{x{~zlmw|wxu~||u|~|m|}yzw~~|{x}|z||yw~tu{tzu{~}v{}{||z~z~~y|xw{x~}{{|~z|}y~||lzw~u|z{yy{{|xx|z~}~|{uw}y}||}{}{~}~t~vxx~zw}r~w{}}}}{|q}vww}~v{}y~|x|{|z||zw}s}zt|}yy~zz{}y}{|}kys~w~|y|}|vzyyupozww{x|}z~~~{zz|l{y}}qy{yxruz{uw~z}y~}~{{zrvs|{z}{|~|{}t|z||u}~~}vx~n~o{||twyx|~zu}}x|{tyv~v|w~y~|}|ux}t{~|}}v|ytw{{wq{~wvto{~|{sxzy{y|wy}}t}yk{tz}zujg}z}u~su~}{~wq|p|}{~}wvyr~swsxlx{xxxw|}z{wq|{|v|q|}yz~un{t}yvnz|zyzyzx{z~~~|{~x{t~y~}q~|~xqw||yr~zw|z{q||~||V}yzv|svzxtr|z}}sz{~~{}q{uvjyy}~w|ywzxx|xry{{ytvxuvy}{}~{w}uzt|zxy|y~p}{zuv||y}~ywys|~~xorz}{zux{x~}}vtxu|x{wzt}{w{|~wu|||~zqs}vu{}ud|}~z}{wvz~zsx{zz}~}snzxur{zwypus~{{~on|pzpvv~vwysr}ryw{sxsp{yvwvs}~}uz|{v}}y~}sk}v~{y}}|ooyu{}}|~~y}|{~~|u|}yq{z|~px}~z{|w}}vy|t}v|yz{|}{|{y}{{{}}}~xyw~v{qyw|zy~}s}}wyu}~x~zw}|}}z|}}wyyw}wv|}z}|yy|{z}}}~uk}|{~z}~y|y~}|uz}}xz~||~r}|w|y~r~xwu~{y}{yw~w|v}n~u|y{y|o{~}wzpqp}zz}|xy||zf}r}z|{z{}p}}w|}qn{}y~~yxrf~|~|~v~{z}~z~x~z{~tw~|wu{zzn|}|t}t}y}}~|}}w|yz{}}y{}~vs{|||tz}~z~|zuzwy{wwu{}{w}}}xx{}||~|{z}xyvwfxw{|n|y|wvv~}|}wv~|zx~}xt~~{k{yyw||{}z~y{yx{y}~v}|sx}t}~w}}v|ֆ|}zzt|z|yty~yyx~}}v{}~~{t|t~yzz{z~{~xz~zo{z}vvr{~v{~~|{{{zvx~u{{}~|~}z}wx|}z}~z|uz8}{zut~yvzzx~||yzwuwz{~z||w|q}}|~xt{}~|z}}}~{wx{~~wxyzzzz~w}z~zv{}xw|vsvwyvzw|~~~u~~}u||zxzyvy}~}~|xv|vr~z{~z~yz{{}mx{y~zxz}~sqpzs{qyz~~z{|xw}{~uv|}v|}tw}t{x~xz}vw}yxxuyyw{~}~}y{zz}wtq|vz~~||z}~wy|}y|{}{w|s|pxtz}zs{ts}{{{{yw|{zy}uvw~zx|xz~}z~w}~s|suk~yn|suYh~ww~}z~q~gwy|vvt{yrtbo~yvwmv}|w}yr|~x|xv~{}zt~rt}|ww}rz{w|~{|{}||~}}}~y{pxy~zp~|{ww{~o}wyx|zp{}z{u~o~{~yyvx~{vx{{x}}tszyys~{xy|ty}zuv~j|z~}y}r{u~{~{r}z}s{}t|a|z~xpz{}||u}{u||}zy|vzynwx~v}yp~zx}|o~xqxz{{|z||y~zuzzrt}{vxx}|~}um}zuxw}yzs|}suxxy{zvsd{toywynxywuqyv{~nx|w}t~{wtyzz}zuvwy~~}wu~|||yi~uoz}}{wy|}uu~x}t~~|w{|ts}}~w~z{z{~pu|yxvzyxzZ{|zyzt}{xx~s~|ts{{xq~uxw{{~r|~wxvxv}zxn~{x~uvv|v|qpt{}o{~y}qyw~zyys{rz}vtozuzywzss{{x}{s{}|z|{xvop|z|{zrz~w|xz}~|oux}wjxowszq}}~xtnyy|s~}rxx{r~w{uuwu|vw}|vtzqz|zy|uzzx{{~}v}x}yy{l}xxvuzo{{xx{z|~u~yiutyxrqvu||zw{{xxz|xz|yzm{~pzy~wxzqxwv}~}|mux}z~wy}}{|xs}z}~x{}~fkw~zzwt}vso{}||ow}x|sz{mqytw~tyy}~}y~|vyz}|}wQ||}~sq~y{~}~{x}{tz|}j|x|r~}u}zyyrr}v{w~{ww}{z|y~wxvu}y~|ou}x}vzzyut}|~yvwyz|wuy}~~zzzyrw}zy}Ss~|~f{u{v~zt|~my}ut}u{uzt{u|}{Yy~}{x~~{{hnn~ytt}}xyvs}hyx}~zxm{uz|{x~z|t{iw|ypv}zz||yy}zpzq~|v~|w}|~y|yyy||t~yy}}z~xttttzur~{|z}xzhxyqv}{|v{~|y}|~x{vyus~{}~yzz}z}l~y}zeu}}~}u{~zz~vz}|i~wz~{{}xw~o{~v`x{~|zx}v{n}rxy{~~~nw|y~wx|m~z}nzi}~uw}{q}y{y}|w}y}z~~x~~~|v}y}{{~}|~}i}~q|zvywy{lw}~|w|{|h~|{pum{y{z|~|}}~~{|}{}}{{~k{|z~|y{z}uz|{~~}zw|x~}wwy{uu|zz{ts}|v{}y}_xd}xx}}{q}mzw}w||wzyyq|}{y~{v{~p|||~yr|z~uxxu~{{}~z|xxy~|{p~tq~xq~w}zq|kuynvy~z{||}x}~uzq{}uu~yqpuy|v}~z{xtw}|~xxww{sx}f~~|{|r{}|z~}~~{w||}u|m||}}z|{xy}|~z~s|x}|utywxrwv|{{z}|||~nv{yw}zx|v}}|p|zvy|zu}}yz~o~|www||{|y||{y|}w|wwtn~|to~swy}}y}`r}y}v{i~{~m{s~|~w}|~~}~|yux}{{|}||}`}vx|t{s|}z}{}{w{x}{s|{z|}{x}}t}w{|y{uzz{x~z}z~w~zrzy}zy}}t{vwxx~w|k~~}zvrjvzjs{}|rxy{vwy~~y|w}}}x{|vxq|zx~xzt}}wqj~uptpz{z|pz}z{{}~i|||}}s}|ytx|om{qww{p{}j{|}~|u}wut|m}~~~y~yjo|~|ww}~y|w{m}mu|~~z~|yvyr\t~|x|{xyy|uzz|~~}wz{y}zv|u~{~|~y~}}|~}|vwsww}y||z~{z{v~~w{yr|}}z||}~v~vwjz|{x{~vywz|}{{w|u~n}~~y~qx{{tpv{{t{py|~||~{|r}zx}}u}xay|}|~{|z{}y~y||~~~v~~}w|mzxp|{z}}{}}{wzz|tysz{yu|w}r~{~~z}qxu|xt|q~||s|||{w|~}|z}}wyyu||}{z|w}o}}n}r~}xr}yt{zt}z~srqz}}zv{q~vu{}|}~zxwzxy~~}}s|~zyp~wp}w|{~yk{xt{x{{|y|x}v{tzisxu{{vz||}x}}{n{~ux~{}{{wz{xxxv}x|uw||}x|xyt{zr}wyvz}yu{zy~}rzyzt{t}~xz{}yux]wt~w{}zw}w{|}}u{~w{}}w}oqx{z{xy|tzywt~~||{{w~ty|z{s~ytwr~rzuv~}}|~|sp}{ytxuy{u||zc~v||vtxzs~{}~~y|x~ws}|yxx{|usz{}|yyy~wxwz{~{zpx|yv~{}{n{x}||wwuux||tv}~}~lyr|t}z{{nru}|}~s{wz|~y~{r}w|w{w|zyyns|{p}zzx|stzox}w{{{}}~ytyz~{x{ry}||jyx|qvu|x~tu{|y||}{zx}|xw{qyyzxwxt{y}~|{xy~{{uzo~{{t}u~}~z}~|~|zzvvxv}y{~u{|u~{r{|}vzs{s{}~z{|wx}}z{x||wvuzwzzz}t}y~v||}}z{}xz|~}}{q{v~~g~{ysy~}vz{}wz{}~|z~{tyztz}|xyxsr}y}~}~|~}}{ro{x}}zy|}zx|~xmx{{uswz{q||y~}|}y}|z|{{|}yy|}vxtz{wwy}t{yuvt~|{~~x{zwp|q{un~|z}}w}l{n|~~usw}}~zzwzwv}x}ov}{{~zzxo~yx||yzv~|zxwz||{zyz~}~}{qt|}y{~xz}zz||~|y}}yv~~xw|x~~ny{}hw}~x~x|zzw}}}hx}|sw}n~~|}w~{~x~~~z}}y|xx~}|}}}r}{xk|uzzz~}v~zz~w{o{{~y|{~}ywt|ny}}sv|}mz|uxo{t||rw{z{y~~s{{z~|w~puzz}y~}zy{vm}q~|{z|~{ju{{~|t~~m{{|~{yvt}|zs|}z{~}}}~s|~vwwouywtzwz|d{}{~{zy~|x~ow~zz{}}t|~|z||r||tvz}}x|yyu{||}z|yz}~r~wpwty~{}}z}{x{xwyrxy~|~}{}r|||}{w}z{y{ux}z{{r{}{~}wvuu{{wzz~|}zs{{|x{|z|{rv{xqj|{|wu~zyz|}{y|}~{w~xz~w}{|}|un}{zxxx|{|{wy~{}{}xzo{[~yx{{ykyzp}~yj{~}qr{zkz~jl}~rysyvv|u|trkzzw{wrwys}w{vvz~|v{tzwtvyzp|{uj~{zoyz~u|quz}mU~~pmu~zs~{zv6]wuv}|x}lffz}txz}bq~n|lyqy|}r|xt|y}}xy}sxilt}l{yrsvt}r|x~{}{{~}{~|{yyluqz}o|}{q~|lwzyl~|}kWsysvx|}wxv|[v||x|xz|hvt}qyrtp|utx{t~~{|wzz{tzwwm~zyuyyzyqzrywz{}{z}uyuxsh}~zzo|~zvxz{zsre~wvu|yu{~b~svvlzyq~~v|syuqgv|wsz|}vmxzuxyqw|~xvg}|vu|xm|tyv|{sy}z|ktu||w}vxp}r{z}ynyz}}vw{ny||zw}nz}ozyvww|o}o||zy||y{~w}~~}~}~z|y}{{yxtz|{y}}}|~}~{{w~||zy{~|z~|x|{{|r}up~vz~|sp}}xz~~~||z~~|{}{}{v|u||z|q~~{{yw}{z~||}|}|x}}}yxyzk}~~}~}}~tz~v||v{|{{x}|yx~x|}ez}}z~}{~y~|}wy{zw~|ysy~r~{}~u|v{y|yzz~~||z}x}~r{v|}}q}|z}}nx~zz~}x||u~~}x~x}}z}|sx{|t{zv|xv{{x}~}}{~~yu}z{w}w{zu~zxqw}{|wzu}|{|yx|}~tu{yt|w}{}~rwjo||y|z~r~p|{m}}|~yuu~y}|mzyyyz{ty{z}|v{w}zxvyz}ytqy{{sw{v|wzw{zuz}}{}|}~x{vy}|y~ssr{tywozty}|~n{}}xr~{~|{p|~zz}~xwvyzzps~~~|zy|{{|w|xs{|z~uy||~p~}ys}~~|~xz}q~~{pz}x||yn}zt|ov|}y}{~w~{v{x}y~qzy}zvzrvv~y|}||wzw}~uw~{vvzmw{vw|{xp~|{wox}{}}w{w|yr{z{}}v|}xt{~w}}y|w|un|}sz}|~z}uuz|ytzr|}|~{s{|z|yx|}uw{yqxzyvw|wzyyzu~y|}{}wsxtp{~v}lzxzus~{}z~{wu|{{}t~~}}w~r}}w|}zyn}zq}~{w{}{z{q|vv~y}twxyx{}}yyy|x~{oy||~s|uxqzz{{}t{{xv~{}}}{|x}twzyxv|p|~vz}xy{}yuw}x|~}{p~v|z|v{wwxzv|~u}~~rw}nxw~xz|{t~x|v}zx|{y|z}{x{uwt|v~wq{v~vv}us|{sn}}v|wryouy{w}yup{x~|s{z{~{~|jy|||xvx{uy{|z}zsv~}y|sy~x}r~v}|{{gr|nxsw{{}s}|}w}}~ruv|z|zw|~|~xwu~s{zy{y{zowy}t}yxzy{{w{y{~wty~w~xwzzq|xz}||w|{t|~z~}ppv{tz~|wxtyx|}x~y}u|~s~yzm|n~{}}|~}~}~vy{{l{t||~~}}k|wz~}u~|}|vxyyxpw{x~~z~|~w||tw~~y~||t~u}}|~~yzwx{z|tz}zr{{{yx}~mvy~p{yri}~zvmy}y~~{lz~~z}u|~}vvy|y||yyz{uw{~xqs|||}|~j}yr|xx}|{y~zu}zux{q~zx}}yy~u|~tx~o}~s}xons{{vzzyz{}}{x|w{qyw~v{x|}~ywu|{z|y|s|zyx~~}{}vutz}}~}{{q~w}~}}~~~uut~z{x{|{~~rpqz|z|zx{znqrz~zo|uz{}zs{|su~{}~y|{tyxpxu~x|{u{xx{{qy}~t|x~o|wta~|r~~v~{yrxw}{}|zz}y|yz}}~~}}v{vwy~}{z}{xzr{}ti}vz~{ww~~h{{|}zy}vr{kts||y{w|{|~y}~Tw|x}{|}||srw~~xxvw}otyy}~x|}f~~v}}z|~|y}s~~{w{zy}~u|}xfy~{}|~}x~~vo{{}s||{|zx{~}||{vix{{z~{~||xu|~x}~myu~zry|{zw{}}~|yzt|{y||{}wlxrs}xy|{vo{|}rn{ww{~|r}~|l~{jp||v||~x~{xyz|vz~|zy{m{|}~~~}rs}{yw}x~v{v}||{}~|{{}sv}~|n}yyxy~z{yt~u|}|p{{hzr|~z||~yt}yuzvzx|xu|p~z||x|zs}~~~{}Z}zyt{|}s}|r~r}x}uzy}yu}}w}xs~}zvu~~ot||{y~w~~}rjcw|}z~vvy}vzt}{yt}xzzx|puzxvx}~}w|}zuxbwv}x~r|~||vty~{wbvysz{x}xz}}y}{|zz|{|s}u||{|{z}wzy}w~z}|uxx}{|uxy~~uu~|}z}{z}uw|zyz{s|~j{|}znz\~{|typ~x}~zo~u}bvoot~uyux[|vz}{zi|zzz}qy~}l|zxspu}x}{~|||}cs~y}{r{uk}zs{lt~}~xgevstswz|}||~y~~|~tz~o{v{u||||zy|rs}y~hjryq|{~|{|~yyypyw~t}}zz}{~~vw{xzx|{z|wz~|zxz}|xt|xzzytx|k}szxry}yuvvx~z}w~i}~{|w{{{{|xvmv{t{xqyprvxqsx}ry{r}~zw{vyz|~|s}|yvz|~|zwyz{{w|u}}}xyx{x~y{r{z{k||}ky~{zw|~wr{x{}vqa{tx~yvrz|z~~vyw}j~{~~s||qvt{~yiz~}zx|y|zo}|zx{uyyk}x{{~y}z~yy|}wpuwzowqsu|~~v~s~|y|ypz|}w|vsx}woz|xxplvoz{y{p|}t|v~wx~u}xrzv{z|jzrty}wy{o{w{~p~o{y}z}r{~t{~~xvu}y|{|xq}v|{xsk{z{~}y{rvx~|ynj~~uuwwv|py}}u}u{{ozqy}yr|}~}}ut~|y}}uv|~l|{{xx}zj~s|y~y||wwv{~~v~v{bu~}{}}{|~ty}w~s{swyq}~y~z}ow}yw}vuzl|z}pt~oz~{mwzy}yy|~{uqy{}{}yz~ut}r~{}|wv}}v|{z{pp~txz|uv||zp~~zy|}k|}}vqxuv|zy}zn~o}x}{||x}~yoz{{}|x|}fzu}r{v}r|ywy|}z{w~i}|y}y{x|{}z{olsxy|}v}{}kwn}xvy}~w|izox{|ymrvy}}wxzyt}|}eu~ywwty}p}~~{i}zz}{}x}ox}xz~zuzzt{{u}{{yvr~zv~~|{z}y|}s~}}|~{{rx{}}}}t|{t{~}}uw|y|yh~w}zxxz~~{v}y~{ww}||}zzvrrytwz|}|ynvt~zxwyr~|~t||~rsw~}}z{{vzsp|vlv|}zxy{zy~zr}{~{x}}uz|wx{st{|{z~q{~wz}w|xzzzk{zz~ux{}y}ftzkyoo|zv}{}w|~}~z|zq{r|x{w|z}xzyyy}xzuvkzv{{s~wzrw|}z||o}{~qur|v{xmz|x{|vt~|ww{r|yzmwwqwx}||s{|}sx~|r~v~{x~{oww{z{|u{y{w|~x~z}}uxyv}~{}z|zy|m{}}z{{z{vux{yvuspm}wwyutk|w|wswt~{okwy|wy{tyr{ws|xt~{z||x|ww~u{}zz|yyrltw|xxsry|zuwnypzyzxvzr|vv{y_t}vy~~tyy|swx}u{{|~vs{vxyx{wo{}ywyu}k{{|y{{x~}mzwzww}}x{}uwpty{z}~w|v~{x}}s|zzbuu{w}}~{}nx{kz|~v~u}s|s~zwr{||x|~fy||qz{}}{x|z~y}{z~uy~{}zz{||z~{~qzvu}~rp|{u{z{{uwzyy~~oyv{x{yxt}~}|wy}x}||~{y}}pl~}zzz~wuw}x|x{p~}yzvu{y{x~xy}r|y|tu{o~}y|zh|v}u|yt}||zswv|vl~wvuxyy~uzv{|{}wy|xqvy~}{u~y{y~v{}P|}~vv|r}|}z|w{|z{xv~zxx~yu{u{`{zyz|lzv{}}|~s}~t{}~xmx}n}}{x~}}xu|v|{}]zyv~{|~|x~{~}y}}~xx}~vv{px|}y~}|yz{z{v~ouqsv|}}|vx|{{xzz~{yp~|xxzu||ut~~}}}}ztvu~{{z}|~q~xvw}zs|zwqw}}}}~}z|}ov||{|v{{p}u}yo~yzzyuy||xznuz|}}vy}~u||w~m}}x|}|}z}}{u~|vt|}{zz}{|}~}~{y~sxz}}z}}|~{}|||x~~~~}~yy~vz}z|yzxul~ww||zz}qz}w|w}r|v~~z|~{|y}q}~zzwy~nu|w~z~~z|}|vw}|{{{}o}y~y~|{n{u~{~ox}|}{kv~j|q~x}{wrz~v{qv~w|s{sr|izz||w}z|}{xj~}}uyz~~zuysyzvq{q~||~yxqztx}}y|z|ev~s}r}}|wwwy}z}wyy{p{{}z}~|~}|p|zxkq}wy~{|u{{xy|x}}}|w~}~ww~}yv{|}xfr|y~|||e|zw}zl|qxu|~uzzuuzpnry~{{yz{}s|{y~vw{xspx~}zn{}~|~}}z|~{xynsyx{|~zwrq~p{iyy|||{~m}|}x|||wwt~|yyx{q}|ytl{z|~vw}yoil}w{~}}|z||}v{}uvy}x{t|~~u|iw|s|}r~}}wwy|}|}y{x{y{~o|p~{|~}{xztt~}}nyu|zuww}{w{~w|xu}|x~~u~xx}}x{}{~wswtw|w}x~{w{|{p}y{}}{}|w~ow}v}u{~|~}|u|zo{{xr|~|zwkz{ys~zsu}t}}~}uqu{z{~{xxn|v}}zv|}|y{{}yz{~|{}{t~}xyz|~xz||{}~{uyw~|sv|~vrxy~uw}x|~~vxyzqwp}yxzv|}p~|~|}{}{v{{ywyz{{}~u}~zwx{{yzwryyu{w|~|}{ux}|v}u~||rzwx{{s~r~|s~~u~{}xwyz{|~zx{w|~|}yv}y}x~}|~}~|{{~x}u|{|~}zzyw{y{w}zz{{y~wxz}~|x~{xu~y}o|xx{}vu{{zxqm~~{~s{ul|rz|y||}yz||~xxszs{y}z|{z||ww}xu|y}}|{xrz|||wwz~}v}}t~z{}xzs~}v||~~{z~wqpy|}xo|zum{~u}zx{xx}wy|{y~wxwt}|vuw{~}~|}k|}y{zxxu}rwz~|~}{{~w|y~v|}|xz{zvq}z}z{x{~}xs|xv|vy|~{}y}twy|r||w}yzs{}|u~|~}uy||~|{zuzw~}xw{~v|xy~pvq{z~w|}zzw~u~{~~{|~}w}{v{pwyx{{w~{{z}w{|~ww}wz~}zc~{||}{u}yw~x{|zyqz|t~wyuxx}~|~zuv}z}}~w{sw~p{}}{xw{}y}u~}}j|~~{y~x~}{w|zx}zx{}|xz{r{zzzy}~{{}syzu|t~tv~~|}z{~uy}z{}z}zn{w||z|{lz}~|w~zx|zpv}yt}t}|~r~}{xxz}y~~uwzzw|~{t|zqy~xyuv}{z|{z||wy~r{~}{z~||xy}us|u|{w|srv{~v}}y||}~zz}yy~xzpp}y}y~w}{ry~|vemr}{xzx}yy|r~yu|z{y~}xyy|{|z~}{}z}|x~q~ufzls|u}{z}}ux{cwz}p}{y~|~x|z|x{ry|w~{{~ryz{v}}~~v{zp~{wu{zzzx~{{ys|z|x||||~y~|yzuz||z}wz}~|yzzzzty}}||{~}~|z|yw|z~}}~w{y{z~zy|{onx~wzvwx}||~}~|z~{uz||zxzzz{~z~{~}|~~x~y{}ty~~{|z}z|}umz|zyz~y{|}ryt}~u~}y~}~~{|~s}uyry~}u{y~{|y}|}{|}vqv}w~~~|t|wq~vzzy}||tx~www}{{{|{~y}z|}}w}zxy|~vx}u~~|}v}zy{x}w}{}|}yo{}}~z~sxwxr~t{}}u~v|z}}|~y~~|||y{zs|y|}z~}uv~zs|{s~pp}zx~|}{y}|~zz~x|}}w{||u{zw{z{xzyz}|~~x}~xx}|tv{~z{rwy~||z{}ywr|y|n}yywu~{{}}}{y~nswisyz}}{z|xz}}{||{}}}^|wy|}w|y|}z~||~w~y}t|z{~x~v|xy{zyyx}|~|z}}~|tv|xqy{xzq|m{}}{yvtcw}w}s{}|{}x}w|wut~}|x}wh~zz{|}rv{vu~{wq~u~}{}~v|zy~|}~{{}{xpy}pxz{t{y{{~x{yz|{}xqx}z}v{yt{s}~tz|~v~{|~}y|y{{}t{||wy}vy~v|{}}y}x|{zz~wzw{|~y}|x}v|y}uzywy~{mw~|yy~{}~y||}z~y}~{yz}~x~zz|zx~vvt~y|qz~z~yyyxzy}}tyyx~zz|zzr{~z}{{xuoyw|~}zy|}{yy{xy}{y~q}~xx~zvxxrd~xtwzw}y~|yo}}xz~|x}w~~|{~~sy~~~q}{ry~}|u|z~~zz~}~t{zz}w~~upxo{wwj~xv}||tx}w||~|y}zwu||~y~u~{~}{~~{}~w|~x|{}{~}tv}|z{y}vtz|ywuy}w}|z{wv~zu}x~zx{}~}{}y{v|}~~y}stut|~v|{w~~zyw{{||}t|y{~s|{}~w}xv~x}yru~}x~wyz~}zm}w}zy~|wy}}||}z{zz~}~y~~z~z~~~zzx~|yt~{}|w|}z|zx}s~y}u|}yz{o{{r{|}~{~w}yw}{|p|x~~||}xwd~~u}{}ywyy|wsx{x}zxz{xwyz~~tk|}|{wyxwu{~t}}r||zk|u{{~{w|rypt}s~uy|x|~zwtwu|s~y|{wzuv}|}tyw~|ororx}wzy}xyvx}uyzn~~zz~zz}~{}wmx}x~vy~qqr{}o~|y}rzu~vuvzt~}tv~sz~~yt~uuxo~s~znux|x~}~zl~}sxwzxw|t}tx~{qx{~w|{zu}|lwys||qou~|||}n{j|zuy|zqtqzv}{q{u~qxgxuor}|zzw~x~v~jyy~w}~kx{~zy~~}yzk}yxv}~}uw}uzy}wtpv|_}}tyqxzlz{yxr{rxx}s}~z{{}yz|}{}}t|~|t~|xs~~{vzzlt~|}~xvzvl|vuwxy|}z{r~tzy||{{}i~ke{}~zuzuqv{~}{~|z{|yvz{xy~}{|~zpvx|w}zs~|xz}yw|u{zw}{}{vxz|{|z{{u{t{|y}d`x}}~t~}{x}{{t~~}z~zx}z_i|~~|}lxh~~{vq{{zh{yzv|~t}z|~~y~|}uu}~|g~||x}{o{~v}|y~xy{u~y{|~ot|v~||wr|_w{|uz~{~}~|{|}zztt{ulwl}{{}~~zvcqz}zvz~z{}}zxx{z}|{}p{ezx~y|vxz{z|~~w|v{vz|{wty{}{vywt~~|~~|upx}yx}}|q~{|}y{v}w{vz~z}~}jvuz{|xxvw|~~|}|xqzxrtz~}~|{x|{xsy}}}~zzw}uuy{uz}v{{~xx~}z{x~}u{xut~x~~wp{p|f{}yzsw{||q||~z~~~{tw{}x|y~~~xx}tqo{yt}z{}{w{~}tw||y|wzw{~|{ey{{z}}tz{}yzr}u~x{~zwy}z~z{|z{w|}}xvxzzq~~~w}|y~|}z~y~z}|yzwt|}{|~zr{x{{{{i~w}~yz|w{r|z|w|~}w{}zy}}u~zzuzyz~y~{v~w|}~r|yu|{x{|{}w~yvuz{uw~{zx}vw|~w|v{uvy~xy{v{{tw~~t||rv}}zzv}{{zz{|~z}yz|qy}~}}|w}y~m|{s}xvwmj}|}}{opq{y}yt|l||ylt~{~p{|{zoz{tx|zy}ur|y|w}~zv~xt~z|n}vk|~txvz||}v|}|uvzmzz|v}yp~~~~qr{s}||}psx}z{{|}q|}|t|}|~{p~oz}zzx}~~|~~tpz|xuy|xx~}}v|}vzqsws~~{q{{zv~wrx}xy{h|w{u~y|{{zyzjw{~fpx|w|zw|{evpoy|}}k}u|kf}|x}x}x}||x}}z~u|y}}x{|v{y{{k}r}}|zg|x}{yy|~~tykw~|~~yzyr||ox{z}m{p}|w}dwz~|||tu|~zwttvyt~~{~|yvzzly}|xxy{~p{~z}zw|ys||x||z~~x}}~h~y{xy|zq~z~||{v|t{s|~}~h~xz}~|yy}xty{~~vtz}}}|tw|}}w}x{v|q{{}v~|zy~z{}}xu~|{pyyx|}r}z}t{{{zz{z||u~~t~v|pz}}{}wz}~~wxb{|}}|~y|yx~~y{{yv~yz|{z|}yq~}|z{}x~yw~z}~{z~zw}{w}{~~~{}}|w~zo{x|{z|{}}r{w{wyzz~|xy~~z|}|~~~{}{y||v|~d{{~yq}z}{~}z~v|{{~~q|{}w{~{u}~w{x||x|ot|z}pvwzx|zv|{t~}|{}y}txxo~|w~l{|~zp{~z}zw|c}y|x~vx{|xz|yvy{z|xwt{|xwt}~vx{~{y|xn|z~}~|}}z}|z~yyx{o~w}~ku~k~|z~x~~y|~y~{|~{zx}{yz{}yz{r|x{|{v{r}y{|{yzxww{u}y|}z{yw}|}{{~|{vn~|{svzz}zw{|r}|x|zxy{xyt|wyy|{yzvyzvy{||wyzz~{vzz|~v|{g}}pz|t|~zr~x|x~~xnprzzww}}{u|~w~zy~|v{|suv{}v}xxzyr|xzz||x~x~}u}svz{zz~}}{t~{~}{x~~|xv|ntxp}{pyvywu}y{~zwu{|||w~q{}cykzq|yv}u~}{x~zy|~q|{}~{wzu{~uv~y~{}wmxw{}}y}|uvumz|z|{z{{{w{r}{~xzq{|wy~{w}wt|~u}~zz|u}||z|z|}{|z~}z}n{wz}yw|}~zv{~|}|~}xx{yzz}~wxr~{y{{|}w|x}{qy{}zymy~{sytx{{u~uz~{z}v}{u{r{~{z|{}|}x{~}zyz}~~u}zwwr}}t~|zpl|wu{}rz}{t~|z~vx~y|}}||o}|}w|uy{x|x}zz~|x~zyy||~|||y|{{}}w{ywl|y{{~y{|vv{zo~w}~~d~zv{}{{t~zyt{|}~|v~}}xyp|rv~|z~zy~t}}yy}{yuzyyqu~w}x}|{{m~|}z{uy}~wu~ww{||x~xw{yu}pw{}{}wy|ow||uw~q~{vz|}y{|x~hv}lv}}y|~ou|vw{{|z{{|}}xz}yzgzyvyg{}ywzt|z|yw}~~}|{~}xxdv|~{|zw|{~{||yvtyz}{|s}~~~y~wzv|t}yr{}~t}xz}~u~}uo{}~{z}|~}qkz|{w|{}~x|}~z|~s}}u|z}z}wzwz|v}~~~}}z{y}y|yxv|{}|xyt{|}|}q}~x|}s}v|yzv~{}|vlz{{zy|}z~}~}zy~z~}x}{|~~}uz~vzxyoz}y{|}x|~~|{{{w{~|ly~|z~}v~||}u}{|zy|wxuxz~vq}~}}v}|{|z|yr~q|~}|xz~}vzt}|p|x~v|~zyz~|{{{{t~n}v~|{}|w{}|ulo|xn{z|nvyzw{~xxwt|}|}}xvzrxsy}zz{xuzyxz|{woyt}}~|qqz{|y{xy}~{z}~}ovuz}t}w~|}{y~z|z}{}px~w{|y~o|~}w~}z{z}wv{||}mw{}zy~wvu~z}}y{~pyy}w~}{|{}~|yoys|ov|p~z{}x}vw~~yv||rvz}|txysu|tzyzzy}~t~}|xk}|~z~wrw|z~oz~}{xv|{z}{||s{|}~r~~{|y|}|uyey}}s{s}yz|s}zvx}vt|z}q{{ws~x||zq{s~{z~}z{x}wzyzl{j}}wzz{~}zr~xvq{~|{y~}v|w}}}{}}{~}|z{wy~y{}p~}|{{}twx}{xqyy~|}}|zsz~~}y{}tzywz~pr~{y~}v~~{|r{{zt}|||yz|}|~y|}~u|syy|xrz}|{zz{x||z}yu}~}{yv{zx|{~|{~u~y}}wo~|{zv|{yvx}v}yz~u{xz{|}}}~{||~v~r~y{w{}y}lz~s|~{z|{y}ywyyv~|x{z{{|pz~{}}y{v~}||~zw|yz{y|yv|}|txwywtz}{wywwyz}v||x{u~yw}~o|t}{~xz{vswwx~{{}{}zy~|~sv~y{||z|o}zz~z{~v{}|~|x~{wxx~}vyw~|txz~v||yxt{|xxy]xvw{z~~u|~{uyv|~y{~qyx|~x|u||{t~}|zz}}|w}z~yw|z{}~y}|{|yz|z|||}}}}yxu}wy|~}|y~~}{~zt~sy{n|{z{z|{|}|yx~wzs}~|}}}t|yw{u||~|}{}||x|u{y|~{zwz{~{zyy}xyx{sv~z{~zx}zw~~}z{zv{~z{}{|}~~|}}}yxwt~xz~}|}z{{sz{w|}}}~}|}z}qzwvx}z~x~}~}}{}||y}xz{yxz}||y||yw}zw~}z|q~z|}t~}~~{{{y}{~}{~x|yxy|x~}}~zxuzqzx|}x|y}yxz|}}|xytyy}~vxyt{yw{|zz{wywwyyz}|~|z|}}}ryx~yvyx}yx{vwyvz}v~z{zxz~{x}{|~z{}|zzyt|}{x~lz}}v}~o{~x}z{z}zxyx}{t|ty{y~{~yz}w{{x}~yy{y}z||y}v|~|r~|||~h|}uz{v}|{}v{yxy}u|~|}z~zyyyx||{zx|}}v}|z|}}yx{{{zuy~}|v}ty}y|~z||}~{x}|{}~t~yz}wzy{}}|wxzz|}~wx~}||{s||w}~w{|uy{xy}z|to|}}}|}y~y}y~yw{zy~{{~x|}~t~~}x~s{}}v|}{z}w{y|}|{}{{{~|}~}|{|~qz}}}y}}vs}~{tyy~|z{yvzxutqy||w|z}}x{}qz|{z{~|~|xyzm|r~x~zwzu~vvy{pzs|w|}}}~u~{}|}~}~z|yu{x~z}}ruxxqv{{}~{x{|~{z}{|}{|~t|}{{z}xt}}y}}~}yz}{|xr|{x~z~}xc}urzxxx|s~zw~s`~v{w}}yky~r|ry]~y}yxz}w}islws~~}fj||~kxzvzq~x}~{tq~|wtu{kx|uzt|}~vwxr|v}zu|xij{o}x|xwr~zx|{{~x{[zzyur{{ty{y{}wz||~^|li|v~tw{xy~vWy|umw{ts}}z{}ypy~}n}wp{xlwi~}p~vu~}}vyxx{yyyuw}rq}o{~v~z}tzvvy~w{~s|vj}}yyt{Pvt~{uyvzzzt}{pdj~xzzttur~|iy~~~|}}xrgvse~zvydkcsl|gozs|||}~ws{xz|~l{xzjxxw{y~z{pwu~xz}|so}z|}~|}zyw}|r{}{y|r}wzy}{p~|zz|z{|xq|||x|}l{y|lt~}~{~yz~}tt~|t~vu}}{v|{z{t~~zy{r~w|wo~|y{~xvv|}v||rzz|~~}}w|{|xwsx~y{yz|||ww}tk~{}x~}z~y|~}s}z}}y{~}~x{}{sxvx~}{x~o|v{{s~x|qw{us~xy{}|}{y||{}|~|}|z~{x~}{y~}||wyzlxv{~{||~~|x{{sy}}~}~|uz}|yy}oyvy}xyz{w}}~t|y{|~z{u|zqqx{yz|y|{|~~}vv}w~wwp|r|xzy{~|{z|yy~|w{zwr~~wr|~zx}||}}|}|wk{z}w}z{{pyz}|}t{twy~p~}xr{||~y}~jwq{}t{to{w}~xn|vtz|x|}~{s~{|y|{{vt~t{zx{psnk{y{zww~}x|}}~xx}yw}yz{|vw|{yz{u|yu}v|ww||{u{{{zzw|zzzwxvz}z}|y}{|~xs~y~ymvirww|z{w}d|r{|zz~}}q}x|x~}{~{uvt}~{us{z|z{~wzq}y{zh~{zs}y|t{x{yt{~xtqw{b}_t}wrz|r|}wy|}~~{zz~{u|z{zszy~~vz~~~{v}}}i}{z|y{ex|zyz|u~~|z{}p~zv|wtvo{~u{ux~}~~|}|}~|z{}yqts{|~{|cypx~wxmx||}|zz}zqvyx||{yyvy||zz~{s|x|ygs{}}uyx|xz}|{z~~~vv{|zz{ypu~{{{|y}xsx||{{zz|y~~y~z}z|}~~|~zu|}ytx~wz}u{z}wz}u~zu}~wy~~|yww{||ztx}~wxzzz|}tw|{x{pwqwzyzv~}~}|r}}{}x}~{xz~yy}v|~|~xy{wv|~y}}}}x}{}t~zw}{|ytz|}{{t|qj|zwzs~{z~|z~~{y{}{|{p}{}y~wz{~|s|x}}|z~tuvz}xw}}v|ytyvtx}~~{vzv~|x|x}x{|}z}~~u{}pzz~sy{zy~s|r}{y~nz{z{}zwq{w|}~xy~}z~yxt|zw|yxxz}}w|}~{~yx~}{z~x}z{yz{}~||w~yxzzz}xxy|~zrzlvozw~vzu}{r{zyxz|}tz|{zzx|zzy|~}}vzpyw}{yw{~|{~y{{zrzv{z|~w}vu~{zqp|z||}}~}v}{{}zvz}{v{xs~|}v||xzw}~~wvx~||~|v}|~{vrzz}zyx~wqw~z|w{wz~~y}|z{vx}xw{|z{~x}{l|w}{~~|~~x|yzx}{r{zy|}|zs|vzwy|z~zzztyw{}||x}y{|~vz|yxzvzw{|~w{||z~{xx~x}x}~xyzvy~{{~||~x}~~|}{~{x}x}|wy{}z{q~xz||}s~{z~|yz|~y{z}w|s|xq{~uxz}vzqvt}vyvz|z|~z|||w}z~|{}q|yzyvgpo~|z{}xpwso}tm}qzxt{xy{{}~~zr~uut{~{~xo~z|z~py}ysww~r}}wz|}}u}}z~krwz}wyz}|{}utx~rz}{rs|x~y~qn|p}}xzexw{{{x{zzl}yy|~wuz~x|}wrh}zw~|{}|izx}~~z~z{zzy{}y}{rl{~}uv|||v~v|}yz|x{|xvv|zr}|q|x{z}yzw{y{{z}~p{w||{~zyzx|{zxum~|wqw~z}{|~|y~ywxy{~v{uk||t||}}n|yr{~zqo{}z}z}}y~s}||wsxvtol{}}{{t|rl}x{|w|x|z{wxuzszxwzz{uz~|{}||{{ywo}|y~~yz}~~wzyvx}~}}v{zvz{}zyx~v|yrtx{zs}}uu|z|}}{{z}wz}~|{v|xt}|}v{{z{|vt{{|vy}s~|y~|}z~y~~y}|z{zxz}ymy~x~luz~~{|}xzz~}uzsx}y}t}|~}~}|}y{|y{w|~{||~q|}~t|~~|~}{}|z}{q}~yzx}~x~tyw{}y{vt}}|{{~}}y{swzuw}|~wz|x|~~y{rz~u|zxpu{}ypst}z{|{xwy}||}xvh}vym{|v|{t~{}|zysz~wz~|}}zq~}y{}y|~}ks{\t}r{{v{}z|{ruz}|w}sw}~u~u~q{||zzyz{vzvzsrz~~{~nwzwzzx{yv|uwt~{|pyzux~|{vvzy}s|{y}zz}~y{yw}jwovzqv|}zt~}~|sv{s{~w|y}zuz{z~|x~{{yv{z{~}v~~}|wtu~~z~}}tzq}v{}}yr|}}~}{sl{{}}}qy}}}}}}{x~y{~jv|vu}{x{sy|z~|{vzxxx}|x}~zy{~zy|}}}|{}~x|v|||w~s}~u{{yz~|~|~g|||gx}}}||u{yjvur|xy}l|}o~n}}}z~z|r~~|u~y|{uuuxyzw~{~|}ztv{av~|}|ys}z|||~|}y}}xy{{y~}vl~{c||}}xu{r{~w{{zw{z}yuxsszuvusx}|{wx~yz~|~vwzqtxztw~yu|v|}}xxzyz|~~zzw}nu}w}z|}|zX}uxt{~x||u}pyx{{uw}~~|t~vuzzxy~s{yzyv~}ys{~~}ysz|sz{wz|}|z|~}u}{zztpw{ruu|s}w}|oy}{~w{|wx~{~hy|v|z}}|}|{yy}f~u~~zvz{||t~y{zvy|~qzu}zsvi|}yx{~yy|{{||t|wxzx{usyzuu~|v|~vu{qv{|wxzy{zy{}t{r~}xu}qrvyzxyu|zz~}{uwvk}~z~~}u{}z{{|e|v{uzywuw~w{|{|~pw|{}~{~|}x~x}~|}sy{zv|{yi}wz|o|ny}y}|v}t~{zw{z}xz{~zvmzz||}||}yxeovxp{u{zyv{tpzu|u|~r{|~~{|y|ox|{syz|zzv||zyk|zt}ytyw{y}{|vvz|x{{~~x{{yy}{x|~}y~z||{{v{yu{lu~}}~{}}~iw{p}x~y}~x|{}ezy}{zzzzxw{~|{|}~|zsw~}~~}yw~~~||{~~{v}{z{~~~w}}x|u|uy|y~x~~|{|{w||||w|}}|}|{yyz}{}|zxuz~}|~|}u~~zz}qv~p|y}}{~{~~||}~z~o|y|v|quqy~t{}{vuz|yzw}}|{z||{{~zt|ys~wwx{~z{w|b{{}|~|v~w|z~|v|qy}~~}x}zpzt}{|}||}~~~v||{~u|yv|z~~~sy{x{v~|}|}}u{~xwxz}v{~|z{}{|x~u|t}zy|t}}zzr|s}}w{}zxg~v~}|{y~{||{{yxwwt}}z|{~~lxt~xo}~|y|~|}|}x{vxzv}{{y~{z|}}xqw|yz}}uyvt{lvx{l}~}}}xz~{w|zyy}~wzxxnw{z|{otw~||y{q|{}tly{t~||}|}t|{}~~~uw~v}z{s|}ux{x}|~y}}}}}|}{{xtswxz||xy~y{}ywv|{uyp}~y|x~v~}}~w{}yy~tzxv~{{z{xv||~vzyz}}}~s~{s~~z}y|~wxv}y{vy~~y~u{}{}|}{|st~~~}nzzwl}~}q}|~uv{}{}~yo~|t|tyx{zy{}vu|z{{{{x}w{ovx}v}xs{qx||{|~{{u|~t~{|y~}{z~x|}~zy}{v~|yz{x~|w|w}{|z||}}yxyw~{y~|~||}vz{~z{w}{py}~l{~}}}xxx~|x||{z{y~}zpy{{xs|w~||yw|~}x~}|v|{yvxzyw~||{{}w~tyiu|{|~~s}wyy|ywy{{}z}|y|{y}~|~w}{}~xx|}z|x~uw{~|}{|~zy{{z{~}syt{~|~{}}w{{{|~t{}|yvy~}{~wzt{s{|y}|||z}v{~yy~uxsyx|y|{wx|}|u}|ryx}~}}u~~z}pq{w|{z|{z{|}~y}~z|yu|x~{~|}{}}p}}zz~vzys{s|{v{{x{{{sxu{{s~}|}r~y}wyu}|{q{uywy|x{yy{yxw{~py{||}{}}x|}t~{y|{{|vzw|}yyy|x{up~v~}zxu||z~}|~|z{zyu}~{yw}|xz||~{x{}t{xs{}yrxzx~wq|z|||{}}xs{{ysvxzv{v~pv{}{~z{|~v{wy~v~{zx~}v{~~x~|uvxw}tz|{v}wotz{z|tv{|o}u{}y|y~~yx|{xy}wz|zu{tv|x|z}{vz~{z{}zxs~wyyq|zv~wvwz}nxz~xu~~||{z{u|x~|{y~s}~~wr{~z~}u}wzwvt}}w~}|x{z|tx}y|u|s~zy}z}|uryv~}{}~|~y}y{uswyzz}zy}t}~yuv{y||vzzzv~{}~wxz{tuq}v}w||{x~|w{ux}{z{~yz|suwypu}w}w}wow~z~z~}{}~xxu}hy}}yzzwsw~zwx}zyz}y|{}zx|xy|qyzyz}wy{sx~||~y~y{zz~s{z~x}}}w|}zy{xy~{}z~{wzs}n|yqs{{}zr{sqxy{vx{{my|}{{|}}yko}z}wyzuqx|z~~y|xu{}|{{x|pqwpyz|{wd|x|t~|{_{yysosrhzu}xt}q||~{zzx~vyxtn}z~wm}|V}{}qy|x{|{{|y~}ywvv{{p|~}|}~{}v}zz~|~|{{zi}v}~xvu}yw{y|yvzozz}zn}|y~{u{uuzy~xyyo~u~z~zssy}yvu|x~{}t}z~~w{{{x{y}x|y|}~{~x}vz}|fy|sx}tp~}~}}zfxzt}uyzwuw~ws~zuv~v}{}~zy~||z|~u|{oxztu|~yrz{yu|~}z|}{|~w|yzyztr{|yqz~}yzs~~}x~x~zo{yzt}}uypxm{zwy{yx|l{|x~{t~}{zyvzy}x}w{w{}z|}wv|}zv}}yv~q~vu}z{wqx|wzy}rq~|zswl|||z{uv~}~}{w{|wxxu~||xzz{z{y~{w~||}n|vu||{|}|~}y{v{}s}vuv}v|rwy|{~|~{z~xt|~|{}|xy~|x}{}sy}}sy|z{xyz|}htwiwu~|{}s|t~{~{uz{uywvzzvz}xuy}x~{{yy}~{|}w}z~y{zz~}z{zzxu|q|uv}u}x{yxuyvs|{zs|||}|s{twvsyyzuw{~{~zyssuytxxtt`w|||{szwx}{|x|rwu{~xu|}{v}z~vryszx{}{{~||u{x~{}}{x|}~zrwyt{zwtwx~{wu}~~wxw}uquw~y~zw~w|v|sv{}{{z|}fxvy|y{x}wxv}}z|{w~syyz{rq}vv{u~y~lyhyz{|zxn{wxrqot}~v~{|{q}{vz}~mtr}~~{nz{{u~yrru||~|zn{zz|{{vztq~}}}rz{{vg~~xzv{yypu{~{}zw{y}{~wsz{ulzs~wxx{|{{u~{{|xw}}v|myzx}~|~|wv}|ozx~|}po}~~vvx~yqv{yy}|~|{w~vx~zs|zy~yx{qyz~|zyw}r}~}|w|s~z~ytz|{q{{~}~{|xs{xz{e|w{|}}}u}j{xs~{~{z{rzz|ut}{{{x{}v{}yys~~|x{z~{}~w{}|}~u{~{yx~z{{|~|ztwy}|{|zq{}wz{|utzy~~~~tx{|y}~x{xw~x}xz{k~|zz{yzv~~d|{{~}y|{x~}zzuy~{z~{z}yxxzyzz~~~|ow}{~~v~y}s{w{}~~ty{qzx||yxz}q{ys}wz|}|yz|~wwzx{~z}x~yy~y{zyy~}s}x}}~zutxl{wxz{tz{}~w{}|t}}r}}v}u~wt~uu}{yzx|}z}{zxzyxzo|z~~|wyzx{z}z~|x}}}|v{ew~}|y{~||x~w~~{}}}{vr{zy{}}~yv~{u|v|{{ypzyz}kvu}t{{|x}q~}pyyz~~}}}~|tyuwzz~zy{ry|}|y}}x\}|{{}}}z}z~{rwzw}|~z~|t|w}||~z}{rv}y}~|{lzx~|vv~z||}p~|kw{|~xt|y{m~{|x~{|x~}wyu}x{{|~|v}~{zuq||tx}x{rz~y{{}|{nz{zx}|~xk{|xz~~n|z{tpy{wxyrx~~|vz|yy|xw~yz~|}zt{|~yp{z{wyzwpx{}zz}zz~{}wzvuu}y|xsy~xv|}}z|{~z|}t|~}{x|z{|{zu}z~}}y{z~qtw~{~twyz|t}{{{{}}~vuxuqzsyrvhzx}z|{ux|y~{~||{y{~t|z{|~|||z|}z~|wx~~~z{~|s|t~~l~}|uz|r}}wu}~}~w}z}{x~}y~|ywywy}}zy{u{}u{|y|~oz}{xu}wx}~y}vxw|}}sy~x}q|r}z{uw{xuz{|ryvz{{{ql~|v{|}{}|tt{fl|xz~w~{}}}|y{}k|}vxk{{x{|}~vzwx~~x}|w{x{xvw}z~|zw~~zd{{~y|uz|y~}}ty{mzxrm~~|}zt~|x~{vvz|}xznw~~||x`ux{yx~}zxy}~z~~y|~tynwxyvtw{{txs~|wxu}|vvv{yp~z~{u||s|{z{{v~{x}}o{v|{{w{{x{||{y|w{~}tz|}~}~}vwsw}yrz|{z~y}rzy}rvz|~rwtxw|y~|z{t{|}zy}}{zvz|zw|z}}zz}~{~|y|}v~xv|~{~||r~xz~~|pt{xm~{~{{p}{{}}}s}{smx|}u{~zzt~{}~}|x|ztz|z|~|t}v}}v|xy{}r}}~u~]y}yuv{{xx||}|kxzw||}w}|yz}x|~y|x{~v|r~}wmz}zz}zy~y{hkg~xtxuwv{y}uz}z~xw{tsx|v||~yx|ywx|zyz~}z}zxutx|~~y{w~uu{|y}wv~yvzv~p}~|x~vx~ky~~z}~vll}|wz}w~}}ur|{|tztl~~zw|~tt{wvx|{ux{~w}vzy|z{}xy{{~zx{zz{wyyn{{~ywo|zwzw|vwv|~||wx^{z{sx}}{{y~{||u}z}{~{{yr{~zw}~{y|~zuxvwu{v{ly|yww}t~wyw}sy}x{~|x{{svwxm|{|z{{tt|xzvyxo{r~kl|{fyz~|{z|w}s{yu|}{y~x}w{{~{z}zc~{v|zi{u}r{|~kzv|~rqyyx~qzxz}~uvvy|yzIzwxzxy|y|x~uu~x{njv||{{qz{Z|~xw{~~xt}o}~z}v~~{||~~}}~|u|{{}~f}~|}{~}~quu|~xv|~ozzx}~y}{{u}}~z|}|yyy{~}|y|z{sxxn|z|~~y~~xs}}{z|~w~|}ryt}t|y|{v~{x{{{z~y~yx{zwt~t}|zwyy|tt|}ty~xxwy}t|w}}~}t||xz{{|||}}}w||ywv~z|{|z}{~{~~w{}|yyxwz~}wzzzuz}r}{yw|~y{z}zxt}t~}rx||y|}xz{~{|yzw}y{z}||~yuzyxyy~y}zy{z}y|r~|{yyyzz~~tz~z{{|}{}~~sl|~~|yz}zx~p~xp}s}x|z}~ox~|{y{zzsvtxq~yy|t~uuyty{v}~{x}yzzsyz}tx|{|z|u}~wx}{xt{}}y}qv{zz|}w~y{~vv{u{|~s}ook}y~v}~|x{}yxnwv}~uz{||~y~t~r~~{|w~w{~}y~ypy{z~}wv{~}s~o}}zw|xu}wx|wz{vwz}|yx~~}{|}xy~}u}~{}{{wu~~zzzz|xrx~~}yu||{wx}x|~z~yx}y}{|}|y~~|zw{~}y~v}|z}|{q~sz{u~~~|y|~yr||{{{z~}{z|ow~ys{t}}|~{z{~|~~|z{vy~yw{w}ry{q|~}~v~lxwzs{|}~~}{{~z~~~|xy{}ut|{~}~y|~~{~~}~zx|ys|}}yzux|x|{rzz~}||y|}|}~|v}s||w|}{z{}~}z|||x}{z~}}y}{uyxx}{~x}zzy|y|v|}}||xyup|xm||z~xxt|q|{z|zx{~z}}}{u|~y|~zxz{}}||yz{}}}}{yxox~~~|zx~w~}|~w{w}zx~}w}~}}u}}xyyw~w{}yzy|uwx~z}{u|ysr~~z~~z}y}|~z}~zt{x~~s}z~||~{~wz{z~v{}{n}y~z}|~}~ywwyywwxq{y}{wxy}~xwzz{~z||{{z|}~u}yu~|{ys}~}yq}vtz{w{w{v||}|{{s}}~~|}|y||~|{|}ysv}}u||z{|u{{{}z~wsyx~~|zx}{{w|u{}~~utxw{yswxsuswvzx{}z{zuy}z~yz~|}w~wv~~w|o~xzw}u|}zyw|wtvywo}{vu{z}}{w~{wvvz}z~n}wtu|w|~tpy|x{y|}l{~}{{~|}ww{v{{|{{y~w|}z{|w{}z~|}z~}|}yx{}pu{{|~jwn||t~zx~z}t{zkvu{|w~wzyy|usxzt|~u|znpzyz|yz}x|{{yv}xw{rvw}~r}y~bt{}s{~z|~||{}yz|~|zy{{{pu}zujvy|}|uk}}|x}q}ryyxz~t~x~u}yy}|~yyywz~}{}~lx}xzww{|~~~{~~|uuusg~jw|}vx{{}{z{}}|yy~|xx~w}zt|up~t||z}}ozyvwyv~xzx{kpo|u~|~~rw|~s~}xwz}}||vtv}{xuy}y~y}||~{~x|xtypw~|ox{||||{xvlz}wyktxp}r}}t}y|{}~{ws}w}z~{wu~~s||}{l||}}yrzxx}~|~pk{|~xp{v|zz~yzvu|||{yvu}|xx{s~~{{~~{}}tpwt}zy|}w{|z~x~}z{{z{|{t~u~{}uowt|x{}wzn~v~~zwz}~{z{|~wzz}y{{}xyrz~k~|}~|~t||~y}~{}vy}z{n~~x~v{}|~m}vz}{}|~s~}}z|zz}|}{tr{ty}~u~{~z|{zzyy}~wp~yp}uv{zx~su{zu{zol~z}s|u{~|w~rz~}}zq~{{y{m{u~zxyv~|~v}nsbx}yx}~{~u|zw}~xx~w}{z{s{}~z{z~y~|}|u}z~}{~x{m{z|~{}~~}|z~}tm~}t{wn~}z~}{zxprztxq~ryyuU{w||wxzy{ypx{x|{{||{|sz||y{ytyxz|z}u|~z{y{sx}p}~yx|z{q{v|v{z{|w}|uxwz|~xo|wxxxyj}zy}}}}o}wx|{~znq{}}{y~w|ux~{m~sz~x~~u|qv|~z|ztty{|~~yv~w||~y|uqu~z|ryqg|zo~w{{x}tpu{|p}~x|x~~j}w|~x}wyxzLz~yyyux~wx~{~|~v{ps}|{w}k~z{{|vxtqy|z~xz~{~}|n}}xw{|m~~yo}|~|tr~{xz~y|y~yo~|}z}zw}vy~z|{~{z~ywuzwxyyxy|tu{~{y{x~~{|}zy~{mfyy}x{ry}|xy}}oy{xu~}~rttvw{zvn||z~}}~}zww~}x~}|qt}|yqywv{}y{}x{vuvwxyw|ku}vwy}{zuq}ozouxx}|}}|}o{{{~wz{i|{tr|pv}}v~q~~y~x{zxw{zsxxwzxkxo}}uzzv}suwypu}y||l}|s~zx{}}tw}x~~{y{}}{tvzq~u{yq{}_wy}}|wxwru~ty|~z}l}~zv}z}xu|{~s|~||xowx|{}tx{r~||||zz}se}}{~qz~~~rxZ~}u|uz~zw{}|x{zq}ky~uzvttnxoju|{{|w}qu{sxx{uyszxzy}}w{~}{g{y~t~{}|zzzxx}|y}}{~}{v~}~|}u}{yy}{yx}v{{zvz}}{y~{|y|yu~zu~~|{w~~z|uzv}yz|~u{|v~x}~wzu~z~v{{|x{{xsr{{o}wx{{xz||}{~|y{|xw~{}~~~|~sx}|~zxy||ytz|~v||zyz{x{zt}~}~|y~zxz|~|}z{~zzyvz}|xxt|}yu{}vx}wzy|s|~~y}w~vr}}y}u||}}s~|}z~~||x}n{{z|y{|t||zv~tzyz~{z~~{{~|z|~~x|}~v~w{}z|~{|z{zzz}z|{}x}x}|}|~r{v}}|z||z{w{{yyr|x}ywy}|z|}~~|~{xtzy~z}~z}~|yw}y~}w~}sz{zs}rxrww|{vy}y~~}~mmx|vu|xuzu}}}|vxy|tzx~|v~x}}}zx|vm{h{|~yy~~~|y|z}x~wo|vr}yyz~~r|u|yy}v}x~qrz~{ynw~{}|zzhZ|r~zt|x~{|v{|~~u}vzz|nq~{{npxw{y{{~|ny{z}hv{z~xxy}s{|xr{eny}s{qv}v{|{t{vzw|x~}}~yz{xqy}y||{}qzv|pf{{{sv|vs~Vzt{t~|zzx}|~|p{}yt}{qz}tx}w~~}~yx~~}us{{uyv}z~jwy~zy{}zwptytwa{s{oxzo}xzzu}wu}|oyvwh|~}pz{|t|zvp{wz}yx{q|wzw~~x~twx}~|v~yz}|w}y}s|ytxy}w|}|{uz}x|{|}~~zrvx||z}}z~u|z}uz|{p{~{u}w{y~y~zyxx|xy{xw{}q~}o~ot{}~s}|wzyyyu~||~wx{|~{z}z||}y{~xzx}{}x}~{yxo|}y|}}}x|z{|x}~zvy~szw|v~~|~y}~{~{syvuzq|w|xyz|yyxu~~|||x|~}~||~||z~~x|}~~~x{{yy~xwx}||w{~tw}x{|z|y~x}}}yyv~zrx}~qvxv|~u~l{z~q}|~~us}}}{~yv{|~}}y{z|}~y|wz~|}~x~{yz}y}y}}{w{zr|}|vx{|z|}xxt~~x}}y{{m}~x}|x{vru~yz||~t}}{x~}rw~vyy}{}tv~sw~v~~}yu|x|dv}r{}n{v}}}|yx|r}s~ww{~{xp~|}p{{voyu{wy|x{x~~}tw{~|}{||w~{vz|}|}}{uy~v~x|}~z}}sv~{}}v~z}u|}{{g}{}z{{zxtvyz{u|tz|~w}xz{x}w}zzxw}~{{{|r}zyy~~{~vsuz||yv|~|}~yw{vq|~zz~|x{}}{zv~~{{wu{|{s{v}|{wyx|zyu}w{}zvy}vn|{}yt}tw~s}~sx|tww|wuz{xs~s~u|yy}{{|~|~}x{zyys}}{~y{}yuy}~|vxy~qzxzzw~hzx|z~z{t{z{x}xv|ww~}|y~~{zy}p}x{||{~~~x}}~{vz}{xx~y|zy}z|sz}~||xq~~xv|~wxxyr}{}~{w|~{}~t~|tw~{yv|u|}xzzvz}|{~|~hw}u{zsu}z~|}{vzz{~z{~{{z~twx~}t~|wxvTwyz}{}uxSy~x~r{w~}|vx|{~w|}{~}s`yzv}zx|w}~~y}~syz}v|zs|}tx|f}|~}{{|zzwz||pvy{{{w|v{{rouvt~}~zy}nv{|}yq~ww~|lzv}w}{}|~}tx{us{}}{yv|~wlzxg}vyi}~|ywxr}{{|sz~|izx~s~}|wyy|vg{z~u|v}{z{orv~~y{|~u|x}{v{~}{~}~uyvw~|~vz|w{|~~~~x}wu}}y~}zz~~v{||ntt~~v}}|z}|}|x~t~|y{z{y|}}|s}|}x|~v~{~y~{z{~w}f~wy~~w}wl||{}{v}}xz|uww{x}||u}~yw|{{yuv~x}~~}~s}zy|}|{x|y~|zt~~{z{w{wyso~|~z~zvy~}~|w{}t{~}{|~}|||}y~~y}xv|~~}}||z||}qz}}o|~}}vx{wz|}wxx|}x}||vz|}|yywszvzt|{{wyzd~vt~}zxy~wy||~{k~}z{}~}wq{~wzzy}z~zyux~{|}}w~py|{q{|w{{z}}~|{|xvs{~xz|}}~}|}|v||qvo|ut{}y}~~||t{z{y}||~xxu|w|{zsz~{zxp}}}u}{|z|z|}x~}~x~vt~w{|z{x{|{}z||||pxxl|{}~xy{uu|z~zx}{|{x}y~zy{vz{{~}~y|}v||zl}zxv|r|yyuzq}}x|yu~y}~{}}|mpz~yxo{~|}x~{{~~z{}}|x{|{~|yy{x|}~~}~~~w{|}z|z}{x{{|v|xvz}su~z}|}|{~||~|{~}|{zyx}}}||xw~}~|{y||x}{~w{~||x}{z|{|z|pz}w~}}yo{w|z{}{ztv|~~xw|x{||u~y{}}w{uwz~yu{x{}{~}{~|{}~zz|t{}xz|y~|y|{{~~}zqv~z{{{{z~yx|~z|{{||zuz{|}s}}n{z{~}sp{j|}}{}{||~oy~wt}~}m}{}yv|v}zy}|z|{{|yw~z{z{w}uuy|{||yz{~xy{}y~zzw~|||~}vz~}}}zw|{|xz||~yx{}}w~}z|{y|}t|y~{|}~|{}~}{}{~~o~}z~x|{z|}y}||wxw{|~}{t|v~~~|~x~x{{sx|x~|{{u{}{uzs~zyyzw{}~w~{|}{~|{z|wz}yv{~v}~vyw{||~|}|u}~{~z}yv{}w|w{}~{||{~zyoz{zy{w~|yzw{~wz|vz|}}w|u~}~}y~yym{}wx|zyz|wwwwuxy|}{|s|}w{ozwv|wzz{yyx~s{uyx}zqu|~j}y~ztwz}z}t}~wxzy}|{{y}y{~~}{sxt~uv~k~}}wzx|}{~wvty{~wwqtr|zvyzyx||~w~{~uz{~~{z{y}wyy{y||o~|soq~wkmy{{}}z{~mtz|{|z~w|~~zyv|z{~z~z}y}vm}r{z~|{xn{~~y{~o~}}}|}sxw}}x{|uzz~w|{uzyyzx}~v}vj}wyzw{}~x|r}r~z|z{v}y{~|}{zux~n|m{{zy~xv{yp~~s|}~{|~v~{~q}~yz{vsrxxzxzxqjzx~z|vp~zvk}|w|~q~{}}xy|wx~}rvhovz|{w}xn}{tk}|s|vt~}|}}z~y{}y|x|{~zz|wx||~|~y|vyot~}~~yz|}{}{w~{wsxvy|y{}}~t}~|yp{~xz~{|tx}yxz}}~u}~|}tz}}vv~vuz{zx|}xzxz|}}y~~~t{z|z|zz{w|{~~y|}}~|s{v{w}y}ww~xv{r~~}y{|zy|vxz|{zw~~y~y~}}|{~u|zz|~{}}}||zzx}|yzzv~t{|zzxwv{z~||}y~x~~|}y{x{v~zo~~z{{w}m}{s||t|}}}{zysxyzt{~|v}zw}z|~|zw{}z|wvv~}}x{||z}~|}~{y}r~~{xvz}yzy~~{w}}}y~|zy~wz{w{vz{wszwr}oysz~w}x|{z|vz~}zy{u|s~w~y{~{zxy~}x{z~w}{|x}y}y|~{z}}wzy}}{}~w}~{nuyyxx}zxuu}~}|{szvy~~wv~w|{u{~~x|xvxxx~yw{|~xsqz{}|w~~|~yy|zz}z|}x{y}up|oz|{~{z}~~zz~t~}x{xwy~~{{w{uf|}{}z}xzsz{||z}}sw|{s}zy|u{x}~t|{v{vt~|{}}}x~{ypy{t|rwwtz~s~}}z|{x|x|w{ts~~wuqu|kp}u}z~huzzzu~|s|z|r~}uz~}{}xvwq~{|yzw{{|{v}zzy|z}hyq}xx|suyx~{mx{|xz}}xuv}yz|vywxy~xz||}zxy}x{r}rv}|~}{~x}u|ww{}|}|~z~zwzz~|zz}{yx}~w~~{~zs|v~|x~~|~z~}~x~}}zz~wx|{{}vy}~|{{yzy~}zywwwz{}}{}z}v{{}z~}}y}~{x~z}}{y|~x|y{|z|}}z}|{yyy{~}z{~{xzp}t}~zx|}|u}ztxz{~}v{w{oy}}~zws{x~s~xxz|{vq{zz~y||}yw{~}y~w~{v~~}{~x{zz|~{w|{}}zuo|zzyyz~szxv}yy|}~}}z}{{y}xz~~}{~|ww~||z|}{tz|wzzyz~syyv~|zw~ryz|v|u{x{x~|}uv~z{~{|{zxo}||yut{t}x{}{uw{|{|u|y{~}y~~{xy}|v}~yw~y{w|vzu}}xyzx|yq}stwxp}v|wy|{|z|}|w{|tzvyxqz|z|x{{~}xwwxyxz~{}v|~z|x}vsz{~r|{~{t{wvw~z}}x}|}}|z||z{zvxq~{yv}}|zy~}||zqx|}~|}zx~t{}}z}{{|{v~y||v}y|}||tz{~~x}}{v~zu}}}{ywty{~y{}z}q~|vu~zyy{}}}xyw|w{}u~y||{r|}|{xyppy{|z}w~n~|xzzs|}|s}{|t~{yt|np{yx~|y~~qt~|xy||~}zy~|y~u}nz}u~{yw|{myzt~||{zwx~yxwx}|{{zzz|p|z}yyxq|{|x~|zzxw{v}r|{~}zxzs{t{zsv}z}}sy|}~{|y{||t|}~}}yzu{y{xyzz~}}x~pj~zwx|z{w~zwyz{~{|y~wwsy}|~zxz}|~~||w||z}t~|x|~~||~u|uxy|t}y~|u{{}izuw}y~m}uw}{~ys}{~p|zt~x}|xo}}{yvv||x}~|t|vzm~wy{y|~zyu~zy{|xw}||yv}~~}}|~|~}|zuvm~~}zxwx~yv{q{}~wv|tx|uuzuz|y{{~}|~tzx|~{{}z|ywxuysyzv~xw{{x~||}~{{xzw}~u|~||z~zz||~xp}|~xzs|}zyz{|{|z~~|z|}~y|y|{||}m}|~r}~}~x|z}~{}tz~w~wy~{zvs~{s}yx|~~}yz{ys|u~r{ywt}|}|~zus}x{~|{{vxtqxxo~~z|x}|uvy|}u|wqzts|z|}}||}zyy|x~z{{sxn|wy}|w~kvwt}wz{~}z|xqy~z}~z|{|{{zy|}}x~zz}|||zv~zz{y|wwz{}v~{~}{w{z{|zv}y~}op|}}x{|{x|~}yxz~w{w|{~u~x{}y}u}yx|yxszx|uv{|{}zx|zupu}}uyw|{}|x{~{~|q}|wwsz~|j|~}}~u}zxuu}wz}|yz}~{|ux}{}zuqxz{y~|zyzs~zy}z|x}}~}{|y~{y|~v{yz{w~zvy}vy|||||~zqy|r}|zt|tzss~zxx~zqyz~w~u~u~}~{~{~z|}|oxz{~zxzvz|}urz|z}}r}{|z{zzy{}z~~|}~}||xz~{|yt}|w}zq{{{~}~{~}{vzzlyzxv{|}|zuy}|}}~yzz}s|xz{w~z|v~z{}}x}}~yxyzz}x}}}wy}~wc~w{~}xpy||z||~~y~{r~z~ys{u~z|xy{}|tv}}uz~|~zuzy{y}|y}}~|~~|zy{}ww}xxzvyvtz~~{|x{|}|}{l~x}{xz~{~zxw~{}y|twv}|v}~}~yv~}w}vyyyw~}~|}ytwxz{~vz}}|uz~{|x|y}z{}~~pxyvx~{zz~{|x~{{yuu{}}~~~x{{{zvwwzzm~}|zz~|~xssw}~w~z{uu~|~{zw|}y~{~x~y|x|~vy~|}ny|}yyy}x~xx}~zrv|z~}{{{~|}zt|y~}}~}}e{xx~ux}zw|z~y}~~sz||{v{}~zyvlyw}|zx~}~z}}w~}}~{}wy|{w{w}}z~~|{~vw}{|z{o}~}zz~y}qv~y{w|xu||yy{~qy|}~y{ttzn~vu}~q{{zzyuwr~t~~}yy}y}z|u}y~|{}}|zx|}}yz}|z}owvx~v{{~{{}{~}z{z{{v}vy}~v~}{{~v|qu{~u}}ru~y|~v}{yt{x}{v|~|}yx{x{~wsz}vux~{pt}|~{w}~{z~}wx}x|u~rm|}xzvyx{~}wxxxv|x~{}py~rs{xyyo|n}xw~r{xw|zuy{}~}v{{}u~{}|v|zz~|t~|wvu~}}{}{z{|~vz~}y~}z~~{||sz}|zvs~}v|y{{}s~||y~}{u|r{x~z}wztvtw|}}x|{{{yw}}~|}yx{z~~yyus}|}{zx~zz~}{yy|x~}|x}{xzy|j~~{z{}r{}szyx~~z}r{z}|y}zz{~w|{~~{w~}x{~o}}~|r}|z~xyxx~~~y~{{|}z|lz~zzz|z|yk~|}wzz|}kv||~tvnw|}r{{|ryzxx~wux|z~|zy|~w}|}~~v~|{m~{xv}w~u|szn}xy|{t~w~vvzz|~{~pz~ss||~ytv|r{~}zu|r{}}~~z|}wz~u}{z}~|w}s||u}}vx}uz|~z~|x}}{o{~}|yr~w|z~~}vy}{z||}t{wx{y{yxyn|y}n}yw~}{~~w~y||z{~{z~s~}y|}ty|wz{{{{w|yu}|{zw~~z}~|v}}||xpysyz}{y}}s{~|r}y|{u}x}{|~yz{|zuyzr{}vy}~~}{~zr~}~~z{qs|z}~{~}|~w~~zxv}xyx{zu|}~y~|}}zw~yxr}}z~}}}{~}s|{{z~|z|rm~v|y{wy~{~~~{z}x{pz~x|~}zv|||zt{u|{z|}w{tx~x~~wz|w}uwz||{r~x}{zy}}{~ys}ws~}|{{||x}}u|vyw||m|m|{{z{~uy~r~}{yy~xw}{s{|~r{y|qv{xt{}w{w{y|t|{|{}~|yz{}z~}zy}r|u}z}|x||w}zmw}z}uw{{}zlw|{t}|p}w~~wrvxx}xz|~}}uwytu{~{x|{~|y|~t||||~{~txu}xyy~wyv}{z|{~z|y|}~z~zz~z}x|yyx~}w|y}t}wwzy|{v~~}uyz~{sw|t{yy|{}|xxyy|{}y~x{nwt}{}~{|{x}zyt{z}}xq|x|||}tvu|}u}x}vx{x|lz~{}}x|~w}{xz~}xyw|~}}s~wt|{rzxyu}~|xnw}v}~|w}~urx~v~x{wzvv~|z{z}{}}}s|~|zz}q}}}z|~{}x}|}}|}~~t|q~}}wur}xr~~xy}~w|wx|um{x|~x}wwv{}|v{z|qw}{}|{~yuvxz}~zxz~~uz|}{}~||zo~h~zs~w|}|t{z~zr|z~}x{|~y~Sxy~{|zmy|zsq{}usw|u|vyy}}}r{xow|z}{|}tw}z}vx{uzv~{xvyxzus}yy}~|}}yxy||~~y}w}~zuuvtyz}vl|zvw~zxpzs~|~}vm{{}{}tmy~y{vy{|yx{r|w|w~zz{vywxlxz~}tw}h~wizzos}}syv~}n|>v}wzxy|m|~z|yv^uz}r~yy|y|vp|y{w{}|x}~zz|w{ttx~||uyt|}{{y}}~kx~uzxzvz}v{}}tv}{u}}w|wv}{m{sm|}~}|tx~}q|tx~}x}zxz}xty{uvzr{7v}{||y~}x{}zvwx{}|xz|~{p|{y{x~~zw~{y||{x{{}|{{~}|~~{x{}|}}|wyz~~~x|~{kxw}|~|}|{y|{z||{~utz~x{u|xx||}}|v}{zz}{yz{}ru{y{~~~}}y}y{yxt}~~||}|}{{q{x|~~~|||q~w~|ww}z~|zuu}{~|oxxxzyxty|v}ry|v~wv{|}zt}}y|y{|}~x~~ux{|}x}}{zv}syx~y~z|~z{{y{~wu~w|{yxv}x}{zt~{}z}||}y|{{~yn}sr~}ysz|z|u}w~{vz|{zw{{}y~z{|{|z||{z~t{{~}x~}}~x}}{r}zx~x{y~x~~u}yv{y{~yt}v~w|y{}~}nwuy|xp{wv|y{x{yy~|{ueko~t}yt~{t}|sszy|{z}{xxsx~}wt|}mw}zf~q~}ykkyw||}szx{{x}{vz}|{t|uwwwzv{{krzuw~{wswyvxws{m~]rzqw{q}j{|{vxzx~g}v~vnz]n}}vmupzvzy~rs{|s{pzxvoypip}y~{p{zgr{}}y}q~rvtq||w|~{||smysus{w}t~x{xvlzuw~x{~|yz}t~zv}|x{ryty~~ztu~{zru||z}}y~\nxyzy{zuy}}xyw{y|yzz}sch{}h{az|swuyYn~}z{u~wutth}y|x}||_|w|xeuy\wuwwv{u~y|sGxry|n|}x{{p}~wKx~~wzubz|pu{|}|y}zwz{~z{x}}zw{z{}|{~y|v|zz}zz|xz{t|~~~|~~zz~y}|t|||y}}zzos|}s|~{uz~~~}x}~~{y{||zzt}|}zv{yu|||{}||~y{{zw~}~}~}}z{}{||}~x~y~{xx~||{~|{|||}{}|}|{|{zxzy|}}}s~|{}}|zz|wz|~~}w}~z{{{z}{|~z~v|~~||}w~~}|{{xwywvtyy||~||x~|{{y|{|w{z{|zz||xx|~~|v|y~~~z~||xz|z~y}x{}{ywyz}{|qzw{}z}{o{{}u}w~|}~|x~}|}s{{y|~|||v|}{|zzx}v{zw~rw~~{}v~|{}z|{wzw{u{xx}xv}t}vx{~}}}yx}{yys~y}y{}uxxy}|zuyr}r~}w{|t~{}wz~u|z~z|{{}~}~}x|zxsr{{zy}|||{xz~y}y}~}wz{|q{{y|}~~|{y||~tz~yz{}y}|v|n{zy~y~~~}~|x|}z|vu~x{|}tyx}{}~{y{z}x||zz}z{~~{xzs{y|{u{|t}{{wyu}x|yz~}~|}|{ww|}u|y}}|vzt}||}~~~|~{z{uq}w~{}~~}z~x~zx{u~z{yz}||}}|~}zx~~x{~~~~txzy{{~|z|{zz|~yx|z}|}wzw{||u{uz|~}uyx}wz|{tz|z}~w}}|u~}x|~}|{t{~||{z|}~u{zz}x~||}y~yv}zupu~f~~v}rw}yy|}yt|y{~zzwr|u}y}v{~|x~w~|~zsyq~|v~x|}|}}x|}~|xx{s}z{y}v|s~ov~||yw|~{|}}t{n{||y{sz|}}zut}q{|}z}qvxu|~s}p||zy}w|z~}zy~o}z|}~y{|x~{{y}u~}yl|~|}~x{z|xy|}owt{x|vw|~zp{~x}{u}{{|~~||x}~u|~{yxw{tvsyyt|{{z}y~{|}z|~ywyw{z~z||wsuxz~p|y{~~}~k}|x|vz|v{zz|vt{z}x~zu}y|wzz~~yz{xyyxglyu|~}ws}{}}|~}m|}}{z{rx{{zvz}~r|z|xwyu~wytz}}{~~}w~}}v~z|wy~}v{q}{|z{~{~xz|~y}||||~|~}z~}}rz{|~~w}{y|sy|r|}z~sz}}q|z{wrzx|z~vy{}v||}~~}{}z{y~z{|~~t}}}|{yx}}qws}}zz~}w~z|~yz}{rx{z{}}s~rz}q}y}|u{{{~~|{ypyw}|z}x|}}}z}z}s{{ty}|{||}}w||}|~vu|z|~{wzwm}{|ux}y||t~xyv~}w}y~~xz~{}{~}}}zyy~{{u{vv{~{}}{}z{~|vx{l}w~t~}}wzzv|t|z}{zy}w~|x}x}}yz~~yz{vv}quv|~z~}s{zzt{{v}zy|y}yv|zz~z~v~tzv~xz|~y}s~~sksz{uz|zz~w}z|~~{wu}~vyoy}||y~tyts}sy|{zwuz|y}zz}}~ny||~yz{}~{vy}vw{|yyz}z~|y{v{|~y~ypyvxy}{x{~uw{|x|}|~|v{|}my|~z{s}|yzw~|~}}||~zt~||y|}s{{~{~yxo~~}yz~x||v}{ztxz}~|z~{|}z{q||z}}}}x{}~}}urw|z~zvyp|vy}wy}zxy~m}|~z}{~{wvx}~}|q~}}~{{v}ruhz}~{}z{{w~oz}u|u|~zvy~q|v{y~mk{{|}zx}~~v}y{tuyzz}x}{}|y}{{|}vuw{|wyw~w~x}~|yp}~y{|o|~tz~}ypy{}}{w~x|{zy{sx}~x~}}{{~||ykyx{}wz}zw~||zw{w|pt|u}t{pxv~p~}}zwryp|y~|xuwx{|u{{}yx~||w{~vz{|yyzgxu}u~{~~{xx}yuztzx|x~urv|m|{y|tx}x||z~{u{vww{}~tuzy~uut~uyyrzz~z~|oq~wg~{wz|~x~~~}v~xw{{yz~uj|x~wy|t|~}}{u}~x}yv}{}uy{uv|ys}ev~}||zwwz~|q~~~uxz|uy}}~~~r{~|o}pny|tx|u|~|x}}|l|xzl|{x|xw}uy~}~{zwzk~q~u|svxm~~}s}wt|}|zh|~zz~tyv|y{~xy~z|z~{w{~{|~s{|}|v{~{x|~z~|u~x|w}}{}yys~{~{w}x~zt|uv|}~|vzyvzyy|x~}xw||{|~r}zy}}w{yzztz|z}}xz{~}}q}|~}|{v}r{{z}}}y~~|x}y{y}~yy}}~{y~{}~z{z~~}yw||y~{}zyny~w|}xww|v~}}|}z~{|}{}yw}yq{w~xzy{~zy|uzv}|}|yvu{z}}~|~w|u~{{vy|t||{{~}y{}ww|uy~}z{y|{~}z~{z|t}~yty~}~xz|~www~ux||{~u{|}w|{|xwzzpxzx~}~}||{y{{{}{w|t|||}zy~~y|wy~v{~~{z|zw}~x}}|{z~~{~zk{wu|~u~y~{}xw}o|~{wr}yptx~z~~~}{xu|~~|x{zy{q}x~{xx}|x}yz}}~sz|}p|}y~x}~zu|t~{~w|z}~y{w|y|zwz||u{yut{w}yy~w{~|twzot|}}uzwz|y}yx}|}r~}{zy|zvwz~~|~~x}}|l~v{~~~t}|x|v}zwuyyzuxv{d|}y~yy~~~}y{{uwyu}u~tyxp{}s{{~r~w{}{wyjsz}{y~ux{tw|}|z{}zuu~}}|}qz{zzx~yys}vvw}|~}y~~t~|twk~{{yxmzzyz{||}u}uoww|{{|{{||}o|wwxxtu|~z|{~z~yyx~}{|}|{ruix{~w~y~w~rty|yp|}}u~wu|rvzyyxzz|}sz~sxIn~xvx{s{{x}zr||y{t|zx|{ut{rx{}qy{|z{wyxz|zvz~vq~z{xygyw||}yrw}auzs~zzn{ywy{otz}uu~zv}q{mv{~s~yov}zsz~}z{zztt||}}nyv{v~v~w|mytwezvz~}~y|x~m{ypv~o~yht~w{c|{|~|u}}uy}{yu{xt|y}}yx}lsyz}y{~s{y}~Xz~zx{wqwzx|yz}rymwqzur~~~z~n|zy~mrg||}st~uwtuzxwz~yygzz|zyzxyz~nyvt{~qrzvu~ypuzxsqsyy|}{wxw~jtwws~}{{}~{y|s~wz}wt|qxxxz{~v{}~zxxx~|z|{wxyz}}{~w|zuz{y}|~{s~|w~y|x|{{t}|y}}~|}xy~w||{~ws_w|{wwv{y{}~~|z}|z~}{zx}}}r}{r{u|ywx}|~zx~y|}~z}v}|yu}{|~~}{~x}}z~x{||v{}x|~}jt|xux{z}}~}l|zzhzx{y}|{z~z}|~{}w|}|{wu}xwz~zyy}py|~y|||~z}u|}|t{x}vz}|}{ur|u~yw}{xyzxxy||~~|zxyyz}{xxy}v|yzwyyqu|~{y~zxyz{tvxvws}|zyzv|hzx|{u|~yxz{|yy}|q~x}w}}yu{w}y}|}{~{g|}w}{vvxyzywzprr{~p}{zw~~zpwx~wv{{}}|pqxu{r||wx}vb|q|xwzzwo}}y|{}w~wxvz}ub|qwruw{p_|w~{y~vxy~z~ux{r}|m|u~vzmxv|xwv~xw}x|~uu~ls}uuu|uwt}w{|t|dvv|onxovw}|yw~xw~}xty~}t|}w}zu|wo{in|}m~kazzvr|pwwyy{zwr}y}zmwy{|q~|t~y~|s}xtxm{z}zqmw}ywuq{{ywzyx~}{u}yuzc{x{{x~xq~}w~~zs{|n~s{zx~~}|}|{~xw~~vv|xw}~{w{|yv}zwgz~xzz}t~p|u{}|y|vu{rt~{y{|~|{|j~lrw~vvy~|z{s~zx}{x}~}w}qvi}v~~w~yz}}y|}|{{r}~~u}w|x~uty}|v~|~~}zp|y}~zv|{zxzzz|~{~t|~}}pp}}~||y~vzox~{u}}z}{t}zz{u{~||zyy~z}xn~y|x~~y||z~x||x|w}|~x~~xyy|{~yz~{z}{}~j{}}~v|}}}}v}~z{}}|~{yzqqy~{z~~~{~z{y|}}y}t{y~{y{}wy|z}w{||}{||v||u{{~tw{~{zx~{zsz~{zw{}yyz|{vz}u~{x}z|~x|z|f~}||~|~~}~~{|~}||~uqt|}{~|}x}w{ytj~~{~|~u{|vlyt|vy}~~{{u|t}v~}zx{r{|z|qyw}yy|z~yz~w{~{|}vzu|}twz}}}}{~x~vzpv~~}}|~w~~twz|}y{s{}vyv{rkvxy|~}~zs~~l~~x}v~|w{t{w~~{{~y}{vs||xzq~r}zv|{~t{z}|ktw}}|zyuz{}uy|zz}j|}yy|{tt~~yxw|x}v}zqyv}y|a}ts|wxq|{ry|jt~u}~qy|vwxl~~r~vx|ur|{{xrz}|}x||||~jy~nvk{v{sltz|y~yxv~vsu}~~rypz~pr}t{}ww|~yz}u~u{j}v|{|}t|{}y}xn~x}~||xv}zzzxtv~~|z|{lz{}lvxyys|wu{zi|x||~~|l{z|uv|xxu}z{}zvw~ug{z}|v|z|w{xuy}om}yzkyZs|vxyzxvv|uz~z~yufzw}}uz}yu|||zyx~{yrk||xyt}s~}x{{uxwyyuvv~vuvjnx}}vuf}y{wzs}||zxkx}zww|yyzgg{x}wytpzs|}~y|{oqxz}y{u{~}~vvzv}{s{u~szr}|zww{z~~w{yl|z}vvtxzmwwqwzzsu~w||}y~}us|yvdo}wwy}su~~v{zuo~y~|z~|~uzk[zt|rw{zw~zpzxz~sx}u}ytyq}rrwmw{z|u{wuy~j}vsvua{szq}}x{s|z{ww~k~~}~}s{~xxzp||dqzrz|sydu{rpuswzqy{}zsyzysy|j{~wv{yvy|s{|um}xs}|n{~w{}~q}zxwzu}p}zix{tp}vxu}}}ywz}yy~{utxz~vw}uw}{{||x}~zz{{x}nu|w}w}rlx}t}v}w~u{~x{}z~~{s}~t|~vr}v|rua~|py~{yxy}z|yyz{{y|x{xwz|}z{xzz~ut{yxxtz|v}u{p~zzz~tx}~}yz{{|}yrrxs~r~o}}}}zz~tr{x{{zu~zrq{yu{wit~v|~{}tvzyyzuu|{}|}y{~u{lwxu}}{|ulpw|~u}putyyz{z}v~z|{w}{|xyy}~zwzzzyz~y}}y|w}u~{|~{wj}x}}|xvvw}{~|su{x{x}v{zusyuz{{{|z}}{~y|~rv~}~w|y~z|}rxxu{{|xyyzz{}|zty{{b||~s}wuxxzypv{zv~pxv~~~~}z{z{|~ry{}|z|{~y}yz{}yz}}|wu~z}{ywy|u~|~{}}~}y~||wz}n{|v}{{s{tyy|}{||~y}x||z}{}xtr~|vq{}z~w|w{w{|}yos||{~yyyy||uu}z{uy~x|o{|{y{|{}}|~x}{v}{z~{~|zz}~~~}~r}~{|}y}{t~{ulx~z~z~zzy}zs}x{vw}}z}vv}~}~yw}|zt{z{xvz||~}|{~}}y}|x~}~|w||||}wx}|~||z~v}}~||}y|t}}|zywy|{x}{u{z}}|zznn}}{{}z{zxxouzzz}ww|{y|yx|~|||xtzzwzt{{sy|y~z}~~y{~}lx}z~p|s||}z}w}{|zw}||~z}|vo|{szxx{~}s|nyw|z{vtw|{}~{{|wzxx}{u~~{ty|wzu~zvy~}vuyy{s||||xxy|~||s|{t]z|xztvz{{v~{t{{}}|{yt|gzw}z|p}x{uzy|}{yvzv~|~x}|v{xsy{}{|v~syxw|y}z{xu{t~zvr{~yy}ly|z{{|}~~|y}|jv{~~x|{uyzu|}{hrx}||w}}|}y|u~muz{zyv{yu}~t~}z~uu{t~y}}q{mux|s{|x~|~~ww{zoq~}|z|znvx{r~sywo|ctwwi|w|}zxp}{y{zz|zutz{q~w}ynyxoyry~r}{v{w~{p{vw}{|}oxz~w~{|~}}|vp{~~v|s{{sy~w{uu~z{}|t|}~~zx|{v~wz}yv}~}{||t{ytw{z{}{~|u~{}y|z~{}p|}{{x|pt}zy}yw|}{|t}~}{z{~~xw~xs~~zz}xz~w~x}|ys}~rwz}xvz~v}y{}}w~wws}zy}|~{|u}}v}|{v~s~|}~~|~zz{u|w~z{y~pxs}~l}vws{|zyw~}x{}|~zxz{x{}|xx}v}||x{sv~v{}|||x~zs{xq{|zw~}~vv}}p}o~y}|}|zz{|w}~{{p}uz}|||~y{w|w~}u~v{|{{{z{vsyp{z{||{{{z{zx}}|wyx{{{u~{yyz|z~{x{zz~|z}~}}t~{w{~zy|z}wwzwxsz|l~~{v{{zn{vr~~w{{yx|wzvv{v~y~ux~u~||{ox}z}|w~~~r~y||{xz{}rwky}z~~|uy|}du~z~oaw}z|w|}m~yq}x{yy~{~y{~vwuyzq{q~}||xwt|y}xyyvzzl~||{wvz{y}{x|vz|{qx~}|y~~{xyxsymyux{z|q{~wpzu{~w{{~{t}}|~t|wsvz{~|yrv|~}zz{}p{zz~u{y}|z|y~xwxo~tyu{y}zr|zvy{{}z}~{z{}~rzu~{y|yxwyvwz}zyzx}}y|vzvyz~kyvyx|otzn|w|~~{}{{z|t~{}}xx|v~yv|y}x}y~~{~~xt}{|{x}h~}}{|y~||zxp}~ry{xz{n|z{x~wy}}||z|}zzwr}{xzz~{ui]xpwx}~{~zyz}z~vz}i~~x~z~{~yokx}~zxv|r{yytwxx}p{|v~w~yw~zy||~}yw}{~}zt}{y}{ytwg~y{{{xz~z}||{~rqzlz}yw}zzyy|tuw|q}uz~~~|{{{}~|}~|tq{~|zz|~t~{z|o|}~}y~u{_~}}|izusfxxyx~v~{|~u|z|yzw}z~zkzz~{~~|{zn|x{{t~y{}tsppr~r~{zk~|~xtxy}wyo|{}|rvzz}cvq~}w|}ywz|zxz}~}y{|py~w|{~}~|rsu}z|{yz|{~{|}ypzz~xx}|xx}}mzx~v|{xu{~w{xzxy|~|vu~}|kwt{hu|zq~|ur~vy}|x|{}{{u{|sxu{xzvzy}xtyw~w}tryz{w~||yw{zxoty{{w}{|}p~}j~w|xs}v}u~zxrzvwytvr{kzu|~||}yr}x~u|m|}~u~~uyxu~~zv}{{~{u}vxt|{yy{my~qy{yvu{w~~~w~~zv{x|{uxyxxx~||{}|z||y}||~|{~qxt|wz|v{|x}r}{zmy|t}whu|y}wx|tzvz~smv~|zv}vy}~{f~{~zy{r~}|{u{}wy{z~w|t~{|wy{~}x{zqqt{y}~g}~}x|}~{u|wv|yys}~|xs|wy}on|}xxv{|}}xvwx|v{ty~|}~|jvyjrnv~}o|xy}owzzzt}uy}u{{}tr}~{{x~||xw|z|~wz~~}{t{|u|z||~y}|uw{xvxxm~xp{{sz~zyz~py}~uzzvv}~x~z|zox}x|u{}}xyxqnv{}{{z{uwvyzt}|zzzl|}x|youmwywv~v~{|xwr}~y|utx}xy~s|ycrv~yuv{yvm{x~wzyxzk~x~{ynvzxqv{{v~}{||}yrswun|w]t{zyzxmku~zu~s{|xw~u|d~xx}x}y~d|}}uvr}p}ys}r~{rvxou}}|xtu{txnmrw||~v~zw{zzssptw|{uy}~|}q~u|ysr}gm{y{x{z|vy|}|z{}xu}{yzs|~|||t}~~}w}z}|}z{zyrz~}||z}{z}~~x{}~|||{|{|{~|~{wz|zy}}z|~{}{u~{}{}wz{}x|xzy~{w{}|t|zy||yy}}{t}w{}szt|}yx~xy~{|{xu~zyu~}w{u|yy||}|}}sxx|xt|x{pr|~}{y~v{v~ws|x}xz~wv~~y~}}}wx|~u~~vsy~{|}z}}|yn~tu}~yr{x}y}{{y~}||{w~|y~}~zy~x}y}|x}|~|~{{x{~|~x~vzy{ssuw~z}m}~}x|}xz|}{y~{zyvwyz{uyvyzx|~zy|l{|}w|y~{}zx~z|wz{vz{v|y|x~~uyy|{vx~e~~|}{wy~uy}{}zzt}~~ww~fw{|~~~}y{vg{~wz{}}}}}}{zr}z~}~s}{~x}z|zxx~|xry|p}o}{z~~w~|m}~{yy~|u|yzt|swwl|~~|qszz|}|wzx{zn{|vxu|||~|y|}{}}~|}x~q~z{{}}||r}||x}~~{|ywu}v}y||~{s~tu~p{~z~~}}}}|}}|~z|z~t||}}}yu|}j~xwz~z|}|~y|wq{{w{~{~z|~xz~y}~yxz~{t|~zy{||}zy||yts|y{pzw~}~zyzx|~x{x}{}v{||z{}}zs}~r|~y{s|wow}|||{{zvzz~}{yr{~zu{xzyxw|xwvy|x|x~||zy~tyt~}{uuyu}|{xqzf{}wzzz||y{|x~~w{q{z}{}t|}zxw}~wv}|uw}l}}{y{xr~}}{|{~zx~vx~~wu{sy}uwup||uyzyw|~xn|v~zx|x~|{y}}~xy{x{yxz}yus|z~}vz|wzr}{y|{|~~|tyvurz|~}}syzts~zyz{{s|vxzxxwwzw{su|}t|x{}py|~}xz|xuy~~v{{zw|}{vwyxvzw~yzs}~tp~~u|y{yzusswz|}ztx}z~ux{}~uvx|yytp}uvyzw~~uzw|{o}}y{x~||v~tyyqy}ww~}ymxzuy|rzwz|zz|zx}tzsv~tz}|{zx}~ut{~||z~yzqxw|ox|{}wrykv~z~zyl}}wzyw~xzv~~~ryt}}xy}z{~}}}x|zz~{~}zuxzzx{~z~elyttxyzvt~c{|vvtx|~{yy|}y}ux[p`~{v~gx{}z}xl{wzgyx}{uy}||{~x}p|z|~jw{{{nu|ut|}~~gyyxr}xq|zzz|{y~|j||q|}yslwpzu{{nw|v||ry{}{||}}v~~u}|xx}|z|xz|{v~y}|zx{~zv~wsqxw|y{}z{yx{q}y|{yrk{w|xzRxfyvp|Vy}p}k}v}}y}xoxy}}pox{k||yy~}{|~}{qy}}~~zvwzyyz{rz}x||sw}|||s{xzz}u||s}m~xtt}}|~u~|yw~|u~yxl|w~z}trx~w}ywoz~}~xyy{w|~{~zzzv{usrkv||{u}r{s|w|qs~z}{zzz~v~{zr|~{qyo|{v|~|{vvxu{}|nsy{|z{{zxy{|s{u}u{uwx|{}|{y}~xt}|~{|~|{zz}r|s~z}w|}ys|yzzso|}~{{zu|w}}{{xx}}qytx|{t~~~x{{zy}|}}}yx}|su{|jwz}wv~~u~w{{|y{t}vrws|{x|u{|||}vy{|}wszxzp~}|~zvixq~zovp||zv}nsw}{zwx{x|t|zx|zzys|t}xxt~uzy{xy}x{z}zv~~xwv|yxt|~||}}xpw~|~ny|~zz|}{}x{|xw{~{yy{z{zysx}fxzuxw}~vz}{{|{r|{~wz}~x~{}uzq||vw~|rhvyu|xyz{|}wstvz~}u~zmzwxx|xw{wzo~zw}{x~n}|xvvxxy}wq~{|y}vy}{wx}zx}vvvyyyw^~~py}~{~y{y}~}}yz}x{hfy~x||xru{{jxly|||x}~{{x{~zy~t|w}~xuzyzwz}rzu~v~wu||~~}g}~{|{wzuo{{{v{x}}~}{s~xyw~xw~{vtz~~z|u}z}rnvr~{g~pp~t{~}z~lzy~x{|{z{x~ouw|t|zwywr{}z{|y|xww|xyy|s|z}zu{yv}{sv}{ys}|~y|~yr|lxwxx}txz}xzz}yzz{~{z|~}z~w|}z{{~}yx|}}|{}{|~y|x~y}{}{{w{|xzpv}m}s{~y~{}{||xv|||w{u}~|yxv|yvzz|xo|y|}n}yv}twt}szz~|~xqw||{{}u{yy|vu{v{zz}sx~z|l|yzy{w}u}{t}|z}t}}yy~x}}rxy}gz}|~{|x}{uzu~x~~xz~xys}x~~~ytz~x|yrzzw|{{{|~spw{szw}}zvxtxun~{v~~xzyzzz{|zz}xx{yx{||uzvx~y|gu{{x~|~{~tv{~}stz~usw}x|v}|xz|z}{~x~|x~qv{zzy~}~v}xuz}{{||_{w||zz~yyozt}{{}y~~~zo|xyzpeu|tztvqz|x~zrv{z||d}~~xw{~~{v}}s~ywwu}zxp||}z|y{w|yvy}|yz|}{vyvmwyxvtr~w||{nx{||v{xv{~vvi|zu}{vy~|z{z~}{l~{yx}wwsvz{|zu~v||z~w~{}w{yr}urt{{w{uxvy{srs|yt}}uw|xz|yw|~s~}}wwmy|{wvyxux}zr|~zwvzzy{oq{r}uz~orr~w|~~{zzv~~~x|~g}|u|}{m~{w~{~|}u~zs{zx~xz~{ws~zv|~||{z}{~tq~sy}|zyx|v{|~{~v}}{{{{zumww|v|v~|fsxrx}y}vyyr{s|wvx}t{~zx|{ux~v~~zzv{x|~pznzsovyu|x{o~{z{u}zz||iz{{wxz~rx}z{ut}{x}{{|qryyx|~y~}vw~{{zzy{y{}||yx{n|~x|xz~|}|{vu|mxy{yzxzx{~{|~ywzy~y{w{~xz|}|m~{}|w{x~}yx|}}}|w}p~{{u|{{||xyt~~}{}~y~|}{||}s|~zy{zvxy}}w}|tvt}}||z}zt~}y||z~x~}rt~y{~sy|xv}zvxyws~~}~wuu{~s~|||||~{~~{~zuzu~y{|}}wz{z||~w}||{~|~z{{|y|uyy~zt||r{y|}z~wwzvttv~||{xzw|pu~~xwz|{}wy{{s~x~|y{}}}ywt|{}|z}ts~x{|xx|}{~}z}~w~w{yz~~zw~{~|z}}v~gywvxwroz}|v|~nzysyx|~q|}z~nr||}}yv~zszxjq}}v{|uzsxvx|syvzx}}zw{{}~xxm|tuxk}}{z|wy|~}uyzu|twq|qyz}yyzyr|}t}xxz{}~yxvz{~{xy}w}zyw|su~_xkwsv{wx}{wm{|}z~r|ztvf|}y{}||st~alwo}k~u{}zjwuzzooxth}}yzx~{{z|lsyxvmt}z{{uw~~{zvy}uu{mq|y{~rot}~ztxz||yc}{mpy~s}}|qp|{o|||auzy||{}zzz~s{szzzlzw}|~t{vvwzyovxuxw{qxy~y|~}w}u}~|{}xw~}z{s{yv~{{mzv||~y|r||r|x}}x~}}{~m}|{~}zz~zty~|~{s~vzwwzyt}|}{{{~}|zsy{m~z{w~}x}||w~u}{}~~{|{|{zt}{t}|vz|}{|x~|~{rw~~~y~|~|{y~~{|z}{}z|}zy|}z~yxsz~}y}~u~}{|u{{yzut|}ztx~{}}xuz~}}~||}~~}~}z~w~x}q|~x~yq{y{}}||}~zyv}~y}}xx|z{yl{rv}z||r}{{~u~}}yv}{{{u~}||}w~xww|z~n~z{~}}uw|}y}}m}~u{~}~vpz{zzzzvwzq}x}{}~vuzyy}{||}}}zz}z|x||yy|z~|{||ywmx}~{z{~~~}q~|k}wq{~z|x~u}z~w}x~wv~z}~{xry~o|uxt|~~ts|yx~}t{zz|{kz~}t~{z|r|yz{~yu{}|x{x}{{{yxy|w||yy{|svut{uszuw}y}w|~y~y|yz~}t~twv}w{~{|zwzyw|}yz{~~~xx~~~}~~{{zyv}zr{rx}x~x|}zs}|~zpz~|~}}~~yxq}uz~rz~{w|xz}}v|v}z}|{}{zyv|{|~{}~~y~}sxw{{~{xz|v}yy{}~{yx{zyuy{}|~||}zru|}}y{}x}||}{znyyyr{||}|w~y}x}yz|yy}~z}|xv}t{xzu|qzy}xz{}x}{|y}xusy}}}y|xv}z|~}{~|y{{x|{zl~|yvxv{y{}|xyh~|x{{{z{w{~y|}}{su}z}}~~|~|~}yts~w{xt}~~}y|w|}{~{xw||yzz{zv}xyyq}~{s~|}||{}~}{sw|w|z{~yz}xys~w}~y{|}}|}r}}~z|zz|{{}|{}o|zsz}~{{x{qwtyyz{}v}~{X}{~~~{zy~}~zzzz|wxz~}znnvpu}|}v~}{~}z~~yz|y|~}y}|sw}y|{~z|x|z{v{usvq|l}|tvzirtz|x|vxs||}~}|zxx}xvg|zz~z|~qty|ys~z{|y~{z~}}~y}v}y}}vwy}{z~zvp{~y~zmimx|||v~r{vx|wtzzy|}|xzx|p~qyzy|||i}{~yuxyz{{}|sxz~}uyv~|{}r~xpsp}}wt|uvzs|y}|{zxxv}~xr|{yzz~z}ygmrwq||{zizwytz|sz}x{~w~w}~xi{njz{wy{{~}rvtp}||rw|tix|ysq|~~~~yw{hxvzl|zqz|zl|wu{xow~~}oyw}u{~|t|zz~}r{|{~sxzx}~{{|{mzx{ut{yxz}|z~r~ry}~~|}yv||{www|~m{x{xzz|zl}w|yy|w~|~}i|~zy}~zqxm|{zx}y~tzt{v|qz~}ow{}yz}}|~zu~~yyuwvuu||{}y{|z~|}zrzzlwy~}tw|~z}w~ptty~~s{y}on}|yx}{y}swxwepw}}}q{{}~l|{{zy}}t|}{}~|~zq{{n}~|vz~}~}}{x|xvy{{z~{|{|{~x|w~|yuz{|z~~zyr|~}~{}~||}}yyz}~}~~~~z|z|{t|~}wx}wy{{|y|y{{w|x~|~{|}~z{~{|~{z{yz}{}v}~|~y{v{yvs}{{~}v}z|}x{wzyv~}{~}}|swz|{t}wx{u~{|~u~{{~}|}ryy}}{{{}zy}y~w}}s}}zx|{|{}w|{yzz|}~|y}{}v}n|t~{v~~~ywk~z}xwz{|qv}|y|}~}u}{|tz~t}{z}~y{x||{|y||~zx{rz|vwu~{||}o~yuy|wvz{sr|g|zv}w~t}|qz||~y{{nt}yzx}}~s|z{|}{~}x{swzzo{uxyz|u{s}vr}{yx}v|zoy}~|zzu}y|tvw}{~yo|r{{xx|w{}s~z{y~~{|~w~x{uz~yx}|xs~|z~x}v}x|v}yq~v}|w{}y}tvr|~z{|~wv~|zz~w|t|}|zy|}}yv|uz~{}uy}ww~su|{ywy}~}~v|y{}xyx~}|~r~~~~}u~}p{vm}|y|{~wx{z~{}z|~|t~|{|wyvy}x}~s{x|}z{|n~|||yuzv|~uwx~|xwv||{xpx}~{|{z||{{~~|{yrxx{xw|{|z{}v|t~p{z~rxxv}~{{|i{qz~uy|oqv}zx}|vt}z~}}x~~~}o}w|yyx}xvwyy|xx~|vwt~xy}~}}z~}}}xz}|~w}{}}|||zy{{y|||~}s{y|v|~z||x{sy}x}{w|~}}~}suxwr|l}q{}xw~|}{}yq{{y{}}tvz~xzsy}y}xv{||~|||~||wy{}}w~||{y||o|{z}yyu|lv}}pi}|yy|{~z}x{}y{}|ywqzy|{~|tx}y~wpoxsw}zyyyz~{{|xxy|yz~zxmwzx}{|wryt~}t|}zt~}{{|~{|hyxqyyx|y{}r|s}zlw{wyzu{v{z~zz||}|~xw~{{y|~|~sopxuvtzst}~~{}x{y{|~}w}yxuu||}~{}{s~zwsv{|rn{}zx{~t{k~zu~}z~|z~}|xv{uxxy|z~}}v}{w{{y}~y{~~||}zy{~u|ylg{zx}yv|rx|{w~|my}x{r{|y~tz{tw{y{|~pyyr}|yv}vx~}{|~|syvyzw{t~~s{}uy~~z}~{yyzuz}~{}{~}rin}}u~~~}|zt}z}|{x|ur|~||zlzyxx}y}}s{v|z|yvzwz~~|{v~|}o|{~|wz{k~srk|zx{x}uz|p|ryz}}{}~z}{xv|~xuto{t|~us~~g{v||~u}}~z~xwzxy{orx{{~~}z{z|vvszpv~y}x}zz{{uz~q}{p~szd{|ypx{r~~y|~}}y~{u{{{|y|zxypk}x{~|}}wz|~wgkfyyv}~|x~gzz{v}}x~|tyz}y||{~y~{~|{p}v}}}ux}|}z~{zv~p}|ty{p}{{~}x~}i~yy{}}x|}|~l}r|}}zx~}zw|`}xy|qur|}y}yv~z{|vyys|~w{}us~|yz|}z~}w}w||~x}rvz{|~~z~z|{vsyqnzxe|x{}yy~~t|y~~}|uzr}u|z{~y}{{vv~}|}x~tyxz||{||~~u{}v|yy~|~{{wv}w{~{x}}y~u|y|~~uy|xy~{tz~{u|j~vn}q}zzzy}}}jqvzwx||x{}|u|y|||{~s|z~{h|y{~}{yzxrs~wx{{yy|~{y}{}}}y}on~}sfz~~|{u|xtz~v}{yyyttzw}{w}}}||n|y{~~vw{|{{}x~yzzz~}z}sxxt{xyy|zy~~uz~|{vzu{{}~xpy}{{}yw}}v`~}{|}}w{zvu}{|x~wz{~{}}{~~}{vst{|}zwyy{uxw}y|{}v}}|}vtx}}}zt{{~zy~|||~{{vzzzz}|zx}}||x}}zwwr|zyx||~}yx}y{w||qq{z|~}oz|{u~{}~{w{z|||z{|~}||~xz~~~|z}||{|xwz|yu{|x}|xy|~|{~|~{zq||}~z}zzt}~z{z|}}yxvsy}zt|}{s{v~||{w|ur}|zyw~|~{{vxz}~~|}rz||}twy}zy}~~||{z}uyxwz{y{yw}y|||y}zs~s~|~~}z||{|~}{|w|s|~{v~||}|t}z|q~|s~y}|~}|zzy|}|~v}}{~|{}|yw|s~}~x|{x~~w|}{y~~ywz{}}wy||}zq~yu}}|~zu}xwxzzz}w||{}x~|{|{}x{{|~~~uz|{v}{}}}zz{~~}wsu~{|xw|}}x}}~zzw}|}|}||~~ywzz|{z~y}}zw|~}y|{z{v|zwy{~}||}~xw}{sz|x}x~y|~}}{z{{yyyyzoxx~zxz}|}~y{~z~stwuxzx{v~yx~{}zywz}zz~}{yzw}~xx~{{{r{|{yz|x{~z}{tyy||x}}~}y{{wx}y{|uy}z~s|z~|pu}~yr~~y}y||~||y{wz|}zv{xwwuy|z|~|}v|~~{z}w|~~{v||x}{r}}{}zwt{x}|}y}|}z~wnz}{|z|w{xv~~~wu{|sv|~{z}w{~|vxz~~szxz}rs}z|}{}yt|w}{tuu|}uy|zzuuzz|~u~{|{}y}v{{xq~wzz~y|w{~x}{xzx{}~{r}|sy{y|{|xt}zw~~p|}}|{x~}|}tz{}{}~~|yy||y|}xsz|xww}{zy~{pst~}y~z||z}{{z}ur{|{}z{{n|}{{}~}xztz{}vzz~|syzs{~s}|n|{~uyyw~zzyzv|}}{z|xyvwu}u}p}z{{z}yxz|{z}v{~u}~zx{uw{{}x}|~|y~{{l||w}||yz{z}z|~w{}}{}z~|yz{x}wx|{z~~~tx}ysw{w}|z|||vywzz|}uyu}r|z~}u~rl{v|zv}~~ry~t~x|yw{~zmyx{zx~~}xzzyyv~mv}~{|~dq|}}}z~{||{xqyzuwuzz}y|uz~}wy~~urz{yw{|~{w{vuyyjxwxywy}~~{}}~x{w{}}y~}}{~~{zw~txzv~||x{v{}z{kzr}{stc~z}v|zx|{|ozw~sx}vyy|uv{~r~}~vxz{~w}yqvi|vq|w{|yr~y{yr{|z~wy}v|y}{|~qxy{x{z}}y|}wx{ym|{~{yvw{{|~}{{wz{~l|}zuw|{xs}{||nzxu{y{~}y{yr{~zvz||}y{~}}suyz~uv}}}zyw|~|}y|vz{|vz~yuz~wy}}}~|y{z}w}|q|{w|{}y}~z~xy{}zzw}}o|~x|w}z}|~yy|{z}{{y}}v|}z}~uw|~u~~|z{{|~zu{{w~}yr~yy|}}}wxu}y|{zx{u|x|{~zu{y}|yv}}z|~}o~|~x|t|}x~~}|~|}x~|v||z}{~}rut}y~wz~y}~z}}|}z~y|zw~|}{|~zz}zyy{|}y~|x|xyt{zy}yw|tyxxwxyv|x}u}z}}xwz~{y|ut{|yuzxz{~{~{|{~}wxv}~}|~{{~wywzwy}z}|ys~zuz~}{yz~{y}zw|z}w{|~xprwu}}xw|y|u~s~|zzz}{}{|~{{xvv}uuz|}}}zyt}xw~~}|z|yu~}~xv{~{yuxxy|}~z}z~{x}xw{zqx~y~{yrww}{uyq{rv}mz{{~{}|xy}yuvr~wzryx|z}}~~zy}~xwy}~~|xmwz~y|z|~x}~|q}}|zrz~|yfyx~v{|{wxzzr}v~{|{{|x|yv{{~sysuww}uyzz|}ys~|{ws~~~x~|w~}t|z}|~yzvw{~u}}}z~|~|zq{~z{~~~}{tz}~~s|}}u{w~|x}|{~}~x~{tzzvztwxzzyw{}zx~~w~~o~|uz|{y{xv{zzzv~}~~u~rx{}xxv|v~yywy~~z~txyzxzfz~|~|~}z~}|}nz~zyzwyyotz}{}x}~yk|}z}|yu~|}~~w||v}zy|z~y~xzvy{x|~|}|x}t|}}z}l{}u|}vzw|{w{zz}{zz|{vzw~{c{z|p||x{~}y}yz}z{{}~|}tx~ts{z}}|q{y}t{zr|p}||v{z|}|y{|}|{}}~{}w~utzzwz{~|v{m}~y{yt}}|{}z|wnyv~zx~xzyx{|y}}}~|v}{zxy|{w{w{yq{yzx{w|wyv}||}}~~}y~{t}zv}}}~x~{}~~|~rx{t~~~}~xyu~}vy|z~|uy||}t}{yyx}||x~}x|}}utp}|{zu}u~uuz~{|tm~|vu|x|||}|w{oyyy~{ytxuv}|ww|vwo|xw~i{ra{{wy|zn}rzzw}z~vs~yzuyqvw~|}sx|}|{wxvu}{w|w}z|}x{h{{|xx}}x||u{t{}|w|zwv{m~}~vyp|~yvkx|x||~|`n}v{u~xG|~s}x{zw~~~}x{s}ys|~}{r}Vr}z|{ywv~yz~~||}zwsu|z~{y{t~g}xz{mz}~~|~{}~ww}kv{wywyysc{{}pz|{}zr|zyso~{gmo}qtyuw{su{{zyyz~}{{q{zwx}pxm{tvyw~zt{tw{v~st~s|}vt}tpyx{{}xi~y{}y}}tr~~m~Rzxu}v}y}}r|{ulqy|py~|x||ox~}||{|tu~zy{ur|vz}~vxsvnw}x~~z{|}}~~{{|x}~}}yy~~~~x~{}~qyk{~~xx|~}vr{xz|zy}}y{t|}{~x~|}|zzow|y~z~x}|y|}}~~{|xs|wv}u|}u~zzvszv~|v}x}~|{~}s|{|}usx{{~r|wyt}~zpnx|xyz|wy{vv||}ys}~u|}zy}{|o}}{x|zv|}x~|}~y~r|y}{t}|y|y{w~|zv|{ux|s|}~yx{{yx|yxw}uyy~zyxw}}v~v|{|u{|xzu{~w|}xz||~rx|{wx}{~v|}wy|r}|~w~}xtz~v||~|~~|o|wx}xxvxy}x}{v{~~x~y{tovv~kstzwyu~|ynzzzr}~v}~~{wk~{wyvw|xk~r{u|}~}~{uv{{hwwy~yux~t~q{x~v{~x}x~|vx{zwz~}~tzu|zrrys|{uzz||wz~rvu~}tyo|v}yz||~vl}yvu}}{|t}ttzy|y{{qyvww}}{~wugr}|x~x{m}a~zay|~zxv~||ssyu|~vzs{}|wtlv~y}}|ztvw|}soms~y}~y~u~xsvtywtwxvv}~z|dz~z~~|~}~|}y{{yu||n}{{~u|uqz{u|w}~~x}yy|{zr~{xz}ujy|u{iyy|uy{vt}uymu~sy}~ur}x{yuu|z{|{{ytyyuwyWx||}yyzx|z}yzx|wy{v}|zz|xrw}qz}ys}~|vy|}z}~|~yz~~|wz~~|yx|v~xxuzr|x||{{|~{~}|||}|y}z}|}zu|zz{~{x~z{|~ywv{}zx{ovw}}x}v|}}}{{{~vx{x}}v~~xy~~}|~}}v|z|}uztyy~~yw~}zy}wzxw~v|{{y}{}{~~~y}|o{~zv|y{|~wuzo~{~~y}z~v~yxxz~z}}z~|}{z}x|y}{}{y~{y~s||}t{||~~wz{~z~pvpzw||y}y~~vzw~x~q}w}}uzw~|{|~w~~{~yx|v{|||}w}y{z||z~~y}~~}{~}zxzz{}u~xsvxty|wx~}}~}t{ywoxnx~~|{s~x}zuy{tz{}}yx|{z~|z}}{y{~x}{}}~vt}uyz|~y}zy}~v|wz|s}pv{}s|}z}~|x~}t~{~z~~x}y{{}{}vz~~tv{~y}z}{zv|}vyr{x}vyx|~}|y{o|ztw|yn{|{z{{~~x|x}}w}~wso{|y|}y}wqvsx{{{x{ur|gztyu}}m}}}~}y~y~w||~{js{~|}~}vaw}}zx||x~{}zupz}}~|t~ywx{z{|{|}|x~x}}y||}}ww}{yx}hzxxz}z|u{z~xw|y}z|km~yv|y~~w|ux|}||{y|ztyz}z}}~{||~~|x}u}v}~}tt||{wzv{rx}z~~|~wwxtz~}}y{v{{v}~}|zzr{{yz~y}y}z~~y|{}zsx{~~{z{wy}~}oy{yx~{z~o{w|}}~xwv||}~~zs}}yyssv~{wyx~{}}|z}|{t}}|zx{}~y}p}wrz{{z~wzt|}q~}{||{|vk|||xzu~z|}}||v}|y}x{w|yxz{|z|{{zt||yz{~{{}}oz}ry~u~~txwz|wz|zyt}{~yr|~~}{}z~zv|w|yv~~}x~z|{{~zs~|vy}|tx~~|~{ry}}~v}yxzt|zr|zyuw~}|xzvzz~{x{x~y|~v~xt~{}z{ys~{sz~zy|{t~~{xwu}wyv~~|~zz}t~{}zyxzxvs~{zlyzz}x|||{|vu|yyy{~y}{{z|||p~zv{u|~|~~|~y}{zyxy{u}x}~{}|y{~~}|{w||wv}qzxux~s~{z|zr|~}{u|y{}{y{~x}{{uzu}~jy~y}~|{ywqz~vy{}yyy{}~p|}}nv~}y|u~z{yxz|{}x~~zy}}~uwz{w|zsy~x}z}y{}{vz|u|{{yu}z}~tt{xp{~wt{{{q{}w}yuyww|z|zw~~}~sx|||}~xz|}~|}}}|~yqu}zm~{~zy~z{ss}}y}v~zw|v|n{}vwzv{{~x{z~}~uszxy{{|z~}rt}|t}|qyr|w{xyxyv~w|x}v{}}}jxxv|oyyxzz|tt}zvu}~}{t}|tw}{}{{zn~~x{ywtz~{}|zrxw~{{w{{z~~|z{|vzv}|z~xv}xv~wwzs|~~z{~t{vy}vy}|~}zyzvv{{}x}~}{~w{}{xt}}z{~|y~v}zt{ywzr}~{|zv}}~y~}tv{~||z}}{x}x{||{~zvyz||zz|{z}z~x}xv{}{|vtxs}~~~z{~ytzw|}zy~v|{~zzxw}v|y}}{}{~~~xxzxx}~|zxxj{|r~ywr}y|x|yzz{}{xx{x}w{zyy{{|~zzoz|u~q|~xyz~y{}}|t{{z||x~y{}~z}z|~u{x|txxtzzvx}~||||y}~{{x|tszyx~y~}y{st~{zzx}}{|}}m}txu|t~n~sy{~~{xy|}y~u|}zy}t~xz|}~{~zxv{ru|}~}}~}x}|z{{{~{y}vwz~w|}|{zvy}~~y{xk{{~}w}zr|~u|x|~z~zy|y}}|yz}z{y~{zwo|~|y|~t}p}|{y}r~{~nxx|}x}y{y||xz{{xx|}|}}|}~y~n}v~}zyju}z}|x~wzwy{{}}xw|wl}~w|x}~||x}~yy~z{}zw~sw{~||q{yyzw|~{}w|}zyx}n~}w~{|yvz|y~x~|z|z~x|r}y}~su~~||u~zy}x|~yz{x|||zzu~ytxw}~q~{{{|x{x}|z{}xrqw}wz{}{|}~}ny|~}|szz~}}||~|~||vz~x}yzv~}r{xd~x{yw~}y|}~||{wz|w~t|~}{hy{y~z{vz}x~z|zyv|zy}~zx~}||yy{~y|zyz}}t|~}}ypx}|}}z}}tyxu|~uzw{|yw|zw{wz~~{u}{w~|~{w~u{u{yzw|x~y~y}}z~~~}|xw|{|x{{~yw~ztwy~{|~||vz|xy{||wx}||w|~s}}zw~z{wzz||v|}z}{~z{wv{y}ymv|yz}}z~|yvyw}{{{uyy}}||zpx}}}xy||yxyy|rvv{~}v|{|{}s{~{v||y{xz}|uy|{mxzv~v|w{y|vz|xz|{{y~}|wyz{||}}}z}txww|{yy{{{x{|}xup{}v}{x{v}}~zyx|{~{}uwy}|||~qs{}y{v~}zv}{v~}v{|~}}{{zzxzu|vux}}ry~~y}}{~{~~~|}v}{v~~}|~{z}|{}yv~sx}|y|}lZ|kzy{~}w~z~}z{{}s~t{{vyw~{v~z~y~|}sx|}~|x~}y|l|}{zvu|{|~zz}}wwu|m|y~y|}~z~}}{tx|y|~~~~~u|xx{vwy|\v}u}x|{|xv~|w~{{{|~qyryou{}~y~yy~yyyx}{s{~z|||}{~z|s{w{i}~}z{{~|~}w|~|~}w~rwzw}y~z}u{{t{zqy{}|}|}y{hv|z~}s{z|}}|zy}~||s{|{|yz~}{~}}|~xs~{ru|}||v~{rvm~||{u|z}t|}}}{oux{zxwzv{~j{zyy|txzz}p{wz|~zxz{||w{~{}||{y|~zxx~yv~qywowwrzynz~{}|oz{xmru~v}zzp{z}{|u{}zx|}~~{vzx{}xn}~y{ur~xyx|}}~z~|~}}}|qyvw{qn}y}|{y}q}{y~~{~w|zm}v}~wzyw|}}{}wpx~tswv~{vzo{~v{v}~|x~wz}yx{}{~sxzzy|ww}{wu~}~{xz{o}}|n|~~{~~vq|~}xs|wwz{w}x~vv{|mz{{~}z|vwy}twoy}yxuz~~|~}w~vuwy~}|}uisx~yxzzy{~~y{}y~||zwy~|}u~w{|x}y{u}z|vwum~}}uyzzot|}y{x}z~}xto}}|ywy}u|{xv}~u|}y~qy~vw|{z|||w{z}}}z}w}vx{yx{}|~}|uzyx|z~zy~tqy}|~|~y|t~yvz}o{|{srx~xwz||w~|y|~~~u|{}~}~xyz~{}sz~~x}tx|zz~~|}hzuvu{y}xyyx|z|zyyo|}rwz{xyzxptsn|uwx{yz~z|{zw{t{}~{x}xw}wx}{}x}x~~w{x{}}{y~{zx~z~~z}zu|yx~{j{||vz|}{oz|zx~z|{}~~z}yt~~{{|vxx|z}}q|~}{sz|~q~wt~xzwyy}ywyyxyz~|{{y~yz{rwx|z|xxzzx}}x~{zzr}|||tyszxr~{xvy|}yz{w{~q}{|v}yxv{|{z}v~x~}}x|rl}~uzw{~xv{}sy}|~}z~s~}}{{wzv}{u{z~e~~t|z}}zzw~}v}{uxrw}~zw|}x}~~|{x~~|}z~}~}}xxt~z~|q}|w}~xzv||uwxr|~y}{u{}}zt|}s{yv|zxv}y~zzz}y~zzs|{}z}~{|y|||}|{~w|{x~uy||{~zy|z}z{{zvzx|zxy|{z~yw}zry{rxywwxwz{~~wwxxw}v|xzu~zx}{qu}{x~z~}{~{{}~wt{}{vs~{}g|{}ys{|}}|}}}}}szzv}}w}z{{~~~xv{yyw|y{{xynwy|~}}{vt~{xz|xx}}~|{x}y~y}z~}zzx}zjv~yzu}zy{wyx~}xy}{zuy}vx~|ww}~vwmyv~q}z}{{|x{w|y~wy~|x}{}|}~|yz{~zz~~xw}{v}v|}w}x~{~}z{~}~|}}m{}{r}{z~}~~~y|zzypx|z~{v{|xyur~}{}}~w|{py~xxsx~x}y{~w~~{|}s|zzxw|}{{ywzs|}s|{x{yzz|tzz}z}}wv{zm|~|z{{z|{~u}~}xw{s}~~t{}zz|{{l~ozyzzxyz{}s|z~~w{x~zy{~}}yuw{yvy~||~~zxy{{||t}|}}{|vxwu{|o|v}}~{w~z{zu{{z|~x{|~~x~z|y|}vzw}vv}w{yyz~z}~||{~{}|n~z}vu~xux|yw~z~zz||z~z|}|xvx{wz{zx{zr{}ww}|~~tyyzy{{}rzxz|~{}u}wx|}|y{}}}}w~}n{w~u}{{y|~n~~zy}{zrv|zz}qzqy}|vz|z~z|{{|s~v{y|uyvtx~~}z|w|v}~{~{|yyz{}|}yrxzy}~}sw}x|~}y{y{{|s~z|{|z{x{|}z}}tybx|t~}{~~z{xx~~{~}||}{t|{tu|vy~~}ymzzr{~{{}yusp}}}yz{~}mv{|{oj}z~zzw~~yz}~~|z~zz|~z}~uwr}~zz{y{x}|}}~|~y~z|}{y|}{|xx}|}|w}|}y|w}~x||~x|vz~}}~|}uz|}}~}{}z~yx|~|{}}{{|z~z{zy{yt~~{{s}~~v{|{{~yz~|uy~us{z{}zx{y~~|yy{z~rz~|||~xu}{xz}yz~{}|v~w}uzz|yv~wzw{v}}z}|yz}~zx~~y{||tx{v{x|yz|p{rshwyu~|z{~|y~}wy{{}|}~}z{~|wzx}vtu|{xx~}}y|yzw~~{y~~y}}z}}}~wy|pvw{|sz|}{w|{}jvu}u|xwxuz|}}x}}{vz|w}x}v}xxyv~}}}m{}{w|}{{vyzy~{u~qz{}w{~uyz}|u}{z}~{|w}wv|~u~~{~{w}||}~|~}~|||xz|}z{}{x{{{{tr}|x}}|u}|~ywq{{tq~}y|s|}~|{}{y~|~|}vu}xy}{jx}|u{w{|w~}~|w~~|y~zr}svyv||~z~u~}}|yuv}{|z{~|yz|y~z~pw}x|xwux|z{{owy~yz{{~w|~t~~z}}|w{t|~~|uz~~}w{}rv}}{}x}|~}{z||}y|}}{}xz{ux}|x{}x}qzp{q}wy~}y{{{ulqv}{{}t~txpv{uumzuu|}||uzs}u||{}|y|~}}ty|{{o~t}wtx{sv~wyzi}yy~t|{rzy~~|z}vsq{yt{w}x~~}|u~~~}|zy~nyyypyzu|~{z{z{zv~|yur{q~x|z}~~qxyyzyxxv~xz{z~y|z~~x|y~}|~sx|nx}~|w|}}w{w|~|{|yzzx|}v|{y{yw{{}~lz~|{}}v|~}x|u|v{{|zz{~w}yx}yz}{}v~pz|~xzr~}z}{{zu}ty|zv}z~y~}~x}~|~y|zy~q~uu|vx{|}xy~}z}y}z|{tx}w~~{zp~z{yssx~w}zo~|z~}{u{|yo~zxw~|}yvy~||zy|w|{{s~qyz~}}|zxy}r~}}|v~m}{|t{zzmy{x}|xy|wz{zyy|wy}{v~z~}{}{}u{}yy|vzt|zyz~~}tz}~}{}}}|~z}wy{z|uy{wuwzzz|yxsv}z{w}oy{~}z}|yyzky|y{~~~~yt~r}zy}|}}y~}}x}oyu}u{~}||~|w}{}z{vzx||~yyy}~{vozyxxz|z{{z|}{y}yr{z}~xxv}~}{yy{yt{{|wz~}|}xx|||{}}~~{|z~|wzvwx}zyz~y{|{}}yx{~v}z|w|~{~t||}~wxq{z~o|xxvs}s{yy|{|~xz|}}~}~w{}|}}zp}{w~|}}}}z}zsvt{}}}|q|x}q}~v}}}{z~{z{~}y|}||v}~~{}||w}x}|{xv|z|wz{y|{yp}~|~{}usvz|~|~zwz{{wx|x|z~zzy}|vv}|o|z~zy|zx|x~|zuepus|vs{z{x|y|q~luyc}}|os~wzr|u|vw~wvv~~psvw{xwzxx|}yzuv}}{|imz}}|}v|{q~wmsxxwyys~{|Wqz|zvuv~v|{{s|~~zvpmz}yx|}s}~p}uzp~wn}m|wss}}|~}wrzy{|m}}v~{gt~|zy{-|}yzm~x|uwxasky}s}zowwxzu{wk|wv~{y||quzxzozh~yL~}|w{m?qrztxwvtywwo~w~|w{x~}zy}xrqlv|{~~y{~sy~y}ngnpoqzx}p}ylw}~fw~~{yyw|u}y{}|sz{{vnyw~wpnz||di|low||vz~zb~|}uwq}v|~{g|y{yz~ysv}z[syzs||yvz}|z}ruw}{~z|~x~}uzy}yzyx{xs}~~~y}u||{vu}t|{yw~}{~}l|~}{}~v{z|t|wp{x}}}vzt{t}f|ty{nxu{~x|v~lv~qwwy}xyxnx}zy~|zy{|}|v|qxuszs~z~v}|{l|}}}}yu||z|{}||{w}zz~u|{z{xyzy{|~u{zvyyxyz}~zx|}~v}}|vz|vy{|{}yyy~{y{}|~wz|zr|~|xyx|wy~u{}|~w{~{|}m|s}zyt~{}~|wyz||}~xzy|}uxzyty~}~~}r}y}|wqyuzzvv}~}}yvzsxv{~~z|rf|zvq||xz}vxw~~wzu}ruh~}w}iuxx{|}{|tw}~y}|u|q{x||{{{|w|~|w~s|z~~{~x~|z|{yx}}~xx}}qz|}vpgtt|xr~}||t|dy{|{s{wzyx|v{~~~r~xz{|{}ryy|su{{|}~}z|{}sxuww}}|y}~{|x~|~z}|wq}{yxz{}}|z}zx|q}|y|}~~|zxyzu~zy|kszuruxr}{~|r~xuzw~{}oyw{}~~z{~xz|~|~|zvxt}}{{w~{yty~sy~|w}~x}yx||z}~}|}~tv~{y}}~x~w|~sv~||o}}~ztz||yyzv|xyszz{oz}x~{|z~zy|w{|x{|xwr~{{{{}|zhu}ww}z}~|}}{yxzy~~px}~}u{sv}}p|z{w~zh~|{y{~}zx~|}t}zq~}xz|~~{r}ysxw}ly|ywxu{}|x~wxtx||s~r|}pwv}_x|{}xw{z{u{~z|~xvz}vz}pqvxzsyvz{zuyz}~p||tt~v||{p~zz{~Zsu{~~~h}uq}x{{u~|~m|~{r}w||vjx~oqw}}{ux}l~z{{}{|zzw{ve|m~{{~x~x}||~q|}|~|w~{yy}~x~v~|u}}s}udxz|}~wx{{s|ynyz~uw|}rhq~uiz|yt{ymrv|w~by|~yo~zsmuww~}w|v{~vz{nw{{jx||y|vyy~{x~wxwvxz}z}r{|n~}y}e}urxz}}v{ux|zz}}zz~ztz|~vv{{y~tv{s~~|{}y~~tzx{x{~{w|r~~{z{{}yy}zy|~w~u}r|wv|~}uvzt{zxt|xux~vwzw}~~v~}~}{}z~|z~xz~w{~{~z}{tv~zu~z{}}y|y~{z}}}{lyz}zy{~wx~{t}x|v|~y~z~yz~xzx|zyz{x~{}}}}w~}}~~~zx}{|zy|~|zy|~yzx~s}z|}xs{wsy~xwv|~{~}||zs~zyv|wy}~|xu~y|x|zy}}~zw|xtzwqy}~}}}vs}yx{z~|~t}zv{ywp~x{~upi|z|z|v~{{}v{{x~zu}~{|zk~xy{|}~|~~w~}}y}lvxz}{yz}z~{sy{|}}||{{{|}~sxzzwxw{}|xzulqPtzyvzvyz}szz||{tvszz}xts{v}vxtuwy}zz|z}qzzy}|yzw|zx{}w~zw}e|zp{z{|{qy|{srx}~x{|p{wxv}{{|{tq{wux~{||t~y}tu|y~xzyyjmu}yzs|z~~r~~}yvv~y~{ujr}|w|}|zozvi}sq~{y}zxyvs~|xxyo|vxy{|~~s~{|{}{~z~zw}yltxv|vqT~xwp~~|{zu|x}vxtuu||{~q~~qx}yy~{x{z~~zzr}su|pwzsv}x{|yf{{{}~|}but{w|ymuwvqjzzzyw~ovz}u~~|}yxsyxq~{o{~|}w~m~}~wk|zvyzsz{~xlu|v|x{vxwz}z{y}{~||{vn{z}zsy~|u}|||u{}}|{~y}y{yzmyztn|{guy{}~x{y~wvyx~v|wzxxm~||ny~~}yx~{{oqsyx|r|s}~}~|z}u}}}}zu}t{~|~x}~tv}}y|wy|zwy{u}{}{y]s|{xzN|ts|r}xxur~v~w{z~{||txzzt~x~u}uo~z}~{}|~y|||z}vvu|n|w{lspr}v~~}{{}~{|v}vw}yvz}zwuy}}yw{{kyuytu|uveouzxwyws{j~wwyz~y~|~|zzy}uo|x|{yr{{{~ywtp{||]p|}|xz~}z|{tw}|}~{}q|~z|h~vxozzryerxtxw|u|x}y{|w{w{{|wv{s}~zw}~}|xx~|w}~~y|~|{|}zxzy|xq{|n|z}|zu{{y{~vtw~yz|yy{vtw}~y{}}~t{{{~|xv|wz}~z}syw}vx{s|~}zx|}w}{||~{}}w|{y|z}|x~z~}{{|v|v|}~||yz|u~|}v}xz|~w{yyz}y}wws|~}yx{~~~~||{}xp}z~wy~~xxyyx~~s|v|x|w}xyw~{w~q{{zy|}s|~x~~zwp~x~}zn{xx}|v}||~sxzxtz~|~{~}~|{}z}uq}||~x{y}|v}wvx|}}|}~x}~~y~x~}~wx}v{xr~sy{}~||w|xyt|yxtvzz~r}{{{z|yt~{zyv{|{|hsv{}u}t~xv~r|~v}}wvyy|y~yty{w}|}|{}y}}yz~~p~~}vyds{}x{vq{~w}{}~}wqm~u{|~~{~|x}}~}yw{}{~{~w|v|~u|z~www|}z}o||~xv}~~x|ltyv}s}|~y|{{zz|}~}}|u{yz~y{wxzy~}s}|||y{u~z~{uzz}}|~}}v}~txx~|tyy}|o|~xz{wz}}}yz|}}w~{{s|}~kyw|xvx|uy|rv|}v}z|{zx|}t{~|nq{~~yy|}~}n}um||~w{y|z{s{xsyy~m~r{|zs}kw}cq~|o|}yy~|}sq{~p{pzwrv{{sswv~|vszz}{}{uznyww}~~|{{~{{|}w|~vw}}tt|~|zx|x{}}}|~yxw|~~tu}vx~}zv|~zx{|}}~~{{~y{z~r||}|y~ym{wy|s~~{{}~tz}t}yz|yw}yyssrxztw|x~ztu}~v~xrv||}~sq{|r~}ytz{{|}~w{~|}|z}~yqw{t}}}zr|{~}mwuwx~|~}~~~znyxzz~{x~zspm~t~}vx~w{z|zzzx|~}yt~{zqyvq|}|w~w{uwz|v}||u{|s}zx~}}w{y{}|~~}ycu{z~~zwx{x|~~|~y}~||z|yzxwzwyxvz}{}{y}rzwyz}|ws|}~}|{syzwz|~wnu|z}z~|~~{}y~o~}yw|~}~~|{~~vy{{z|zuxy~wz|{~xz|xyz~}y{~~t}{zru{~}~}~~x|}}y~ws~zlx|yzy|~wz}ys~n~|x{}{}x{elxw~e~yrz~dq|z~zzxyywyzxuz}g{}y}yvsx|{rz|uwtyywk~w|x~z|||yrx}z~}pv~zyy{||{{u}{~}}{z}}q|~|psvy{z~~o~}t~|~x{{t}~vy~|j~}xz~w|~pr}uz~{y~y}y|{{v~||~z~y}~{}|r}}{~|{~t~ty||v{}xr}|||z}zssws{|yy}py~s}x|}}z}~vx|~~zy~z~~{u|z|x{x~|~vzvy{}{~x||~{n}z{zx~w}{yy||x}|}wryvxwyymw{~y~zw|v|z|{o{~~yws}~{|v}z~w~u~ywywzvx|~zxyx{tu{{xv{w{vuyzzyu}{||w|{{w{{~u|~tu{{~}}qrz~|uuv}~z~st~wz|||x}|{|zxsxy}zy~}x}sw}q~}{}q|xx{rx|}ss{~{|{}}znwzy~ts|}}|zz{v{yx~z{{}|}u}|{}|utxwpvq|}xy~uf}{v}{{s}q~rsz}sy{}{ry~y|{kzwzuhvz~|wvwxv}|}~~z{|~}{n{py|xxux~}ww~~vz{{{q~~t{{|}~us~{v|}syzy}~~upv}|{w~doyws~zwyxxz~|vo|tz|x{vxz~{wkz|}x{}x~z~}|~wyyz}||uuv{w||xvw}yyy~ry|zzz{o||}~~s|z|zz~{zz|{~x~~}~{|}~~zw~|~|~~~u~}|]xzwq}{}z~|o{~{r~zw}uwz}{|w{~s~}z{~{}}}}||s}~~~w~~{|t{v~yypzy}~~x|}}|yq~}~p}y|||{y}zzzy}y~{~y|z~y|y{||}}z|sy|y~t|pv~uv|}}k~yy{rww{}}{y}zz}~{}{xz}~xxz{}z}vw~}|}~}}||{|{txzyv}}~}z{zz|~{{xozxt}}}|}~q}}{y|||~t{|~}m{xvvj}|w}}{}u{nkyr{t~x|v~}|z{uyt}{}{v|{yy{{tx~zyn}~|}}}}}zt}{q~so~z~}xyx|x|{|yp}v{}u|ou|zq|{}}~}|{v}|z{n}{}}{y{}~yqzyrz|~}yv}|s{xz~}|z}}}}{xy}xz~yugw|~xu{wy{}yx~yxwxv~~zx{nzss}z{}uyvz{uyw~t|t|~{zw}xy||y}w}wqxs}ryr|xyzv|q}}}|~{|}~{|pxyx}~u|}}rsm~}{}u~vf}~~xu{xy{v{s{}}ys}w~y~xzx~qtz~z~~xzow|vy~|y}x|~{xxzxqx~}}w{~|{~|s{v}y}|{z|yv}~~|t}xr|wty~}plrtx{xz|xv~}~{pn{ws~wlz{y{{|xrwt{w|rvzpu|}vy{zu~yyz{~|z{~uvyy}srs~u|{y|t~xxyzw{l~~{pv{bv}yww|yu~s}|y|{zwo}qv||~|s||{yztyz}urwy|}}~~qyuyz}p{|yzy|{uw}}zvzuz}y}vwmyz~|x|x~|xu}w{|ovzvz|~}s~{|x}vuz~~|k|zmx~|zx{oxrs}xe{yttx{{}y~{{}|}qrLyn|mtv{u~~~|w{w{yt{{ux|z}}w|r|`t~v|yz}u}lws~v}z:yyy~~z|~xw}]xwvy{Q|}z|x}vz{zrwQ~~wz}|x}m|~quw~|z}v|}u}r|{{~w~zv~sqx}}}|}zyv}|}~{x}}zuzy{zxy|xu}n|y|z}|wd~|||{py|x{}z{zvxz{}}x{~t~x{|y~~v}v{}zy}{{{|}{|z~xpzuzwo}~|{{|{x~zs{{w}{x||x{}|zwzu}yx~y|yzm~ux~}yq|{p|~w~z|yv}xy~{~{}}zt|~{~|~zvz}~|{|z{q|z{x{|~|t|y}~{tx}~{~z~|~y|xy|zuv~|y||||}~w~~}|y|~t|vwzw}{yx}yxw|u}x}||}yq~~z{|wou{zzzw{z|w}{ys|{||w~qw~{y{z}|}|v|vo||~{|~~~v}wz{~z~|wzz{}zz{zx}y{w}vtw{y~}|~~}zz|o}xyv{}zy~yu|z{x{~{u}~}|~x|t~}zu{{vp~~ww~z{{z|~}|h~|~|u{|t}ut{{z|hx~}|~wu}~~zs|wzz|yz}zztv}}|}}~}z}|zuy}x{w{{|}w~yy}x~z|}~~}~w}{vzt|yz}{vv|yzyt}|~}~y}r{}||}~~vy~}yxr{x}vy}{z{zy{y~r~y{z{}{yst}~z}{t{}}s|~|zwzy|}}yzw}}wv}tx|vz{uyur~qy~{tr~y}||~~vzo~~z{~}o}x|}}}}uvu{r||~}vzyz|z~}~x}~~zs~}}zxxzy|z|}voxwvz|wxs~zvs{yy}{|{~wqx|}|x|~~v}}v{}{~{m}|ws{wx|}vxxy|~x|~v{{{svn|vu~t}r}}t}t}|ytw}~x~v~}||{|{ztpq{|uqt}m~z{y}wxvzx{{v~|~~~fz}xy|t|vu|w{wt~}wzxn|{~zx{{{|ry{~|~z|u~~n~~i{~zy~y|||zv~y}x~ov{|z}vlr|t~x}{w~yvwxro|xyt~~s|~vuyy~ys|z}~uq|r~~~{ys||{{{~|zz|nw~~x}~~yzywuw{wyp~{z~zw{pz{}xx~~s}~}pw{z}yy}pz}~tv{qyyzW}}y}yy|o}z~wy|y|wuu}qsz}}|r~tv{t~~tsv|z}|w}{~x~zn}y{sxvx|~m~y}u|w~u~}~}{}}}zw~uy}x~|{y{yyz|~|{y|}y|z{}}pw|zv{v}y}}|z~~|{yx~wx{v}}y|wz~xz~wt~~}~wz|}x}zy|}}zz}~~}}~|z~|}~m{|~}z~|z|zz}||m~x~x}|~}v}{|v}~}xx|~~y~z~~z~zw{yz|~wzz~z{~x}|{ys|u{{ux}}~~{~yx}zs{~w{ty{|~|zz{~~}yt}y~vwy|w{~||~y|{yl{~y{y|{u|}}v{~|v~}~}}y~z~|{|zwyy~wzy~zyrxrz|}{y}}xyv{{{}|yy~~}~rz~w~{}|ux{{w|syz{{sv~}}z{x~v~u{yz~{{|~z|{~w|{{xw~}}|yztyvxwl{vzv||rqr{y{}ys{|{w}{||{[}xnv~oxn{|yzvtyzy}}xtpz|xvvywz}|{y~~j{x}}w{xz|yZxy~u}~}q{{~|ztty~z~~wwzuy|x}qr~t~lvy~s{zw}n|v}|z}wta{{z}j{y|}{}w~|xv~s{x}w~tyz~svzu~y}{~y{~}zwy|~xyyw~~`}p}ur~|ukxxzu`~x{y|zxy|}s~|y|ztxys{q~pvw}{~}|zpzwz|}z{z}~{rz{v}zzyt}t|wu~w~z{|||q|z{~}w|vz~~|~||z}rt|}yv~zz}qyo~qwy|z~|{ux{}x~xxvm|zuz}s|}q|rs|suyznwx{x}x}x~wszt~|zy}w||~y}x~sx~xtt}}{{|||xv||y|yu}|~yvv~~vty}}yz|r~zvi~{y}{{{y}~yzxxu{{~os~}~v~}rw|kpytr{}~|szy{zjw~u|x~sz|{~|zzzv{}wx|}~{wxyxuytuxpw{yv}}p}~{z|rx|xz~{w~yz{{~{}{~w{yxx~x}~x}qyp}xw~~p|unyyx}z}zxy|y~~{z{}}w}{z{w~wwzvsoyw~w{~~vuz}ywy|{|w}{~qyy}|rx~{}|}{{~{}~x|xxuv~}l|h}|~~{yz{}~zwpwq|{zg~}{s~~|}z|}|tvou|r|{z|}~|xpz|x~{}uz|v}|}}yzx~y~z|}s|y|v}v|zuzu|v|{}~rzv}}wrv~{|v|wtt|{}t|v{{~{}q{z{{y|v{~z{z}yysy|yzz{|vv||~}y|}~{~|{||{n{|}vyw|}|q}{}w{~q|x|}ywzxv|||t|y{sww{u}|}~y~~x}~{{yz|||yx|y~~~~}u|xtyw{~{v~|xx{{{}~z|tr|{{~{{~yzxwu|}~wvx|~tz}z}z~{pz}{|~s{|zvwx~z||ywz{u~ty}{y|wy{w{}w}z|~zxq{zzl~|ymtxz~u{}v{y}y{z||puq~zv~p~|~|~z{u|{~}}z~|||~}x}|{~zzswu{}|x~w~}y|vws}~yyy}{x}{yz{y|zxuz~zy|}|zy}x}{}x}}~wx{~~z|}wt}|r||n}~{~{t}zv~~y{xuy|~{}|{z{}|p~~|wvz}~}}xxwwy}}}}}|~}{v}~|zxqu~s|w}i~~y|{{{}{}}z|}z{{w}z~r~{z~xp~~t~|}xw{zy~}qsvrvy|}ywz{{~|}yvzvy{}|}|s~}|w}~~sxv~|~{|{}y{{x~p{u{z}z}~{|y|y~{r{}w}{uz~{xzs|~{y~{wz}~vz|z}yzw~x~t|~~z||}|y}|yyx~z|~}{zyy~w}}v|j~vyq{z~~{{}~uwx|{{yl~{{{v{|}wzyz{~rx}~yxz}mzyv|q}w}z{}{y~w{{x|l}}yo~y{zv|{w~sx|~|{y}|pzzuu{~}u|l{q|xw}ypy}z}}y~}}u{zxvww}x~~~y}xxv|~y}zxz~w~{u}xzzy|z}}||{s{zy|~{v}vzs{wyu|y{|wvzw~vy~{zz{ryy|yw}{||{txw|zz{xy{{}yy|v|{y{|~}yzvmxzz||{~w|~x{}zw{vuy|z~z~uyx{zxu~u~{~vovw|xn}{z}zwmwzr{s}|{~~w}~zyxy{~xutz{}~|rytw|{yv}yz~}{}zyzz}|uw{||nyz{yu{y~wxu||}|z~~w{|t~z|~{zw|qw}}y}x~y{uy~z~~y|r|}}~{~x~uy}ytz~v}~z~vw~y{{w{g}xy{}zyvyw|sz|}|uw~m{}~}}zw}~z|yyprzw}}}u~~st~~}}}|u}tw|}{}~|x~{y}vw~~~||}}q{~{yz~~z|ys|q|w}{{zzz{xx}|}|{}uy~}{x~w}}}zw}{vz}yyz{{}u{|zzy}|}}|}zvy~{w~|{}~}{~|p{x~~w{n|{{}}w}{x}wuv|{}q}~}}|uokn}wq|xz}wvx||{~|}wx}}|~q~}y}}x~z~x|~v}z|zz}v|}}|{oy}xzu}{}xuy~}y{|xw}kz||v{{zzl~yzsk{u{||{|}xtszw~x~yu}}~{{{{~}~zxz}x{px~}{{qzx|}}x|{{v}oz~z}~z|}~}|z{v{t~x~z{{}}yt~{z|x|wzw~~v{}~}zz{zzzx~uzs}u{vzw}}z}}}||{yx}yzwv{|}w|g~~|}~~z|r|x}{~}|{~{x~zwu}}|t||}u|wx}{~yz}w|~~|{x~rt~|yuz}vx|~z}~y~x}t}|~|u}t{|~|z||krl|v~}o}}z~|wyz~|~u~|r{|{u~v{y}}sx|vzyr{xuyu}|vzr{w{yu|}tz}z{~|}wv}~|~xtsxx~zww|{}r~||uw|~ozwz|y{~~|xxz|zyyu}}{}|~~wzut||x~~~|{z|tz|{|x{~~ez}q|~o{~yx|y||~s}}}~|~vwux||v~~}|y}{~r}~u~o}|y{z}yzv|{x|{u~{~sv{}~|{vn~v{lywty~{|ww|}t{~{yz{}|}}z|~|m~|y{z{}~x}xut}zx|}}}~{|vwz}|}vz{|k}~{tu~yzsuru~z~zt{{y{{ts|z}vzm|y|y~|~}}~uq}{z}}rzu|w{xtx~zv~}~y{{ywqrxt|{}}}{z{z|z~{y}~wxz}v}tzgy||}~{y~|{{{lu}|~zm||xy~u||~|~{|zx~z}~x{}y}|wt|q}wr~x~x{sxv~~|s~{}|q}{ytv{|~}wt|zx|}}n}{|~x{p|s}{utz}||}}v~~xyz|||w}}uz}|yv|}y~|v}|z}xv|{}w|}~tzw|~z{v|z}|~xx}u}zzyq~yv~{}y~~~|}|zo{yz~s}|~||su~}x~{x}{z{{t|}{w~xtwy|wzwuu||x~|||t{~|}w}w}z|~xt}||{{z}v~|xy~|{z|vx{v~~z}||}{txywyzy~~{{}}xo~|m|wzrw|~~}{zxz~}w{z|~wy{|~|{}wumypuyz|{w{y{sy}~}}zzw~}yv|xqr{w}~}xxzzw{||zz}~|ytwz}~}{y~z}~}{v|l{|x~~w|~w}{{~~yzoz{}|~zz~}~~{q~~w||x{}wz|~xw~~~zv{|v}vyvuz{|yz||uw|x~p~}y}{}ww{~x}ww{}y|{|y|~t|}||y{xvuz|v{}z}|}v}w~ut{zyu{y}{{~}~y}ywuz||xxsy{{||zxy|vur~~{}~{s|~{~}~{r}z{~|xz~{~~}~~||}}w|rzzyv}xx|x}v{~}tyrx}yz}{~~ww}{}v~~}{}w{{|y|}|e|zx}y}zz|vt|zt|yz~v|}{}y~}z~z|y{x}sy{uyz~z~{x}{~{zy~z|yyv}zux~z{wx|zxzy~}}y~q|~{{|zw{yz}||~z}xz}|y}~|~zwr{~~|zzxw~zss|~~{x|{v|}x|z~|~{}s~zu{~|o~zv}sfq{}|tw{y{fvo}xtxx}}o~}{~{slv}{u{z~|x{}tz|~w|~~~y}|oz~v}s~{}~uso{{zyw|zyx|}nxrw~z~}}~t{|x{x{l{syyzp}\}x{jvvwv}v}yuztv~{}~t}wzqt{m}|zy~}z|zothxz~ywy{|}|y~~|txt~z{k~}}szsu}zr~yyyzsvxyvtsxpxx|~y}}qZ}}vnu{i~z{{wvwuow~~ryw|xy{}x~uz}uir}z{t~ly~ur{{{zzy~xy|y|z~xzv|x|vsvzxmbwzxz{{~|x}}}wwzz|~ysz|uwvuv}wv~vyoiz{|oyuxw}y~m}~~~{{zs|zy~{{zuvh}n|yw~t}{{|{y|{z}y|w}~{{{~xzx}x~q}x|}xs~x{x{z|{xzu{}v|yyz{{yyyuwpx|v}zv{u{}z|x|}q{y}||{{|}{s}y|u|}{~y~}~}~zyvs}}}{zx}~u}{zz{{}}r|}z~|z|{~vuy}~{~{{x}y{r|z}x}~~y{v{|v}}|v~zvyv~}z{y~~|ww{||zxk~|hxzxtsx}}~yy{~x~~|}yztww}y{}|uy|zx{~z~~zvuv}~ynzr~{xz~|xrxl~z|u}}v~|{|v{sz{qx|t}~wy}w}}{}~z~u}~{}wy{}zy{zxs|{}w}~~{~kwzsxzz|t|{}}}}|}v{r}}{}}{}|y~|~|z}|y|ysz}w{x{t|i{s}vyy|x{}szyzw}}}y}{{~|{}xtrntwxs}{}z{y}~n|~n{w{v}z|vz}w~zx{|xy{~|{y{xyz{wz|~u}vywi}{{}|}|r}}v~w|s|zv~zu||zzrut{}qzz|xtzx~uvy{}z}|~z~vxuyxz{st}{{~vzqwywvqut~yy~{{|~w~~|}{w}~~|{x|rz~|~}}~yy~~}|w~w~}|kw}y}y{|zw|vz{p}{~|{z{~}x{}zy}xtt}{~}|}}ru~px|{}{xu}}{{|{x|xu{{yy}y}||{~}~|{}v}zu}rp|}|y~{z}~|vy|~~hw|y}z|}{yr|wm~r}v}~r~zwanxnxtuz~|xuuxyv|v~zpexptsz||x~ytx|wztvu{zr~tuwuw}r|{{v~ryytuw|}tzjxz}x|xneox}}tzXmq|mwz}}[tpsx~vu~x|xi|wy}}pznytxxy{x~~fvr~}z|{c}~}{gw}tu{z}wz|inswxuDsu||rLqyh|nzu|}}zvyw|{vw}~{{bwyu~|{kvz}~~~|xw~y}couzsrb}qx}ww~wxw|o{m{{xo~trvv~{v~ysz|tvsgplsuuc{}{|aosztx~{{t{rpzt}|{~uls|wur}}zli{zv~|t|b|ryl|xyz_{t|~y}aw|pqxo}~}|x}wz}zvt|~|||~~x}zyz{ztyw{u~|~xwx~xwz}y~~|{|}{y~zry~{}~v}z|v~|~}|~|~x}{|~}{~zxwuy}}z}~{}ry{zz~~y|~}v~|{}~{x}xw{wyu}~y~~x}~y{y}uw{}||{}zz~w}yu~}|~ss{{{}||||}|~zx}~}{|}||zzy~~w~{{qy}vz~rz|y||~~vy}}~|x{~{{z{~|~t~|tyzz{}|zz|{~~}}wxzv{~yyz~xzq}}wzz|{}}{|}}|{}~~}yz}{v~}x{|y|}z}ryz|~{{}mszx|}||}}|~z{}}yz}~|zx|rzvy~z}~yvu{~{{{v|~y}y}||y~|{|~}}{{w{wz|~w}}{~zy{|}uz|}}}xy{{szzyszk}{yyz{}|ys~}}~uyx{|}}~~~zzvxx{|y~z|z~sv~|z}ym|||z~~v~yw~~||{|zz{}qzqx|}}yxvz{y|xxt||}{ywzx|~}~~yw}x{~pz}~xz|}vs~|{~}~{}~|}{zzz}~~}uz{}t~w}}|{|}zz{~|}{xy{|xw}|}vzxw}w{u|||x|ov~|~~|z|j{|}yx~~wxyyy|v||}|v|uy~~z|}v}v}u{wy|||}}z~w}xz~~}y~zz~~qz|w|~{~oz}{~tpx~}}{|}zuz}g|}|x|zz|zsx{|x~~~wxz}|xt~|y~ty}|}}~{z~}{{}xyz|z|w|}}{y|wz|zy~y}}~||{u~o|vs|x~~uz~z}~|}~}y}ymu|}un}~}{}yzqzzwo~||}n|{}}xuywfzzz~~yzy~y}mv|~yw}|~~{wu}{p|uus{||svv~{~|}~x{~wyvyxvq}s||ux}|{}zyy{v~|z{||ox}vyzz}~zyztto~~|s~}z}|~|~zrzp|~}~w{tx{}~|nu|{|x{{zzv}tz|{{}y{w{{}yy|}}{|yx{q}|~ytow{w|~zz}}{}y|{y}u}u~y|w|zr{|~kv~|u~}|x|zv{rm}tyuy~~uywu|wyz|vl|wxw~~}||{z}x{{y~}|{yy|m{}uz{}zz}x{||x}q~{|~~}|wxu}yysz~{||tz~tt~~{zv{{|}vvrxwv~~s|x~~|t{y~xtxyzvu|z~|}}{wyzf{~w~|zzvyx~qv}||~{x}}vx|}}}y{{}{~v~yyyxy}x}}y}u|}~~w|}}|}qzy~qqrszv||~{{z}sy}~{t{{zr}~~|~{xx}{{}||}{r~{~{vzzvyyv|{q}}z{|z}zvx}~xv{~yv~zy{zx}}||{|sy}x}~yx{~rxw}z{}|~yvwt{z}}o}x}|x{}||~y~~zxsyv~}~}uz}~{yvz~zyz~z}yz~}|}|y~uzz{}z{x||yyw~zxx{~x}~u|}x}{}zw}|~{w{}}w{y}u~xz}{v}}|}|~~z~v}x}|s|yy}zzy~~ry~}zzvzy{w~|pzws}y}~z}wmr{yyl|}z}uyy{}zw|p}s}y~|~wvy~~wzxp}w|yvx}w|z~}{|uy~x~}}z|}w}zuz}|{yslpxw{wsm}}n}||tzzx|{xx~uy}}~v~l{t}{zxm|{w}}|u}ypt}{}y||yw{}|qzyywz}~~~wvuuvtyvxww}|}||vz~~rxvs}~}{}{oz}w|ux~q|znz|}||y||ytxxm~~sx|}vv{yq~|{|v|s~~|yl{rxxtzw}}z|}vx~|}vx{u~zy{}xxv|wlvv~~{p|zwouz}}xuw|ur|r~|u}~{}~|qz{y~zt}y||}y{ttz|zwv~{|{||~uv~w}yxwu}r{z|}zr|}~~|vx|~y{r}~|yt}~}|~yy{sv}z|~~w|y{x{x~}v}||~z{~ry||~zy{|z{~}~|~|zq}{||zvw{r|~y}xu|uzz~y~x|x~}v|y}~{z{}~}x{}}{v{v}}xv{}{z|zzt||wy}{zusw}xx|{~~v{|s|}}{}~zt~~yty~{||v}}y}{}~y~}~vz~wyuw~~wz||{tz|s{zzt{{{}w~{|y~{|zxz~{}~x||}zzv|zyx~yzx|zwx|{|x{~~{qy~}ry{~z~x}|z|y~}y~}}xt~vyyt|s}x~yzv}~~wszwvwz|y~|y}so|ptv}wzt|yz}s}ztz|yw}z|ww}wzj{~{u~r}vu}z|v~wxw|qz}{~vz~|}}sj{}z{y~qw~tt|v~y~{yyv{||u~{~~yx{yz~u~~~y~~{y}~t~}{yp|y{r}y~{{|rwwu|}~z}z~x}{}||y{j~}}z}{ztv~|~zxw|xvzxzzzzx|y|{}}xyz|s}y|}~y{e{{{skuz|t~z{y{vs|zvxx}swy~{}{~~||{y}y{}}wz}q{~vy}r~~~~|}|wkyw}{^~}|~y|q}|||tz~~oqz}urwv|zvuyz|{v}y}q{v|yuy|u~y~~{~}uzoy{ovzzzx|s}}~a{xy{z~z|~n{z~|u~xzy~w|p{u|{zp~trj|zxv{{~w{}|u|}x~~~y}||{~~|w~~z~{|{tjz~xw{u|{z}tzx{|}|ys}~nixxt}yr|~y{{wv}}}{yy|{~z{yznv{{y}}s|{uq{~wu}}xu~qyxxz}{z|{{s~w|{v{{zz{}{~~}|wst}{y}}}}y{xz|}z|}q{~t{||}zyz{|}x~||x}v~t}{v~{z{u}zzzu}{y{y{{wzwz~|yz|}zz|x|x{}{~|~}~}w}yz~|~wz{~ux}~{}ozy~nt||yr}~|~zswzw{u|}{xyz|x{v~~y}}{{{y}s}z{{x~}t|~yww|l||~|xywx~u|{{|rw}|w~z{xz}vu}l{~z}{ywvyxz~{y|x}x}}}|{{uz~os}v}|{tu{swxqyzy}z{vy~zvn}ywr~{jyqzvyywwyyu|z{}|xyw|z~xz|~}zz~wt~w{}|y|u{u~z}r}{t{~{{{vz{|rzz{{|q{vzt~|z}}y}}}}~zxy~}|tx~x~zwzx~qx|ys}zx~pv|szk~z~~v~}|su~|s}t|zt|}z|p~{s}zvu}twyyzx~}tzw~{||}zyyqvz|xzy~{wxw~z~zfwuqz~sy}{{|{xz~~p|~}us}~|xst~}sz~zl|y{k}y}xxoyvxx{}y}{wv~}~yzz~|t~ynzi||{~w~n|xz}~r|}}t}w}|}y|~|w~syt{{~~}y~{zrz}}{~z~|}~{z}{~|}~{}{}z|w~wqyuyy||y||s~{~{{}}|{~{xzyy|y|psz}{~{{}~{u|x}}x{yy{w||~}x}~|~zz~zw~~{y|ytx~}|}||}zwy~}|u{z~|~|{zw}w~zxz{{}|wzvu}~y||z}u~{rx{vzu|tx||{~~}||{~~|}~{xy}wz{~}|yy|}~~y~~{wux}}u}||}~z}z|{}|}us}zwy}|}~y{}~|~~~z|rs{vvty{z~wx{|~~|z|~|}uy{~z|ytz~x~}y~~w{|~}{||yz{~y}}w~}}s~}|w}z~t{}}|||xuj||}xr|{{~du{|{z~x}~o~}|~q~z|x}yy{y{}xxzxwq|n{}|}~yhw||{zx}{}||}{}}tvpuvr|z~xz~z{}|{}w}z}}|~~|u}w|psz{}||rp}~wt|{zz}~yz~uyx~|}|u~|~{|~zv|t~~~|~~xx|twz}yvzyw{vt~{y{x{yqxw}}v~~}z~u{l}}}x}zytv||}{|w}w~|}|~mu|t~}x|z{~~}w|x~yxz{}z}}zz}|~}zz}~pqu|w|s|}r|~z{z{wz}z|rr~u|w|y||~|y}}zp~||xz}x|{rxw|{y|}~v}|~z|y}~vqwo~{~{{y{}xp}z{|y}|{{{z{|s}wrux{}w}{~{{xt~v{|zyv{~z|x{|zlty}xyr}x{x|{}|||wz{y}wzv}r|v{|{y|uz{x{xvxxx{}wyvtywuzxx}s}{~w{vx|z|{}|~y}xyz}z|syw|u~}wzz|z}||x}v}~~{uyzy|}u|xyyxwzv|{}yz~zv{xz|~zwzty}{zpzp}{~k}|}|u{~}yw{sw{|z}wvuw}w}z}||{s}~{xxy~yxiy{x~}y}z~{~~x{|z~~~y|z|~~}}y}}uvyn}{{s|}|te~zt{{|}|x}}{}~z~|}z}wx||{~x}zc~|y}wz}rywuwy~xx~|}{{~|zzx~}yz~u~{tow}|~~xs{|zt|yxzv|xx}{v~~}}}~}{~{{{|{v~zz}}xwtx~}z{rtq{z}x}~wu|{|w}v{||}~|y~y~{~~ru|t{~z~~tx{z~yxz{zy~y|z|~{w|{zz||||wt}yqt~x~vyxtx~~z{~xzvx|zzzx|zp}uz|~|~zzzxvwy~~|}t}zx~{||qzys~}zz}|}{~|q}|~~~{~{~~{~yzu~{|x{t}~u{|zr{~~|x|p|x~~u{z}|~||~|t~~|w~~{xv|w|}r~zy|}xyx~}|r|}|zz}}vuxz|}u}}{}~~|xx~}y}w~{txy{{z{||xsz|yz}|{{{|~ztz|zzzzj|~wyz}xyx|~y~o~}y~~r~y{{~zz~}y|~}~uv{y}ywxzy{x}~}{||w}~zyz{}{|w}y}|vw~}{|}||t}|{~}oz}~zq}|zxu{~{u}}yx}{|}yz~y|zz~}{z{v|wwzwsv}w{x{{{}z}y~yuz}}{{tt|}~|z{v}|}s{~zv|}}w~~~}vy}}}vv{wyz{{}{{yry|}{zv}yv|zzz}x~ur{yv{|w}yt}~{{{~zx{~~z|~~~y~yvy|ux~{{z~zzww|oluyzwx~}~}|w{xuv~y~|}|xz|}{~y~wt}ux}~t|~{{y~||wyzrzwz}wz}~~uvtzxzw~w|z}~~|{}t|~{xuzt~{{|}x|v|~{y{xyuy|{{|}|x|zyzz{kzo{z{|urwq}{{|{yxy}~{yz}{|v}y{u~}~wy{~}}z~x~yq|~vzwzyzz~q}}}sx~~||}~~|z|~vvrwvz~~}z}l{{y~t|rv|{}yzx{|y~n|x}|xy}z}|~{|~zyn|z{x|xwv~pz}}{~}yx~xyzvpw{|{~w|tz~~|r}}y|vwyxz~w|}{~~~zs{wqvt}qzx}~~|}v|o|su~{y~w|yn|}v}|wqrty|zy~|~y~|y}}|{{{}{y}~y{|{~||x}~y~ov~}z{ytpx}u~~w|}bo}zuz|}zy}~|~|||x}|{xx{}|zw|}{|s|~||w||uwy~{z~ty}}~ww|w|z}{}|y|zzvy||nx~|zor~~~{s{yu~~}~ur|c~}}`u{{~}zzu|||u{~~{~x{x~|zpw{iw||v}szy|w~rk|ez|zz{|}zuo}}p~i}}}w}~}{w{{ux}|wx~w{x}}y}~~y{}s~z}|ywis~z{ql{}y|~~v{}s|t{~z}z}u|~w}y{|xz~v~{~sx{~|}~zu{}z~|iz}}}y~vz}}{}{~zwzty}xxx~|~}vx~wv{xz|x}v|||z|}v~}w|z~z}y{yxzzy{t|~zxr~t{|zdw|~|z}z|{w{w|}z~t}z{y||{yv{}~yy{zp||{~zviiy~}}yw|vs|||zw{z~|}v|ztvw{xvrxovu}{{|x{{sy|~|znyyt{zxy{{|w|}nzm}|}s}}y{}zs{x|~n|u{yvxz}y}}{|}|{|z~~uz{xxzz}|xyzyznz}w}y{|{v|sz|{|~}}x{}v~uw~|}{|}~u}su}rvx}}t}y{{{z~}uxw{zz}}z~~|z{xq||{xv~~~|wv}}t}|{{y||{{yzv{}~|}{|}}z}|}}wn}y}}|r~|{{{}zy|y|v}||z}w{p}sfxzy}y{n{~xq{{v{{~~~}v{xy}}~w{y|}~}|y~|y~wzv}{{~~v~}y|{{~uzu}k}|}zy}|{x|zx~w||{}u~|w}{}}wyv~{~~~|{x~v|y~vz|yu}~z|utuxv|yvx|~szzw~||x~yw~e}x}u~|z{{|~v~}|z||s~xsr}o}|||~xt}~wu~~xzi}}w||~|}v|~~uw||g}~zw~y|wxs}h{|z||}{|y|v}tz~y~~y{x~x{y~~z|s~||zz}~}{}l{z|zl~z}}{||}q}~rv|xtx{y{~uxy}wzr}yz}{~yu}w}|v{vy~~uz{}|y~~{|x~|{{~xx|u|~|{tz|}w{zz}{~}}}}|yx|~y{}{~|wx{wv~}z}~iwxzz~x~yy~y{zoy}{{|w}}}}~|{{x}{}x{t{t{u}u}y|ry{u}~{~~xxsrk}qy|tz|~}~{{}{zw~ozz{}~|}not~q}~t~rz{}xw}~~}~y{}u~{}~vgw}y}|qzzy}y||}syvv|rw|}}s|{{{}z~|y~yp|}w~{zt}w|yty~x~{{|x{}xu~|{y~}}~{w|n~z|{~{}wq}}~z~v{}}{t|{x|}{w}y~|u}~{yw}}|~~z}}z}~}}~|z{t{{gww}|~w~||y|{y{zk|z|wyvyx}}yy~{|o~|{~|~ty}~~~h~|~|p||w|{|y{~mx{}{|~{v||~}~wvz}y~zy{|zu{yu|}}||}}}}}~y~~~tws|x|k|~x|}ew~{oyyyuy~zy||{{~~{z|t|{w~w~m}u~}}z}}{{}y|xw{}~~|||~uy}|}}||~}v{x|v{w|v{{|}}v{wwz~y|}{zy{~{|~y}qz}{v~zz|t~{|}~x|~}toyv{w{z{|{|zy~sz{v}{z|xo{|{y}|~y~{~}}~|}|~{z|}y{||~{l}x}wx{~|w}u}s||}~||q}~szsyz~y{zzv||}y|zuy|wqx|z{~xmyx{{~x~v|~}|vx|~}~syzzz~yuz|w{}w}th|}xx}n~{~~oxy{y}~vv|z{||n|z}r|u}w|~r|{~}~~}k{xv}yx~}z~x{zz~}u}~v|}r|~}wz}z||x}{xr~z~yz~zm|}z~}|~{}~}|zv{{z{{}{}}x{{~x}xwyyv~z}r}{svxzzy~zux|r}|z{ux|y{|~|~s{vy}~yy}}}xz{~{~|y{yy~}t}y{vwxx||y}~{|v}s}t}xzz{~uy}s~x|yw~y~~u{|s{{yv|x~{v|{}z}~|~x}||{wz~yz|}uxz|}m{}{}wz|y|{uxu~yzxu{|~~|q|ow}w|x{{w|}{{|{uyzwx{{}}~w{r|z{xy{|~{||}yxzx}z~z|~|z}{~~vrxz|}z}v|}{}{r}w~y~}t||q}|v}}}u||~}}x~yzz|y}z~pvw}~{|w}xynmy|y{~{s|ry~x{}~~}|{|yv~||t|{vywx}~|xz}{t}|r{tw{~w|{{|x|yrwy~~}}yv|yxm}{vz{x{xz}{|y||xqz|}y~xyzvzy}wz{y|y}xz{z{{mw|||}w}|y~{xy{~}{|w|~||vzy|~~}z|oz|{w~x}~}}}|~yt{~|y}vzxo|vq{|~{uyx~yzxvx}u}yv~{}~{zyy}{}wx|z}|uyz~}~||q{}zvxx}yzzsqy}qt}}}~}|yusz}{~|{{y{z~{|~}wx{zzzu{}yv|x}||~zwjzzq}y~|{y|~x~~}~w}q~y}|~{w}{~{{y||{}|x~zx|z|z}zw~~{|~~}zry}z~w~{|{{{}||{y{xz|~uw~~z~}|y~u~tyzq|yyy|{w~~zxxt|~k|{|}|~y{}tw|x~w{zxz{{z}z~}|~vy}tztyz~wn}{}~x{{}~z}}}wyzuv~|zz|uv}w}}wt~p~}{z{~x|{}zq{}z}y~j{|}|otyt|y|y~{|}}vu{|q}w{w{{z|~}{wyuz}uy}~zzl~|~~x}w}z~|{{~{swzosxz~}zx{{zzu{~|zyy{y{t{|{}}z}}s||qzzz|{zw|ryu~{{}u~x|v|yy|zvvvy}z}yvu|wsz}yv|u~uz~}}{wv{}s~|{}xzv{}{v{}{|vz}|}n{zv|~xy|x~t}~}~{~~vt~ww~~wyxy{f}xyzw|y{z}}~}uz~s{yyzwtzt|wy~zwvvy{z~~zu~yxq|~}}zus}p}u~vxtys|}|z|zyzz~vvs|}o~y}xzz}w~w|x{y}x{{{z|~{}z~t~{x~v}}|wtzyz~}x~}x{}zwz}~zv||zqs~||w}w}{zywphx}~wt{w}y}zu{|y}~v}}}}{u{wdxv|{|z~zvz}|zzowo~z~~|y}|z{x|}u~|zt{x}}x{v}~|{vwz}vt~z}}~s{}v}v~|x~w~o}{||}}}~|}z}wzv|h}k|z{s{||}yx}{||tm|x{z~~}}~o|{z}y~z|||~{~{}y~zrv{~qy~y{|y{{}|z}|ytzx{y}n|~y{ys}qy{}q{x~yuzzys~}zz|xo|}x|~q}xx}z{|t~|k~ywu~z}}z|~sypx{~|ux|{pyr{}|sz~|}}|ruvopxgxy}}{zy}u~r_}yy|w{w}vzi}|}}u|~w}rtvwpy{|uzozx{}~qw~~sz}~|~y}}zyt}z{tyy||t{{}~~}z|wz~xp{{yzxz}z}w{zy~x{z~nzx|~|vzq|{wx}v}}w|~y~|{szry|xu~~x{~x{~|o}}||{}z|{upqqvy}~~l{~y{vt~tvy{{~z}x|{|~q}z{~wvtu~}}}yy|{}zx}~z{{zzt{rtx|y}}|x~}{{x~~y~~~z|}|{|rzyz|p|}krz}~~|z~}}w||vyrx}y}~uyxw{~}zyyzx~}~~xp{x|z{ly}ztvzzz{{}y{~xz}vwy~lxy|}}~~~z}}yr~yu{{qt~uyxz{}zw{mv{|{}u~~w}u{}s|~|px}x{nxu{z|r}{{xy{r~zw}z~s~~{~{{|yown~z|x{|}{}gzp~xv}zpzqu}x}x{n~|n|~vw{yv}w~u|x~t|w|x||xj~wux~}{zs~{}|n|vq~~z|{}|p}{x|~v}}{}t}}v}w}}~v{y{}wy~yxm~~u|~w{rwqszzs}vgz|}q{|uyw|ums|w~~}v{{u~xtizu|ywu~{ovu}xv{~~qzq{p~|y~~szzwy}zvxsvz|||{|r}z|~|}}||rxuvzzpv~}wzd{t{txutuv{y{wy}{}rtpkxv~~~w}{}}|~y~~tz~{|yu~~tuywsy~vu|wzzr~}|z}ruwtz|r~{~~}|w~~z}|yyx|q}y~|vsy|yw{y{y}}~~|~x~~y}{w|~~z~~ssx{rzs~v{z|~zy~~xyyv~~vw~{w`w|v}zzv~z{w{{z}sz|u{u}{yz{|{wy~|~|~}}z}x{x}z}t{|}{~|z|{{st{w|{y~}}vz{p||z}u{zwyv|}|~yzz~}x|{xu{rzy|}{~}~{qx{}v~x|qz}~y~}~zy}{}ww{y{x~xuw~{~|z~y|{|~y{yw}|z~||y{|p~||{v{ruv~sx~z~tzy{}t{}zuq{y~|{|}}yy|{~xyzzz{}}w||~vps}}zyr}{~{{y}}}{wyygyz~m~r|||wzt}z{yy~||wyxzyxz}x~oz}~{}{{u}|wp~~~e}~}w}|y~}y{l|z~~y{~{{v~~}~yzws}wv{mty|s|ru~{x{~|y|s}|x}{|s~|}}wzz~|~}y}p{~}wzz~}w|~y}|{y~~~|}}}}v|~}z~wxyz{~}{t}||z}jsw{{}z{~u{~{x|zy|yz~{x{z{lz~yw|u|~us}{~w{~~|rx|zzw~t|~~{ss{zx|}u~{}|{|{{}y{z}}}pyz{|~{~{|dww~yxy|x|w}zm{wsysw}qq|{r~uzwzys|z|}~|xsy|~w~yzo~w~|ty{~z}~~||zlx}xx~t}}|}xms}y}~tyxp|d{{v{v|~}~~zvy{{xx}y|o|tyszv~zzz|}~|}{zy{w{x|qzzy~xzyw}yx{w|x}ty}z|tzys}z{z~v}~|{~|}}zx|~~|ywvzz}~rv~}}yyty~n{~|x~|x|zv}~ux}s}~||v|z|{y~z{~|}~w{wvztxz}pz}}~wx{}xt|~v||}~xw~z|}{x~|{x}vxz{y~y{zw}y||wt|y}}}xo~vsv}x|yv}y{~z|wzy{}zyz{w{}wt~x|~xrv}{}}z|}|n|{z~}rzyxv|}m}yzy{y}qyx~uyyz|tsvy~s}|}|}~}x{|zzx|z~n}}z{x~|{|uz{p|}z~{~||y|}yyt|q}~{~vztxyy{xo{xwt}wxzx|~y~{~~z}|suyuy{u||}y}}yx|}wy|}vxv}|}v|{zyx}{tx}{x}|}ul}|z|o}z~~~{w}u{}{~y}{|}yy~zvv{zztv}||x{{~x}~s~z|wx~wu~}}z}{|~}}z}||{yyyy{~~~zw}|wz{|~~{x}~|{}{qy}{x{|wxtu}yu}|v~}x|x}}~~vv{zzu}{}y{|mz}xz}{{xv}yz~|~{ut{xzys~xwyxp{||{z}x|w}x{}|v}|}{v~||}}{{{wzn|x||x}{|{ux~uv{twzx{|~v|}~z|{|~{}{~u{{xzov{}zyz|{{~}yzzy}mw{~w}z|zrx{|}{ws~}|zpw{yy{u}}r||wzv}~xy|v}|}y~~q{~x}}}zyz}w}~x|{zyzz~wx{{|zyxq{~~~vyz|y|wzk|xx}}|z{vw~|z|ykv|zyz|t}x~{y|w|zu}}|~}x}}{~~u{|r|z{x{}z{|w}~y~|{|w~q~|{yvy}{{qu{}~{~c~}|tz}}v|}y||{}y}z~yu{~|wws|b|v}v~x||xx{qwxtu}|}~|xy|}||{{y}z~{t{}{y}}zyuyzzmz}||x||{z~uy||{tx~~}{~~z}}}x||z|r|tx|{zy~~yx}|xxzz}~v~qzzx}ujz~vs|}|tv}wvz{|zyv{v}x{{xzzpv{{f}n|w{z~xyx~z|x|~vz~}~x}~{pwp~}v~{|{y}xxpuyyz}|z|{|u|q}{v}yt|yuv}|zvzy{|z}||l{xwyz|}|g|t}~~|yy|u~nu}{vy|ix{|zyvtyx~~yvzxzyxw~t{{{xy~~{hw~}w~|xp{}xp}~xy|pty}y{wqiv||yy~~r|nuz~{wkuxvwr|v|{x|y|}yv~|}nzxty{{yny{~{~||x}x{|~nyzzw}|w{}u~~wy|swx|}wybpxz~c~t|zsv~|w||{z~{v||xav}zy{|trvw|wszu}~}~}z~twru~zp{}}ytp{o}vv}z|xym~szwy~{y|zuyw{}yxszxyzyy{zv{}t||y}}}~yx{~||{~y|wx~|z|y}uyw|r~y|{|{~urzx{zw~|{yzx}~t~~y~{{~|yvv~y{~y|}w}zxxu~~rv~~|x}uw}}w{y~vy|~}|}yv|~xz|}~vwzw~}u{}~w{~s{{yz}xt~{nt|{p}[}}~|~x|~~zxr}y}rz|qzz{~|{zsyww}}{zv}yyxzuu|||u~{yz}{}~||y~|t~|}x||~t{||{{xj}~zw}y{v{tt{~}v}w|zq}sxz|}{|z|syz}z|zy{}~{{~y|xy{xz|{~{zwt~{x|z{~v~}|}|}y{wxx{{}}w{z}{~|{|yuq{|~|xw~}}~xpyywxzywx||{yy~v{}|y}z{y}~xs{}}{~~t{vzy~vxy|zvx|~r|{}z}~wy}|j|{~|{~x}}{x{zyz~|nuz}zy{|{~w{x|t}z~x}w~|xy{|ry~}~u{||~{~|~xxz|yvwz|}{vz|y}}x{z{{}|{|yx~{{zyxy{~{u~|{|~~|~}t~}sz}v}w{~vv~sw|zzxz|~yx{}|z|yo~vz}}q}}~z}{~rnv|~pxwzsq}y~}t~|{z{z}~{sz{wsuiy~~w~}}{{qu}~uxqzzt{|~{~}zlv}{}{v~x}|||}}}~x|{y|k{z}kz|s|{u~ky|gvnv~|wmy|wt~su|s~{{}suv{}|x|~{t||{}}y~pw}wwuz{u~{j}}ww|m{{x~~|q{szz~u{ywz||ztx~|~}}{vsxzs}{v|uz|||n|zl|wwv}{t}nzwy~~yz~vwyz}{|~mo}~z|zw~~}w~xyx|||yxtmy{t}yqyxx}yr{}||zyz~vuw~}wz|}|}u}wow|uq{z}z{}t~wy{uw|}syuxr|~z|ux~r{||}}~p~s~y}swy}~v{|}~{t|rx{}~n||w{y|v|{x}~x}z}z}x~~|z~x{~{xxuww~~zt|v}x|zrzxpuuz}y}yw~}svyrysyx}w{~{}sz}~v~~x~x}~{j}x{z{tzpw~v~js}|z}tv}~}^q|xxvp|rys~y}jyyv{|{{x~}~x|~w}t|x~t|un]yz~x}x}wyrzuv}k{\{pz}y|ss|uz|{x|lt|}w~~|}t{{r~w{yx|}ts}^ww{}|~~wy|zxv}wk~{r}x~{~}|h{|y}|{mzyvzr~iv~~tzb}zw}rw~|v}vy~{o|}{{~|xtx{ytz{yz{tzy}pzzy}xvz~~w|||}wnxkz[}~}y{v}gxz~py|||{}}}v|y}w|}}{{y}zzx{|wr}q}{yy~z|q}~z~z~}|xv|z}|x~z}}|}z}y{xw}{{|{|}~y~|v~wt~}}w}~wyzy}{|}~|}|{}}{x}~}|}|z~zzv|||{~||w~s|{y|ywr|z}~vzr{z~}~~u|~|z~{}x|}|w|w}~vws~}z{}y~~~x{{{|r}oytvt|~y}~y{}|y{|z{|v|||~x{|yzx}|xw}y|~vx~txw}zp{|~zrr}}zyvwu~xyw~{}w|~x}|~v|{}~u~wzz}{}q}|{}||u}{yu~rw{{~}vy~vw|gyuz|uqw|m~x{wp|tmzvywx}}qtyvz|xzy|~~~k~wv{}T}u}rzzpz{x~tzxxw|zwszxxxxzx|u~z}wzxtz}r{xwxtvw~}}tws~xr}t}zzy~pyvyz{}ows~zz}yx}}wyvmzx}~u{}{vz{zxxuyqyx{}~w~xu|{~zwyzx~~}lws~~|z{|z{xw}~uzw{prz{|~~wszz}|}|}|{rjzzxs~|v}~w}u}w}sszr|z~pv{ivww{zx}|wwwx{|n}}uss|z}~}wwutxzlz{|}mp{{m||nyvu{ry|}wx{u}|y{|~y}uzz~~}wzs}~{|{{}|}y{{ztz~q~xy~{}v~|vzyv~z}z~{{|{y{z{||gsw~~j{}|~~}z|}}m~y}}nz{}|x{u~z~}{~}~~x||}}x~|||y|u{zx|}}~z~}}z~~~~p}}y}~z|}{}{|yz~wys|||}}}~|yz}|szwx~xy}y~vu~zp{tw{v}}~~}|}s|z|{~x|{vxwz}}t~||}yy~{ysyz~~~x|{u|yu~s|~}|u}s}|{~}||z~}}{w~{~}u}}|~~}{yn~u{y|zyvx|~{yuu~}|s}r}~x|yy}z~}||qz||z{uw~}|vynyp{}|~{}}pyzu|g~~wnz||y}}y{x|q~su~v|y|yzuzxo~|~uqy|}w|vxzvzkx|mtsuqxvw}}}x}}~z~zt~}~{lpw~}wz|~zwytyyrxjvyys{v~}s~|zyzv}ysqyz{tz~}x~s{|z{u|xy~}|yz}~xr~zy}x~~uv|xw}gzuq}|x|}ky|v~w}}{{}yqy}xpwzyzv|rxsgyx{w|qw}{hyyt{}ry|{z{syws}wt|{|{r|sopv||wz|tu{x|xzy{wxzzyxzwyz{}w}wjz}r{~uxv{{y}tz|y~wrr}{}t|tuxx{pl{qt|oo}s{ny{{wjz|z~pttuoxyqwrywe|skz|{{w~}}~|zu|~x}{}|y|~{xsz}vwa~x~y{|fx|}wwvy_wx}yy}v{y|vwyuwr~xx}zry~oxxuzw{z{}y}xq{wm~nyq~~ryy~~qpyot}~~x|yvuzz{vq}zw}~vw~ywz{|wyx{||{ktvx~lgnwyzyzy{hvww}ywwru|vyzryqrtt{~y~{ty}z~~|{||yqywx~l}vyr~t}vzt}{x}wzvy}ytywZ}rw~uzw~`{z{{zxvx{{~~~w{zzxmzzx}~}wzjz{}k{d{w||m~zugs~|x|{|x{}}~}v~ujyy{yr~xzxy~ks|y|}xxz}xv{xt||v}rx~zz{{yzy{z}|b|~~|xz{qpq|{{|xuvz|~}rvvxxzp{y}{~{iuss|{tuyy|||x~u~x~}~qlw{{{|x~t|}}~{~nz{vgc}|p~~u}{zxz}|u~~xzzvp|{}r~xz|pzuy}zqvv~~yxx}|x}yzx~r|oyxy}||{}w}~jw}|{{xxy|}t{{y{}~w{z{~~{}|t{w{txx~y~w{{z}{v|uv~||u|uzu}yoyx|rxyy{{z~|}z{y~{k|v}x{wz{|yvxyq{r}w{}{r~uvzx{xz||}xuh|K~zz~m}vzX|uz}xz|~|r|rozpxwy{y}p{}xt~{|~sy}zv~}xru|||~vs~y~s~zqrw}}urx~vx|wx}~{{~ku{~zmw~s|}}{y~}{{w{r~u|{ql~{yxz|qzs?|~}|~|ruzz|x{{{rx~w{{y|~|\yx}sx||wwz|rzx~~xz~s~|uzx|sw|_n|u|e{{yn}}p{~}||q{{z~{y}{{vz{{xrn}w~z|v{yqw{x|~}{}czzxxzzv~wzz}x|~|yxw|{xx}l{~{|ge~yw{qv||zzxyq{x}{n{~~x{~}z~xy}q}w|uys}n|wz}|y|t~vyy}r|xn{wx}|z}x{s~|~|{}|~z}xz|zy}ry~kx~|x|xyw~|Zu{~t~w{~}}{~|ny|~y|{m{zr}h~{~ytyznuy{t|w|}m{|yyyW~v|i{|uy}zzvt{}|~|oz{{~vtw|{}|~tzw|n~}x{{~}s|ux}{}}vxwrz~|t}}tzv|yyx}y}umvtywytzx~m{|~||}u{{~{zqs}|x{~x{w|xr{{zv|}o{|~{y|wz|||}q~t}z}|xww}s}~{~~vx~~{}{||~zz~{xv{|~|}zz|{u~~{uqv{~~y{~{yuxz}wv|~x}|{~t{{ysy||pvxy~x}`{^~y}q|{|{|}p|y|v{xtt}~y}~~{txz|y~~xx}~}|xut|}ryx{}zx~{r{q{~u{z{~}x{}rw|y}|{xtsp~|~{x{~zw~{~}i~rz|z{q}}~wyfzwy}~y}w}z~|z}wn|vzz|{{w|}|}}rw}~x~t~|~y|vx~|{yv|~vy}xx}~{||}|y}v~|{x}j}z{}u}u{y|r~ty{x~xyzyw|v}||uyzqywyyvsyx}yw}{{|zv}~k~}}~z}us{}ywu{zw{~y|zuvw|{yzz{wz||kuy}w~x|||{}}v{y}u{}|}vz}sxuuz{y}}~{xss{}}xxzq}{||wu~tv{pzy{ux~~yxhn{z~}v~|w||}}~y}~oypw|n}~x}u~||v|{}}}u|{y~z{sy{~}z~ew}u{{{~tz}y~uz|z}}~x{xp{zy|}{n|tx{x|~}|||~{~|rq{}trtvzztqvzx{yy~t~}}~twxy|q~~~}~|wx}|nzz|z~{}|}yw~v{vz~{}}y{xyw}{}{q||}x~|~{y}wu~z~}zvz{z}}uy}|ju}}}z}}~rsx~|xz~{|}}~yy~|}xz{~y|p~~z|y}}y}zz}x~}}}{}}~~||vzwx~}}~wvz{z}xv~{}}|u|r|}|z~}z~y|{t~~v{wy~z|~~~y{|}|}x~t~}yzzr{z~{||}xy{{s}xwyz~{t}{|w|yq}yy}|~z{|zqw||}y}|~~||{w~}{{||{v||~}~}}|~}z|xw~{~}wyt~vdxv}xx}vz{}~wy}{}~}~||}v}wqxy|s|~wz}}|z~|~|{x}}{~u~{{{|{x|x}{uw|}|t|{{~qzyszz}p{~z|}~y|~|w}x{~z|w~|x~{|r{|vyxxz~|tr~|~~|w|yywr}}~~q{x~{{y}{z}t~}||}x~{}z~}qhzkxy~|}~wu|m|{}vy~~tz||x~|}y~yynt|y}z|q~|v~w|zt}}}~|}yvtwz{|x~}uwt{z~}~~}{}z}}{n||x|}~}~{}x|}|yuy|y}q{{|{|{}{zv|t}zr}}~~~{~zxxy~{}vszwu}~|}uv}~|~{}{xv{y|||v{~}}|x{z{}zu|v{x{|s~|y~~{z|uw|r~|||tn||}z~y{yvrxzvz~}}t}y|{t|}wzt{~u|{yxxztw|v{~}zz~{z|w|vz}|o{zyvz}|zwy|~|{}}uvs{w{r{v|}w}z|{}||v||u~t~|yz|}{vvy|~}p{~xz||}uzs||}{zz|yu|{w}ymz}}}|xy}}r{y|{zyzn}|ov}|~|yr|yyxy}}z~|~}y|uu}rw~~zzzw~vy{~~~|xy}yzzytz}vyu{}~y|}}p~z|||}x}v~|x}z}xwz~t}w{}~~}~}x|||s~{}s~uwnz|||swtv|yx}z|~|{{|{|}|~~nw|p|uxzvqv|s{}tx}y~uw|~{{~|}vt~xus{xz{||z{}|{~~ly|}ry|{}~{~{~{|{||}{~|z}w~}~xy{~y}z~|vuz|z|u{{|}|~}{ypv|o~u{vw|}}{yz}yv}~x{w~yz~|}}|~w|}|yw{w{~~{~u~zy|s}zz|{|qy{{y||s{wz~~{s}zpw|{}{x~yxxwz}{t|zyyy{|~{|{|}xxxxz}y|}}||~z~tv|zv|{`uw}{~~|v{vzvr|z|||}}}{t~|u{yvw~{z|uy}}vzw{y|t{zv~}~~{|xh|~xxvvz|u}{z{~|{{z|{v|q}{yz}t}{}{||z|n}v}~yrzss~}q}{~y}~s|||q|z{t|}}y~||~tu|xz|wxz~~txyyyw||zxx|t~{tyx~q{{|}}z}yz}x{|rz{z~or~|{}v~y}}vw{{y~~}zzp}|zsxp}}}pz|xw|qxk~uu|}{yz~~sz|}yzz{js~{y|z{u}vzqxxzz{v}k~zz{zz}|{{yzu}zt}z|}yy{y}v~x{zu~x|z{~z||yy~~~}|xw|x~|~y}mw~{|t~}s~zx|y{~|z{|zx}uyx~}|~ul}uy}z{yy~~y|z}|yuzz{v{su}{i{}||w}sy~zv~vxw~{y~|u~{r|}{~oty}yyw}}x{|{~}uuxxx{{zy}~}||z|z}|~}x|o~~{vtz|}rym{{z|yvutuy~yz{{{et~~o||xwrwzzp}y{yxx|~{}|}zqsyy~}xu{zqv{y~v~}}s~yv{z}t~}w}{ntv}|yy}~{yyy|}{x~y||t{{|{{{||~{qmwsr}w}z|uyt|{zy|}~}t{wx}}}z}w|vt}~w{|z}{tu|~z|vyv~|{}}|zyx}v~}{~z||w~}}vrvu|{|y~yzzz}}}}nv~|z|||x~tuu}~{{y~zvy|~~|xs{~{|}}}~uu{~}q|z~|{~}{|z~y~xv{wwzy{t~|~vy~}~{}}ywv~{~~zwx{w}rt~p~s|~t|xu~{w{~yw|y{x}}w}|~~yy{w|suuw~|{xzy}||q}|}y}}}uxxs|yvz|}ys}xxw}tszz|y}r}yxy}~|ot~wzwx}~twzy{~u~|vux~p}x|yx}t{~~|}|zzxv~w{~~||qx}t~|vyxt~w{}yw~p}xwxy~yu{zy{}xpxv~}|~q~|yz~||w}|z~x}x|y{||wuuj~zz|w}x{|yxz{yz~~}{~{xzq~{}|y|||{{ux}~}|{}t}twz{w}z{|z}~tv|~~}}y||~wuuy|}|t|y~zq{z|{{ux{}z{z|x|zzy}x{xzx|~xrrzx|wt}wt}zy||}~tu{r~v}|}}{zy{yzx}yw{yox}~{|ws|zxx}{yswu{vw||s}uvrwzzz}|zpy}z~{|zzywo~{|z|~}|{}m~|{{{z}r}}}|zqyd}u{{~zs~xy{v}~sy~z|~w{~yrxzuypyztu{}{}v}|}{z}xys~ys|zv}}|vy|zuzx}tx}y|{~}ry|}}tx}z}~{ty~y|x{}|{}~zr{v~y~z|}x~}s{z|wzx}~wx{}wx}~z|zy|{{}}xzzz{u|wx|u|z}s{z~{}|~{}|}~ux}t~z||wx{y~}z|}wzw}yvzzrt~{}y}wz~yu{wzp|{yq|w}}xyy}uxz}zwy}yzz~z|}~t|~}{{z}xyrzux~}ux}|zx}zxz~w{}}~{x}}{}y}u}}|z{|{x{w|~}~~}yz~v~z|~~w|zx{}z}{utz{{|{||{}z|~{~|~}o{|vvyz|vzywq{w~||uyuz}{v{{{zv{~|z}~}~zw{s}x|z|tx{x|z{}x}~zw~~~~ywwu}}yy||}p|~|~u{xx{ytl{|tw||}~tzozv~|yz|}tz~v}t{z|x{n~~{|v||y~x|}~z~~{|~}~yy}~vvuzz{{{zzyw{yi~z}x{yt|~}}~|~~x{}||zz|{p}w}v}xzwv||||{{s}ztx{y}vuyw~~p~uvwww||}w{xz}~|zzv}}xx}{z{sz~x|w~{{{uv}y}t}{~~~zyz}~}vzyumxx}}tytwv~{t}s~|~~~s}zwpzwz}~~~}~}u~u|~||~szzuv{vzyxx|y}{{|~|ucyxtpx||v}p{xq~{wx}{~{~z}{xvpu~v~}~}y}{uiywx|{~{o{y{}z{x}}x||u|t{{wvxz{yyo}zsyu{~xyw}~z}u}}{zy{zt|vy_rxwz{|sw|}vyyxtzy}trn{y{}zz}|sqxr~~y|v||{u~u{zjrwwt}zyz}yz{wzwwp~}z}|txw|zvz{}pzwx|x~{q~~xyxvpy}zz~ug}u|{|~zw|}r~sy~S{~tyu{zlxyv~{|{|{vzyvvy|[xwyw|xzyt}z||x}}{{}xv|xwyvysr|wz~{~v~y}uxz}u{}qtzxy}}~oy}|}xwz|z}|yy|wszz{|}}}|x|zuzwt}wx~tu~{vz~z{t~|~m}}~woztzz}vuz|}pu~xt|z{j||~{s}{yur|v}my|xpyuw~}~}|~zw~a}z|tyx{yuqqK~}|}}|zyz}tx~{yz}~xt{|~~ysy}~}~|{z~||wnw}~s}z}z|~{}z~{p}~~~~w}~|~~~v}w|nuy}zz|yv|uyzv|{yt~zsyz}zyp}w}u~o||xp}r{w~}}u|{~|wvrztv||{|{{~w|xyq||o~~~xz|~}}k{v|~ym}}}{ywz~}||~~{xw|xv|{}|}zxy|{tz|xs~o~}u~~~~yp~{|z}u~}i||t~~|}|{{}sz~|~xz{}~{}{y{|v|}}{s{zuys}}yx~|||zxz}|vv|}iyxyo||{~}xv{~v{~{zy|xxuxx~~t}|{x~}v~~w~y||~}}|z~||z}x~~zx}vl|~|x|tw|}w}xvr{ssuzyw~w}z~~}{n~~w||w}}ty|y}q{{~u|i{|~{t~}{xzz{}q{t}{z{x|~||wx}}zy|yq}||zsy~x|~yr|vyws|{ww|rty}|y}~~~|z{}~~y}{~~}~y}vz}yzq|}{{||~}~~|t||ws}r~v{t}}px|zv}~}x}{yxzwzu}zszoz|~{}utwz{jtt|yyxso~}y|t|}{y|z|y~|wwquz}y}|~|w}w|{wyutzyv|~v}}z|wu{z~~y~}|{zs{t{{{|vz{vx||vx}~~}}y|zxz|}{z|y~|z{{}z}{{{|{~xxzw|yw{uz|}{uw}~yy}s{}~|~uz|~}~vzs{y{{{{zv~~vz~~wywpzs}}|}{~}y{n~yw{u{z{|w|ruz||wz}vyz~vxxw{{}t{p|~|y}{}z{y}{w{|y|ry{~t~|}|}~{yzzv~{xx||xu~w|z}}tuywyps|||}{zt}~vzv{}{x}yuy~yz~x||{{vy{yx|{{|}{y~{||xx}z~xp|tx~~~t}}ox~w}zu}}|vz~y}|}{yzw|~~yqy|}z~|}xz}|yzz{~z~~z|szuyz~}{k~v|w~||wx|y}k}}yz|{v|wwvr}|z{|~~w}|y}{uyv{y|~|}z|}p~szzw{z~}ezx~t}~uol~{yzty}{|{xyw{vy{zx}|}tyv|~~}zz{|x|{r~|~|z{x{y}v||xul{w|{{{z}xyowx{{}{y{||w|~l~v~~{v~u{w{lyw}x}xw|x{}xu|zx{~~st}{xk~{s}ryu}xozur}v}u~}z|{v{y{}v~}xv{}z}zwzp|usy~s}{zlzvzx}wy{{}wr|||y}{}}w~|~}x~}{z|xz~~{~|}z{sw}p}{vo{yvi{~rz{|xt{}{xyz}vss}{w{zxy{}sq}v~w{|{}|vwy|z{{zc|zu{~{ytvxutz~y}v|qx~u|u|}|z{}{zryoy~zycyx}uu~~~|xs~l~~w{y|{|vuwwz~z~{sz}{v}yr{x||}zvtwkvv||w|zz{zh}zxxz|ty~zxwt{y{{~|{zyn|zry|vx}z~{y|{s}x{{y~yyhux|uxyzyz{~z{w|~}u{~}~}v~{~x}{q||~}w{mxu~}}z}~||z}}{~z{wx||x}~~tu{ut~{}}u~~~}wu{~k|v}xtz|{z||~xz}zz~|{|z{pyzy|w}{t|y}xu|||x}}~z}|y~xvy||~vmu~}yw}ryvtz}~y{|}}v}~yyztu|~|xyt|{vx|yx|z{||t~u}xy}}w~x}}xt}|wjxxvz|{}{~|zz||}}x}ezut||t~wwnu~l}}}xyvy{rtizxz~u}~z{~yvl}{z{|{}|z~{||zz}|||x|y}zz~w{~x~{x|~y~}zu||~z}{y}zx}}u}~yx|u|x}v{~xzzz||z{~v~|}{~|}~}z}~{y{z~oz|{u~|{y~zy|{{}|yzxyxrz||}x|}}|}{}{uoyz|{p|v~zy|znz{zz~yxw~||~mzv~|y{~y|}{y||}v~y}{ty~t~t}{x{z}}}}{}~qyyx|}{zz}}xovy{~}uq~{}}}|{v|xv|}}~~o}~{z~z|vx{~p{~sy~{{v}yx~zwsz{uyy|}||zz}uwy}y|x|zy}yxy|yuz{y}w}y|ww{}prw{v|v~zu|{}~{rz}~z{vq{|{}{~txy~|~|zzz|{z~u|yyx{{|y|||w{y{{|{|zp|r~xox~{|u||}|~~q|{tx|}|{}zxv|r~w~xvmw|v~|||~z{{ru}x|~tvy~z{v||}}~{|s~}yy{|~~z{}~u|}wz|sx}{|{ux{z{y~t~yu|[{||xt~}}}~}~~uy~}~|z}t{{{~~{}zu~~|zyx{{{}~}zrw|y~p|}uq|}x}~}qn{wy|zwnyxuyywnw~}~{~y}|~ryz{{yzvxyry{~}|w~yu|}|}z}|y~~z|}|{zv~z{~~}}|l}q|}{{~|z{xz{v}}z~{||{|vzwzy}wy~tzwyx}|y}{t||{}{}~vys}x{}w|{y}}vzw}o~zyzn|w||q~y}|~z{}}{|zw~z~~{~{w|v~svy{|{y|{xx~z~~tw|}}tv}~}~{~{x}w}~p||}|ns|tsx}~~|}}w}pq~~szytr|~u~~|{{~||y|~oe}v{}y|t{|zzq}{o{xz||~xz}~~w}~}wyzwy}y|y}~~}|xv|~s~w}v}uxwyy|||y}}}{}yt}~|~}xuy~y{}|z|{}{n|}|}v}qv~}ytv~zuu{~~zwy|~{y{{}|}~|s~}zw{ryzz|z~yx|z}x~r|||z|zy}l}|{y}zz|{y{ww}uy~w|q}}x{yy~ky}{wztqzw~y|wvz~htrz}~}{v}{|}smx}~{{~ve}z{}v||~v|{{|yv~{u}|{y~ux|{sz|{|~t|~}{|u~yuz|v}yv}y}z~{y}w~~{||wyyy}|t||y|sz}u}~~}zw|}uxzz|zYws|~y}~y}{wy~yvxsx}{x|yz|~i}{}u~|z~zs|z~uy|~ytz}rx~vusv|zz~rx}q{}ֆx}zw||{}|~}zs{|twv|~n}yxyz|~|wxy{}z}|}~xywz|{|v}~~}}|}}y}{svyx{w{~x{|xuz~~t||zw}|pQt{{yv~~yvvyy||zx}vy|w~{wxy}tzv~w~}txxy~~E~{~zwx{yyytuy}}{zx|yzx{|yz{}}r{xs~x~~{z}|x{|x~sz|~}x{w{{|~{x}|v}|yy|{}twxtw{|lx{w|ywtpl~v}w|vyzzzxz~~{r}s{y}x|~{qw~sw{q}{|yu}~z}~u}~~~|}zy{q~x~~y}s}yzu|x~zy~wv{wk{~uywx{ky~y}|{xy{v{zx|x|y}zz|vzv}wt}|zuz{zs||wq}zz{}}rs|v~wz{zxxxuy~{{|z}|~~t~}{~yx}x}{xzv|x}{}{yxv}z|w|{x~{~|~yy{yzww~y|}zv|w{|~z~wz}{}|z~}{xyz|{||z}m{w{~}{yztsw}~yzw|z{toxy{u}w}|~~{|v{zz{wypy~|t|kxvx|pz~{{~{}|zx|{}vmy{|ziw~zqzv~z{~{~}{}~wyv~zz~xyxy}yt~~x{yswys}z}{}~~}}yx{~ww}|x~u|}}{||{}y~t{zt}~w}y~v|}zqyn|z}gx{{yz|x||v~z|z}{y||~uvyy|vuy}s}|}woz|yu~y|k|wsfvw}y}ud~xwwywxz}wy{yzykxyr{t||zu}x~}}}xrwyz}w~||utz}xv~zq||zx|z{y|{vmru|yww~rwx}xzz||z{|yxn|{~ut~{q{mox{}|~~qi|eppu{wzzxz~zwzyqrx{|p~}~uzyz|oyu{}oryqzz{|zusrt|{uqt~}t{z}~|{|wv}~p~yvz{zo}p}ztm{z~|||wx}{xwkyv|}yw}w{yyyU~~|w||unq}q~}~vx|zqvozwx~~}sp~|ywn|{}~{}vhrxzr~~{zw{b|w|vsv|tzyy}xxtu}t{}vtutu{t||gu|||t||kzxzow{r{}|pyuvv~svt~}~w{vsuwvt|~zeyrxy~wYtuw|~{w~my~xl~}{|x{qw{{}vzy~~z}vz~z}z|v}{ty}v~|}tz|}lt{zx}v|y~~}zoxz|z}||{zz{|z|}}}zw}d|~~|u~oxvwovt~v|wyy}m~||tzy~|vv}|}ttxxr|}~z~zzz}y~||||y|{t||{~}|zs{]z}~{{twu}{u{z{or}~{z|~}}ut{lyzyt}s}}~hz|{t}x|w~x|z~xx{ty{w}tpv|}ry{y{~~{yx~p{x~zu|p||}}z}~vzjv}|}|xxs||wrtpqyy{~rzzyxzs}x{{tz~yz~}wy}z~}wwcrt|wxv}~q{|n}r|~{{}}p}~}z}}|}{z~~z}|u}v~|w{{y}}w{}z}}w|zsy|{{}~y~|ty{n{~{|{|~~|}v}|lp|z~}{||x||srq~}x{js|x{r}{~|zmu|}}}{zuxy{}{x{~}|}}~{||{{ww|y|~}}|||}||{yy|{vs}v||{|~uv}|q{xus}r{}w~~xv{zu|v{}}~i}}z}}~~zy}}}}y}||}~|}}xzvu~u}xy}}pt~~}}x{||{r||}lxw{z}}tnv~~|}xyw|~|q{zz}y{|~~r{xxs~x{xzx|w~zz{{vuz{||}syzyt|zx{}u{s~n~|x|vyxv|z}}{}||{}syv|yuqz~~wz~uz|yy|~}{~{}t|u~|y||~~~x~x|}}|{{{tw||~z|zw}|y~xwx{x{|yxsx~{sz~u~|}p|~}~{}tx}{|{{x~}{~v}zw|z~zn~}{}|yvxy{}{yy{zz~w}xzj}s{u}xy{zzyzztut}w{~zp}wx~x}}{}|z}~{z{{|~pt|zz~~}{|~z}z~wz|||~~{~~{tz|w~}}|}}w||u||oz|p|zyw}{~~zywyyzx|}t|{{w}|x~u~y~|{~y|z{{~vw{wq|y~{r{~w{~{}{|t~{|x|~}{z|~zpzz}{}{uzyz~~ny|xwyw|~{||zy{|{|}s}x~|~{~rwx|}|z{osyuw~xxxq|z|z}|~{~tzyvw||~{{vp|}~~|xxx|}||{v~r{hp~~|y||{~{|xzyg~}{x}{}mw|~ywu~}~vwz{yz~{~{~~y}|~wj~yx}{|x{|}|yty~r|}~~}{~w}z|q~ssp{~z~yx~||||w{{w~~{~}zzqw~yx|}~|r{}xy~tv}y}x}ztv|lxz{yy{|}|~~zx}tx~{w|}}y}w|~y~zvuw|}~l}z~v~y||{q{y|~||iy|||zw|}|zu~qsx}|}|yz}{}x{|~}yxw}{v{{~zj}|j~s|}y~ys{}y{|uxrz}}}xw{qtut{z|{|}|{z|~~{~z|zvz||us|~{~wzm~}{~rv|~}towjs|s|tx~yuw{}|}|yruwz{{v~}r{}swt}}ro}zt||t|p{y|{|y||zm~zwyr~{}u~|}n~{z|}~|~}xwuox|~||vz~~z{wzzz{}wwt~|sxu}}hz|u|v}u}uz}|q}}x~{zxo}{|mx~|vt|y}uyx}|wxqvw{{x~v~y~~`~}{}|w~sx{}z~~x}|{~z~{~~vy{wz}z}y~{}truvv{y~||xq~~||yy~~{s~xvvyuw~x}}~|~vvz{{~~}y~x~oxxlz|}z|}|x{}~{{|z}z~yv|pui{~}zzxm~u{xm}~w}u{|v}~x~z{xvx~k~~v{xz{v}|up}{y}~z{~v{|u~wzvwoz~}|t|~l||{|~}{||x|w|}vzz{ww}x~~}}~~||}zytz~zv{sw}~v~|s{}}~|{u}|~~}}{~vwu{|~{|zyz~}z|t~}x|x}~zy}w~}s~}{t}|~||}zw~{|{r|j{uy~~z}}~z~z{}}~|z}|{p~yr}xyxw{|~xsux|u}|}{|}z||pm{yy}ywtt}{zt{v|y{{zw}s}|{~~|v|{zr|n~{z|}xv|~vh~|~~|z|}{w|}y~zzp~w{}}uy{}o}~wyo{|vx||~~qz}|v||z}yvz{}}~yxo|yy}sz{}{~}ti}w|zwvxz~yytw}{x~xz~|}|~y{{yx}z}~~wrv|tx}|w|w}~{y|}y}||~}|}~~}z{z~s}x|{qxz{|~r~vy|zy{~vy|xyy}s|uz{~~}~vzz{}{~}||yov|l|y|zv}y}}y}zyx}xz~}|y|{|}xy~s~u}xz|~}wx~}{~{vyy}z}{~y~|w{x}{|t~uw|z}|~}vvyyx{~{~|p}{~|yyz~}s~y~xx{}}zx|}x~{zyy|z}}}|~{}|{wsu|{zxvzj{|}|}~{v~x{w{}}}zyyyx|yy~wy}|||ryt{|~yx}|{|~|{|}~{{{xm|x{~~|}}~yv}}~}{t}|~}}|||z}~|y~~||v~s~yy~}~~|z{{~y~|{{|vyv{|~||w}}}zyzwx|z|~z|x}v~{z~wzuo~y~{~z{wv}|~y|~yx}}}}zzv~z|x}uu||}xy|lxuz|xzxv~vv~}vy|y}}||~||~~ywwtx|xv|k~{wszz~x~}|{t{{}w~~~|{xwxxr~y}kw|{}{{|{y~z{zwzw||tyz|{r|~x{o~}}xux}|r|usztr|{w}}}zx||t}zz~~x}|{uv|}zwjyo}}t{{~w~}zo|x}vx|wouy}{{~v~waz|||vryfs~z{|}x}o}vuy~x}|xy}{xr|zwrt||}v~wx{{~twu`t~ztx}|~|y{}|u|x~xxz~||~y~}}z|||~|uor{q{xv}vy{zzswtnyy}yv|zry~q{u~z{z~}~{n}vr~}|w~~{~~}m|t~s|x|{~z{|fx|}~z~zuzux}|{{{u|yn}}|v}~u~}t|u{z{|kxp~{}{zy~{{~|y}}{|zzuws~}||}}{~}xwouz|z|}|{{||x|}vywx|||~||}x}uv}|zyvw|}zw}|sy}v|~x|{x~|}|~||{|xz|~y~~~|z{x}{vy{y}}{{~{v{{~}xr}{|{j|~~}x|||u}}y}}{~u|}|yy{e|xu{v{x{~z|}|x|}|~z{}|}|p|~rw}v{~zzy~zt}x}v|}~w}{x{s|}~zu}z}{|z}}}}}{z~xzxz|{zz|~|}|x|}uxw|w|xyz{~{}{yw}}|wm}s~}yyz|sw~{{~zny}|y|xxzv|{~y{|}z}|{~{}{{{zz{q}}{z}}t|wz|~yi{}zz|v|u{~|xzrv}~x~x~vu|x~~xw|}vz~~vtv{}wzo|||xy{l|twv}~}uwxv}zw~~|}}}}~uszu{wz~}vzz~qx~u|o~{||}vxt}x~zmww{vx{yxzyvyzy{y{~z{}|{~~|y|{vsvt|s{~z}}~y}~uxv|z{|{t|uyz||z~{|s~yz|z~w~zzoz|xz}y|z~{}|v{}}yp}{}zwrw|svu|}o|x{~|}}zyxw~z}yu{{s}w|z|vz{zyrzztsy}pt~||~w|vu{{}|e|w}x~{xt|zw~y|zuts||yxspx}x~|~qt}zy{w}xvwx}w|{|w{q|o|uy~v|xlj~~urv~{x{|}}zs{~twq~z}{wy|wv}y}}~wuv}|ty{}q~{}{t|ovz{zx~yvzs~wxxw{|x}xz~|~{yv{u|r}}zw}yzx{yw~t}q}~~w|qxlvzzz}||~vuy~v|~}}{{|{zsv{us}r|yg||}sysr|{}~}{}|ynw|t}|~v{a|~v{vxoxyt}||w~~q~v|z|~zxv{tup{{zmzv]zywy~z}zvuwt{{}z}}x~wu}ixvtz|{t}u{|wu}{v~{qx}~zqx{w{p~x~~|z{|sz~zzq~zy|}~u|}n|yx{{}|s~z~x|yxz~w{wrzyt~{swv~ywx{x{tyy}o|}}|y}}y}~{p~ztxww}v}{u{xxu|t~|nstx~t{|{s}v}}uy{{{_zs||{|||}g{}~y}sq{}}~{xzsn~}r|w}}{|~~~|}|t~{{xtz}||~||uzx{||zq{~p|zx|xz{wwswx~}zx~|kj{}z}|ykwv|~z}ttv}wz}uy~~w|~y|x}wry}zul}{}|}vwtuywxy~{y}}~vyzzywuyyx{wx|x|q|}w|rwysoiq|zzzz|yyxx|zz{|}yvw|r||{}zsx}v}o~xxx|}|z}vvvy}w}}~yv}{~}}|yxqx~}y~xy{||xyx{xtwzw}|{y|pr}}xs{pr~wxt~ww}{{{~v~r{s{nzuswy}}yz~|y}zlzz|}oxruyV~~~uwxzwr}|xp}s~zyuu}sz}}{~}y}~~q}z~ysv}v}~}{{|~vz{z{kn}~x}}~|}~vs{rvz}||{|x{x}|o|gtmy|~yvxt}|{x~||d|v{|||~}}qpsq|{|o~~z~|xv|utz}y~ny~}wy|z|~~~{y~|t~||}}}{}l}}}~}|~{{z~y{z{ys~~u~~zvy}xwz{z}|~o||{|wp}zt{~}~|xz|~{}{}vnz|v}|~~{w|zwz~{wnmw{|}{z}||x|{}p{z|{}|~}{}vyw{~|~y|x}zy~y|q}~|||}y|~}~|}|~oyzyx|~v}{|||syw}|tz~yuz|ky|{|{}{y{tz}}|~~z}||q}ux{~x~wv~ymtz~{}Yup|o|y~}}h{wx{|{x~}{|{{p~zwuwxz|}{x||mxpyyrw|^{w|p~wwz{yuu}wztw~}s{ywz}{xMr{~~~|qxqw}y{a{~zz{st~~t}|{yxx}sq}}o~yywywx~z~|ux~v~y{}x}{w~{~urxptz~~{~z}{{v}y{j~}{v|}w}z~rymwxw{|nq{y{}t|vwzzi~j}|||jw}{}qx~~|y|v{wx{}t~wyz~p}}|z|z|xt}|u}y{|y{zj~xxxywvxzz||wxyywzj{z{}~yu~}~~yx}}jfryulqxr}t}|{{x}s}v|{{u|r|x{~w~|}~y}{}~|lv}zl}u}~xx~|~{zzp|}}|tjy{z|yyv~|}v~uskty|m|w{~{|r~sxx~}|~zpyvx~t{wlzpzzpz}ix{zx{{|~{|x||xwvutxw{vz~rpsthyw{}xy~}zq~{zs}y}nyx~vyx}t|~{yz~ztw}ynz\wul{z~||uw}|yvxy~y||}t}}uvpvxm|vvyxqqszt|wux~f~r|{g~~zvs~x}~tup{x[}|iyt{||y|rzw{lx}z{}uwr}{|tx||yptzoxu\~xy{|g}u}~vyy~~jbxq{wx}_|x~~x~}qxvuyk~zq}{t}}zvzyxy~{vdzv~|rzqnxtpy|v{txv|~z~ozvxuzw}~u}||rw}z{|{x|{vo}|{yuoz{gl{{u}~}{v{{w~t|}u}p{{}}{|||u~mw~|z}}~}}|{}~~e{z||v~}{{z~w|}sf|x{{v}{|}}~|u{~y~}}v}u}|~zvz~k~xop}y}~}|r{zm~ux{{{~~y|t|pww~y}~}z}|u}uz~|}txxwv}{}~~zvwyyy|x~}w}{{}~u||~}z{u|r~}|}xt~|v~y|}|~}{p{|{uzv~uzpx{}~~uz~{{y{y{~}|itt}}w|u|x{p|qyvx|zy~~||}}h{vy~yt|}yu}}~r}zyz~nnw~wy}{}~zwo~}}yum|}x{}{}z}}~r}}}{|~}v}~y{~s|y~~}v||~~|z}|t|||yz{y{}pw{}v{v{zxs{sw}|z~~zys|zvztt|s~|yq|x~~ztszz}vr~hyx{{xy}u}|~|uz~~sy~{{u|}vxzwxy|m|v|zvyw}szzvtw{|{}z{|w}}||}|{yywz}}y}zw{{zz|y~}~|}wx{y{~z}{{z{{|zs|p~yw|u}||}s{u{w|wxww~~~~|y|pxz~w{z|zxxo{y{z|zx{u~~xt}rv|yx|zzzp|wwzz|}uzy}s{xx|xy|py~y}|xw}~}|}}{x}{}{|~u}}wy}{~z}}~~z}}}z|xy{}|y~y~z{|w~{x|~{~{yw}ww}xvzvtxx~w{x|}}xq}{|~z}~{{}|r~zst{sux{p~yz{{yys}{yw}y~}}|}}}x{wzv{ozsvvyuu}}yz\~y}y||v}xz}~r}|J|wzyl}}jysvytywzfz}{vquqti{{~|zpzsx}ry{~xyt~y~x{w}}zzy~x}wrzw{~{}xr~~}zy}zuszvzy}x~wyy|x~w~x|}}s~~zwy|t~gxw}zvz|y}z{{sx{y{yxrvwy~~~{q~{}|y{~Rrrx}zvz~{~v}xz}uyyy{~~vYjy~xy||~zwvzwxrx}u}x{vuy}{~|zxq}|}{q~x~}|}{}nxxxy}n}zvq{vs}zur}{~t~|}~|~{~v~}}~w{}{~~z}wx~|z~:}{w|}u}y~z}x||z{xu|}u~fyviwzuyuzq{~}~zyzy{{tz}ypw}pzy|m}{{rz|~}~\z{tr~xzz{~y|wv|~ow{|y|}|}yzr{}zy~|uz|x}~|qy}vx||z}~wz|~~}xwyx~~}{rw}w~{}|~~|r|}{{sy}yt}zyx}}}~{~~{n~z{|wy|{|}~y|u{|~y}}|~~sz~y~~z|}t{~vwx~}zzxt|u|h{|~{|{z|}w}|pyzys{ys{z{wwyu~wyyyu}~|u}||||}yx{{{rv|y}}}}y}z}v|}|}}|{{}z|}{}}ys|~}~||xtx~~~py|wyzqmyxyyv|zt|||~tl}zzzx~|{|zr{|{{ut|st{||~z~~}wyy~uy{|{|{z{}z|rx}}ww~|~zoxr|{y}|}x||y}~zq~utw~v~||yy~~|}y|}w}}t~~}~~{|x~~}{w{}~r|~{}y}zz{o|y}~{}y|lw}}z{n}||||~z~z}~w~txztx~{~~~}}{v~y|x~nz|t~v~z|x||vy|{{y}~~~z{yzz~|~|~z{yz|x{|}|}|~yzxxx}v}|~~}t|x|t|x~}}o}}zz||yy|~{|}z~{}}wx~w{t~}y}x}~yy|~z~|yszvz~t~|z}{x{}|y{l}}}{||~u}zz|wx}~|w{w~~{{~zy{{|xot}{x|~w|}snu{vy|y~y}yyx|||}yy~}|||t}z|wz}zix{~z}y}}z{||y}xr||{}{|{tw|y{}p|zz|r~|{x{{{{yvyz}{wy|{|xw{zz{yu}{|z}y~}|w{}w~yp}wuw{|}yvw}tq}|v}{z|hzz{v}|}|ww|}~zz|}}{}|~wxy}{}~y|{}z~{uoy}~u~yyz|{|q|~qwswz|}}x{z|y}}{|zxxy|sy}zw}}ryz~yywz{|y|wxv~ww|tv|w~xt|{~u|}}z~zt}xq}z~uvzu}|{}x|yw{{wxy~zw}zvx|x~t|~yyx|u~yu~|~|ywxzy~zwu|{~|{yzy{~wq|}vqw{~{|z{zzzxz}z}r}~}}v}}~}~p~y{{{wt}sz~{}ww{~{yv}}y{{zx~{zzx}yyvs}{x{{~|}vyy}y{}rruzx~~z}|ty~uzxy~y~xKd=|hpfs~o,|XiV\l|p`wfpo1o`qzD_c]meK~KxvdxwBnuÇ[vht_^vKLlOfg{gm|byZpUngzn|b~t|s~zrhkujleiIiǩV|XsUSØ^mvtsLlg~ˏ}4yqYHWES~ImdrbkvoQUmExqysy`Ca^Tcx6#]ypf=|G~Fy\^Z+%og}{bd.vffɞiu{|`lmRboU]tqkvkvu_oV!dxrk|Y[I}`:wyyg1<]1uepca~f\gKIùqtj|]Û}s}xzxz}}zs|}|{}~|y~{wsyxzx}w}{|qt{}x||zy}v}{}uv{{{|z~{{z~~}~|x|wl|yx||k~p{~hvprqktowv~}yy{u|l~xsxu~~|y{xrz~x|}w|x}|~~uy~yrvmryyw}zptw~|t~wwy{}cy{qwzr}w{szuqzikoiu~s{s|g~{΀t}~z{yvtd{jwtxHmu~|{||{||y{xtuvy|_z|{hvrx{~||z~{y~~{||~}y|~{|kmzzw{{x|ws|t{ykbz~xrzh~|ym}wyu~wc}yezo|~t|}~n||qpz||~~pwlywxpwfp{~mvw}pj|sv{~{iyzvu{~wyzzzsyu}~ky~~t}s~{~|u|vt~}xz{l~q~({u~xxyvxu~wz~~}r|zruq{~syl|{||z{~~|z|y{s~}{~~{z}||{y~{uu~d{n~iyyq|xm}y{kku{}z{vz~{}}}w~|zjvx}|{|xo~fza}}Ut}~{yNyh|}r{~}|zz~{|{r|wv{vw}FtD}}zy|w~~}y{~~ww}z|{|~y{pw~{qnuy|ry{|w~s|}~r{z}|~tx}wv{}zm~~u|}}}z}}~{w}w~uz|{|l|}z|rzs{~xy~vtvy}wt{{|z{~xxx~yqy~v~}}|~~|{~wzy~|w}r{fu|~q}~|}{~}rsy}}{~ly}]||w~vrytq~zugqz~|jv}|~V_~wt~~sx{t~{|sL}{z{}~~|zyw}~}v~n}|x}o}ro}nwz~r|{z|z}|y|~r|zw}{|}|w~z{mztyj~v~{tq{{x{{|~|~|r~~}ws~w|z{|y{|z{{~{~}|{v}{r~}}|s~~o{yvz}t}~xpzz}}y}ulv}u}z~w}z~}}u}y~yz}~z|{r}{t~}e|{}{x}y|}m~q`~}xq~yjs}~~vxq|q~{tqp}{||zxIwat|}qx|||~tTvs{}xy~q|P{}oa{}wV{x}{~zw{rfu~|||grz~~u|{p}|x}p~~zxqzr{~|x||~~or}}y{~drx}|~t}}{{x}}|~||vgqqyjbik`Za{njkc_Xc\nx^jb^hfoviunmy}i}iLjnq|bk`fbci]nnpe\elhl_cdcciala^yx]aizoppqpgqaijotq^|`_\ema{I{p]z}sn|cifg~}s~~|~}xv~sz}~|tyxr~}z|tu}~f|zqrt}}}{z{}}t}}|}uz}yx|}|}~}|~{y}z|}{r}~w~|||zx~zy|z|{}}~~|{nv|{{y{swu|~~}~w}xw|{~jo~~|}zzmx}{|v{~{~|x~ws~}z}}z||{v{|w~x~sqn~~{y}}z}u~v~{~x~ws|}nglgvy~|~}}z~n~}yxv}}nr~tq|shzx{~{vow{~y~u|^|{~z~xzyy}~~z|~w{w|z}zj~yhf}~}~ory}|xqyysz~~}}x~yo~g|t~~|~ql{}~sk{t|~ja~zzm{}]o|~u~wvwZ}~}x{}yp|ro}x~~x}~^hnzu{~y|}~~}z|z~t~xyt{~xksntmy{u}yzs}xz}z|y|uvw~q{{p{xb{{c{|h`qvt|aoktzy{~|s}zkruUmiyxwzx{shzlyio~~~ffy~y{tt}[io|z}zz~uks|~m|~nvt~~~}~~{swy||sq||opoxrx{~lulmy}|}[}u|z|{{z}{}tzqz~||~yh{u}}{y|yy{hx|lv|~xy{sre{pz|jpk{~s^~xm~}|ly}zz|~zj}r}w~~~tzpzs|pY}xf{rv|~ywzz}|{~y~vsq~~}~xqyz~~}~yxzzvx{|u|}xwzz{j}~|ux~~xz}{}oq~yu|{zvry~zzz~wr{typ{}uw}tt|s|z{~qqxxxk~uztzli~m|ukluuwx~}t~|y|zq~~v~~j}{~|z}~u|{sw{w{|s{~{t}}yqz~|tpj~qZ~}sirz~{ykuzzv~tz}tx\}~]}\ivgzq~QozsZL:gz<{{~qqxx}oezUw~||o}~}{~vvrq|wx|na~x|y}{ix|{u}z|y~{xv}~~xwxy{|ty|z}x|uzy{x}|Xsgw{ey{{}ti\|mMvor}}p~~w{}}rO|wu~}w~ysvw}|zy}{w|}v~y}{zw~y}~}|gx~py{xv~}|~w~}~}x~||st||}gu~z{ixy{qz}|zxv|q}z|}|zn~xs}p~t~y}||{q|zs{o}ss~}}}zyszzx~~zowu~~ypvlvxzkY}yvxp~}t|g}{~o|a|}|lqnotou}jmqup~|t{ypzvn|tpxvxvyswvwpm{zmu{p{|yytsyqqo~~u~|||~mvh~xs}z}|w|nw~|{|uz||xz~~~}|z}~z~}|~~|~~{}~{y|{zyz~wz{}z{}y|~~y~~{s|{~}~~ovm^|}}n~qs{}x}xy}{t~~~~}~}z{z{{~t{|x|w}~{{~}x~zw|{z|uitt~smywtx|~}j}r{un~yxn}o_Qfbolz=j}p}|t}{`~xt~|y}~xblp|{n|mc|x{zw|{k|s|y~u}{~vz~ud|~}|~}gwy|~z{|{~vk~|z}n{}~}~}u~l{y|zt{nwy{{voz{xx|{cmj|~}v~vyzsyo{~wrw{~||zs}wy~s~}yf~}vuvm{}zyvz}|w~frp||}}u|}u}t~~}||}g{}}z}yz~~|uov|{{{mqrv}gwh|~}|~x~yv|}{~~||{~x{{~zuy}yzo{|yw}~|y~~p~gyu{|w~w`p{qvfzp|xx~z|~y\|qt|~z}vvy}v}}}~x}zvyy}~}sozzy|~x}{|pz~~iwp~~}t}x~x~~j}xuzzzroz^vscpowu}}}zi~^}{~tsyvqvyv}}~s}y}nny|{{xztz{ukq|~|xu{}|}{~}~~y{u{uq|t~n}n|w{w~o~v{ry}}l~w|z}}~||py{ss{}z~ux|~k|{yy~|~}s~}rx|y|n||y|}~zqt}rd}r}hvm{]|{zx~{w{xzoyw{~w~s}tx~~~ur{zzz~~w~li}}~tt~zTs}||{[tkwx{dz}xr~p}{}s}vX~y{t|~ov~|~z}us~}~q}x}|l}}}tutv~dm|}|xq}u|}}~u}~|~}|x|w}~wyw~xoy}~yw}x{}{s~~x|yd}y{~|yu}t~|}~uv}~{}~astynsw~}aysm}}z|||~|y{~w}wq|rv}}|w{v{{~zr}|rysx|stf}n|ymk{~yovz~cz||{r|yz~}x~~u~ynu}~yx{`vq~}qz{~~~zrzzr|}|wt}u~~}w}{m~o|~v__}{|t}k}t|w}yyx|{~t{xzi|q|}|tye{xzxt|zvpyzz}z{p{ya|muO|j}{~|zn_id|k{z|zQJU|~wo}}|zx|yv}}zuz||x{nx{||zzy}|w{|{vz}yz}r}~yw|zvy{z|x|z{|x}vu~{|xyw||y{rt}z|yzotwyxyxx_w~}wu~uU}cr|}~Ur{zx{tqtFqw|xoxpk~=`}u_t{owsyzz}wwo~[w`}|}~yn{{bz{~dozx|zvf}u{~zzwxyzzx}f}~suz|zurfw}u}^anW[zsay|vrjSyNyy_kwm\p|{xqȄt{]~h|v~lz_v~ywp{ve}}|x|y|}xz|}w}}|z|z~z}|}~~~u~yzq}xz|{{]sw}l|u{}}{|x~{}ggy~|u|rprxx~ss|{r~~z{~y}uz}~u~}~gn|~~y~sx{}~}zux|p|vvz|}r|{qfw~sqfge}rqy}zyv~}|tx{nk|~}~|~|}}z}}z~zzz~}{|}x{y}|{xz~||{vvw|zyxy~}uy~s{ux}Xtz}|}}~uw{y{hxx~zz||z|y|z~x}yx~{|~vx~~}{wyvt~}xmzwxw{ysuxwu{z|u{{v}~|}|x|y|}x}v}xy|}Ww~wx~x~yvxyz~~}}{y{}~yxz}{{z{|~z{~{xY}}~yxyyyxx|y~|z{{vzz{zzw||}}}|z}u~{~zw|{yy}yz~{s{z~shc}zv|i}~~{{wyywlbx|~~sZ|~|t~y}}|~w|vm~r~`x|tzv}~r}}k|q}{g~~~~zo{~~~~yuy}wy}u5~|vzv~}zy{}{{}}{}~|{{xs~}}~~{}~x|~~|y|}{zyK~sm{xss}~k}~~|}{~yp~[x}n~w~mn}~{}s}jvz}~|^{yrowzyxns~uz}<}~gi}{|{{s|}cz}|z}w|}kx}f~x~~|ssw~q{{~w~~t~x}n|tuw~z{u|t}}|km{r|{|y~}n|}z{~wk~~|Zvz{~brxQr|~Vurjv^e}y|||xyw{~~|~z{w{}|v~n}|txuwuuy}~zk~~~}t~y|k|{xxz|~yyzzx{|u|}~~w~~|xz~mpQyz|~qL|sz~T|v~wzrp|dxoo^{z~lmb~vspv{|vfw}xw}{rz}zw~~{z}yznxzc|vsyzi~j}wku{tyz{p{rvw{{qgzjx~kq}|}|}|r}~bqv}}vyms}eixgrm`~k~~t{|{uy~}n}di}~zz{}~}z~q|{~~|{~w~~}upt}y|}|~~t~~x~x~}v~z{}{~}~{msp}~~s{}|tu~~~}yz|~rw~\y|wl{~~|xj~|x{~}{{y}|~u}}~yz|y}}s|{{s{~{w{~t}stxih}~j{}}~{w}~k}{q~y}|mtx~~}z~f~ko}}}|{|vu~}z}~~qv~~y~vxw}u|wyzr}|y}|t{~}}y}w[~r^{|t{o|r[|~stuq|u|}xzh}tx@~zxm{]t}wmv~aryz}n}x`xzwy~|ti~t~{ry|~velpw{z~~{y~y~z}z}pvz{{~z~{~|p~}}ql}x|{||~vq{|s|~tu~r{uz|tyx|q{~v}z{yy|z}yl}c}ylwu}|zvz}~w}z{yx}|rsxu}ox{~z|kru{}}{sy{v{~{w}}vzz}|g~wtz}l~xyvwxrwxvmch{v}ovbutsy}s}}ryn|rtMq{|}rln}vj}qzzsq|lq~u|qwx||~}{z|}~v|~w|~turzl|u|yv~yq]}sy|to~~yz}wysz|x{w{z~|yw}}ve~~x~xzzzz}xy||y|{}k|~~~wy|zyt}y}{|w|{|{m~}|y~}vx}~~{z}|n}|t~z{gxdr|~~uu~~}}^|oxko~|||q~s~~~n~}x|~~w~~sz|r|{|xy{|~xs}|w~uz|z}y}v}yz~hy||zr~x~e~u~~y}oxz~}r|x{yr}{x~\hs~sQf|}}{k|zzy~{xrz}o}pwly|}{{~x{}|z}{zzku||z}m|zm{zz||{ow~ud~^|{{usfXg{u5rWvu~|uymh|r{s~}}n~t}~}z{nsj{|}ry~s}u{iwzzm||~|||xw~}~f}b~{~}}}~|~y}xv~txy{}~z~v|v~qvsvj|}kz{oz}~tx~jyw~|I{~w|~ly|{yi~|~{}{zo{j~twxwj|uz|x\m[~yut~zX~~yooow}~~fx}nw}~p}vzzy}z}}~^nr{yk||{|x{{}y~xyww}v~}{txp|z}{x~{~s{z{}{zy|s}}y|qkqx|}i{wt{yv||b|nxgfy{}K|w~x{|~}vi~ji~~zk~s{}yzt~}~v}luwo}|`ux}sjopqstvqv~zyz}w~|{{yyp|~z|{cx{w||||g|~]w|v|z~xyq}}yytu|~~{y}~~sx|t{o|w}u|vy~ut{}z}~}~t{z|r~zvx}y~~}z{x}u|{~yz~|}m}~{v{~{}|y}{~y~y}zys~|~vu{w}y{|^zvpoztwoytyk{yvuz~}}}~k|~kffru~{zv{^ky|x`xs{Lyy|}ysy~ńzv}mřn{|w~rsy}[y}u~ovX~}~x{{}y~{t~|}i~t{|}gxxtz~~ol~kzz~uc{}qp|~hut~|u|~|~uy|o|~~~~s{~~}|ys~}~fr{~~w~}o~xxv}}{}m~{}vy}~~|~{wryzx}z~t{xh~~~vyxio~|omyz}~{yzy~yztgz~s|}}}~{~}{vk{zh~}}yy~x{{}~|{t{}t|rv~|z~t}u{ssnveyz}v}{y|~w|yxtz~n{xoqzs}rzqyt{|Ȉ|{nr~~}{{uv}~~~t~zylwy|~zv~v}jm{{ztw}r~zy}|v}q}s~~{~}z}ytm{t~jap`|~tzhbujR~w}otr}\\]b}-aw~y~y}w~yzx}z|lzxwtz{s}|v~{|s{~}kUy}{{y}{yk}{{{}z~{~z}|ys}oz|w|z}ox}}t~w{y{xut|r}}y|{{zvx{y|~|~{|z}|wxwzntzx~~{y{uy}xxwz{{l~~{v~||u}|^ty|u{t}w~~~|}{zsyw}}t~}}yz|w}x{vy~m}~q~y~z|vs~{mu}s|~}vv}va}v{~a}phx~}vz}h|z~zvrr{~~~vy{z}y}}vzyw}|q}{}yo~}x|}zt{~}}~{~~|v~{{z~~l~syu~x|~y}~}~y}}}}}{x|zvy~}ytyyzqvw}o|xuxos{rs}uz}v~wu|oz}|xkw}Ņwvpxpok|rw{{yqvx_`k{typzkqJ}d|~|{z}vz~}|il|}uix~x~~q}sw|mzw|}vs~~{~zwvztzzy~|u{twtx~|~y~tx}v}~z}i|z~~{wzw}jy|y~}m~t`xur|{iw|}|~|zq}~{~z}~t{|y|~zu~{z{~}}w|~}~y}w}}yutzssnyrspwvrwxq|~xzvujurx{ywso~}{{}|}~z|Umw{|z{|{~o}v}xzqrsrutgfv|nqhwywz||{{x~y~{ox}wzyyrs~r}}~~{p|{s{x~hi}~wt{}w}{zq~kuw{k}og{v}yq|yvY~z}z~z|{|~{}}xw~u}}~~~{}vhr}hrxzqx|}u~wy~|y}wz||~|{~yw~z|r|zwt||~{si|}s|}wq{{ux~s~s}~ywy}yrrvxx}zz{~vnw|~ssi|}~{{|xw{~~z|u~wy~x{||u{zuyxh}{vu{vx{{|{yy|wr~|}u}w|y|xc~vuk}{z}||{}r|}vty{y}zp~v~u~~s{~|{|tzzy}s}{x~jx~|{}zr|{|z~z{}lw|v}}}zyx}|~z}y|}}z~~}zj~Uw~||y~~tys|~s{~ndj|tyj~;}x~Y|x}mh~qt|sjz{zjz|jxwxfpsms||y{s~swvz|ls~t}sp~xvwzhytnxr|}ytltlyv}uus~o|l{|qxn|t~wtxz~|yxzvvqWwr{r{~|g|}yxyzruq|~pt|tqpnv{vqyp}~tu~{wy~{yw|wxxrjznxx}itp~{{u|}{}~{u}z~}{|l|ms}}w{{~y{|x}|~z{}~w}{pp|uq}tdt~~~z|~}|{zZi|r{~tzs{s}{an|y{u{{l~w}|~z}}|dm}}z|yzg}~{}y~og~{~`~yvi}|}x}p~zxw}zvqwy}{w}}w~~}|p{}{y~e~x{{g~}}~{|}r}}~{|}r}{z}vx|{k}u}p~|{}~~|t{}~w}|~~}|~{m|}~}{u~~ys{x~x|{~x~{}z}t}yv|uqx}w}~tul~yytw~}|z|xm|z~}u~ux{{u}z~t~}}mw|o|u|y~x|zx}xx|u|syx|z|}~}y{~|jz|{|nw{~~xwtws}wyzy}{~v}q}|~|{xx{|t}}t~y{x|oq~zcx}m~ht|sn}wywy|hy|{cl|{wuw}]t~~YX|naysxfo`qpxpfpo}~|~u}}xx}hww}~~~~}t{qq~l{u}sv}}x~~~x}ytz|zzyo~x|x}||~rz~q}~~~~ztx|xx|uy~}}~}z{|y~}|~{~}}|~~|}nv~|p~ryw}|zw{sx}zxy~yw}oux|{x}zy{p|{z{~zz~v|zssv}u|}p~ws{^zrlmoxy}|yx}sv|y}{uuwy{w}~z}n~rw}~~vi|~{b[|yz~x|}fy}x}{}}hs~kdtvJ_w[}yZey|yxsiz}{{pz~}}nx||fzlr~|ti~z{xxw}tsvzu}{{ztvo~|{y}}zt}~t|z||{wwywc}{pyWsz^vz~bbOTy~rkz|belz|ynzuvz{~|qt}{w{|{{|}|u}z~vy||tu|w~xw|zw~v}}Yn||{y|~qhz~ucuy||z~q||~~}}}}}zq}}{~uzwt|z~zq^~vr~||yy|}u~x|q}}}~}z|t~}uyv~zzpx~zw|vy}w|yy{z{|~~|uz{v|ww|}{|||xz~zux{u||~}|}|}zyv{ut}}~xzq{{{uz{}|{uttp|}wqytx}szv{}{tyuw|vs{w}pzt|||}uyto{pn}wy~sz|oy{r|z~qr}lw~|~}|yss}|w~z}}~}}z~y~w~z}yzrw~Y||{quy~m{}tz{}}}zshy|ot|z~qzxt{{}v}~v{zvt}q{|wjc}}iutm}c~{gWiMoStNunw~czv~z|p}}t|p}s|nlw~qqw}z|}~sx~~{m~X9{~}~j||rgeyxwwxzu{u{||t~{z|v|}{\q}h{ys}tx}uzytzz}Qr~xxysv{nzywzqYzyz~{|nv{~ywr~Qz}|rpa}xe~wdl}|z}r}wlzqh}Yk~y}}|p{it_}z}}mm^T~y|Os}t~ve~xn}xL~~lo~yl|t}}nw~yzyonc{O~^|usVntx|}}{z{{{}R~|v}n{yz~~~~~z|xv}uz~yy{n}c}}||~u~vy{}z~v}}~}|~{~~ho|~~}zywu|otzwqxz~}|}~~{x}w~~pra}zuuv}~|y|sa}~hvzns{{qzuxzwf{~{uuyuEpwyt{sqQupxz~\r|{}{wy|z~|xyqgxwzyH{d{{~s~^k|~_}}cv~z~y~xrpyy}j}xu{|}yzy{}}zyw{|wi|mUvqza~}}{t{}_sxmws~S}y~Jpyoqs}|sgm|~uuro`BrZmvk@fd|~q}}|{~y{|a~rx||c~x~zu}z}j}wyyv}|~xrxi{ywwzZvB~uy~}kw|zsychz}u~znrzf~{~}{nzzt}t|vq~zz}uc}{}qmt|u}~~}}u~yz~~v}lgtz{zyuz|}}~~t}jy}~|}mz{{w}k}yzqwz~}y~y~t}nwr{_|~mox{w}vs^z~u~wjp}{w|WzKxsx|~p}z{{x~tp~|~uuxv}|x\fs~uw~qZ{lz|vysv~~u~q|s~zt{u{|rwxxzzuuo|{~~v{~hxq{vt{|z~n{{{x}{~w|{s~{|{z~}{y~t~}yxv|~}yqz}u~r{y}~{uv{}}z{}s|{|}zvuz~~}}{|{v~r|~|~{f~{{w|{z|{~swz}xnw~xq|}sr|z}|{n~x|xu}x~z~zxy{~wtjux}pgzvxyys~y|y|pw|}~}}yr|~s~vzxzy}~{sy|q}|}mvxiqpwz~mrz|k~hx}}zuz}}utt~{}x~~~v~}ns}{p~yv|~o~{~~}~~|zt~{~~uzyzv}~{p~z~}w~~k~|zvp}y|yxdyt||rwqosjizv~{}}|uzs|sz{}z}|}zz{|xpz{}~~xx}||{~z|~}yxmy|z}|~}y~}}{vu|yy{u|u|p}e|{}}|ytaz}ykyU|~}x~|w}zx~~ne{q{eVvz~}}t~uzy~|~`xs}{|~}~ph~`~j{}z}hzyvwr{f{}v}nl~}}zf{yu}|a~{y~|o_p}Qk{{mtu|}~ofz}g|zyyfzwiw{yzRl}y|{~{vWv|ysq|y|{{{ys~``o}|xRertu_d|i~y]s`McR~{{}z|}~{lz}iuixxv}{{{~[{~qwwr{~xw}i}{~yqzz}}{~yz}vr|n~~x}xv}}kz}|z~}{zvy|{{y}}~W{}x~w|y|{{}pyzi|~}~nx~ts~}ssqstwy{|rzzum{k|sz}xrj~ez}p{yy~w~x}xq~s}{}fpz||}~uv}}{tq}pwo|xx~zkxw~}~q]c~|sQ{wu{~hX|~rzyzw}vt|zt}ys}}y~~e}~zvo~uxz~|}}}u{|xu}w}~s~r~gx|v}twic|w|w}|u~owj~~mx~y|k}oyz{woj}yzvy~}ys|}_|~}{zxzyf{vx~dd~w}~zy~jhl||}|}y~~|z|tyjs}~ss|u{q{~rv^^v}yrdqzv~||}~us|{xxy}{s~||p~|~zyq}y{uir~u}~zyxq|~{z}~x~~z}{s}x}w{{{yzu{tznwn}sy{~~y~rvkuu}oww~~|xrxzzsj~yk|{x~z~}~su{}v|zwzr~zxv~~zxrycxv}u}du}ywu|ux|v~l|~|ws|{lr|}yt{x}{~}}t~{{~|zyz|~}y}|s}~|~tt|vyz}}{z{yztz|v}yz|~psx||xx~v~|xzpwu|}zt~yux~xh|~~}d{{wS}w|y~u}{{|}p}||z}vz}z~z}zzyvwx|y}{}~{p|xz|}|uy}o~{}~t|xzw~v}vzw~y{|x}|{luz}~|w}y|w~~yz|qyw}|wy}vv|xzuy~xyu|}{}}~uou}{~zu~zt|{y_{~z~^xg^}|}}}~|{bzy|~{~ywz~uzuzdl~zlzeZW\x{f~t|~xttTzw}y`}tyipem~{|{}|w}t|w}~{{|p~vyut|vj~{~z|x~wwq||jvx~{t~l}~}yz}~}vzzxw{xz}r}}~r||u|~~x}}~z{{w~||{~zz~|klz{}z|wt}z|yy}|~w}{}v|w~x{ytx}|y{x{x~x|~~xy~||cx~~x{tdm|xm|P~rpv~wuu{~q{z|qgauxf{xocnxc|{rqy{{x}xh}v~{}}{~|y|s~}tw}no{|uyoz}lswwx|~z~v~~y}x}io~z~}y}{}~k||ptvq|wq|}r{j}yw{~}uo}o~z|v||vmft|ku~ny}|gx}y}{y||~}}xz}~z{~|s}vtz|uq~p~xz~}}ywfy{uy|o~w~}vv~woqz~pz}{vyy}}|~m~{e}}~}|}~s|tx~yy{}z}}v~{vuzz~}~xv~|z}|}}r~w~yyzt|~v|}zy|{}v{x|t{}}}{ywxrmp\~mk|_x[~{|ysf{k~|~}~z}|~~tmx{v~{|n|{}~y}}wu}||}||yz{}z}~}{y{|}zyxytw|zy{z|}|v}y}|vy{w{z~~yzwt~~~u~{}~}~|~}}~~z}~y~~~|~t~}}}~zw~w{}{{{}t{x||{s}t}w}wqq{~~}}}ws}}}~t{|z}z|w~w~~||}}}~~x~}{whep~m||ow~o~r{dzs|z~vx}~flzxp}yvzy~usywopyx~{||qbzw{yn~vupz}y}||~~tyl{}zv~v{~zxz|{}}~~}~t~~}yv}~uu|bow{y~rnix~|u}}ryuf}|h~o}}~xyq}k^{zxys{~vxv|ux~{xv|e{qon}~upyr~x|x~}|~ss}o||~z~ytvkzs{~rry|y|{|k|xwu{vmcxzw}~fZh|yyx~|~]uovzpq|{}m|}|d}}}}v{{t~yv\}}rp~~|uov}|{{}|v|{x~{zr}|vvuzuz~ynlxu~}|{{~~|y~xyx|~x{~{}~z|~z|}~v{~xk~w{va|||{eyyuy|t|~}h~|}~}vtq}x~jysqs}y|~~`~z|x{q}}~||y||}ox}y~rsb{|~^~nmw~ywr~}~yzyhqtxykqzru|~zwiy{||||y||x{sxzpys|w~w}y{{uJ~{~{y}tt{h~xtz{~zkw~x|mn}|wh~tb~}R~s|}hƀ~s{xx{ł~|{k~}v~|]s|wwvuizxzlga?vRz}wUh~z}w~~}xxpt~~x~w}}ux|~~z{n|~~p{zyx~z|~{~z}~~|}y~~ww}~||~~~q}pq`n}e}v{^xv~wwzwm|dxv|woxmx|fs||sZj~|~}zxzb~xcz}}rzx~}t|~vzmv~q}y|h~{oum{xy}|vx}~~wzbs|p|w|uh~zyz|{{{}u~|}{|{~wzvy|r`|vzdqlq{}||~|~w}~|yu}|~se}}{~{~h|z|s_q~~j}m}s}wy{f~zvxf{x}}lvxxxx~y|pztto{o}ct{y|tzz]uquk^{}x~bw|zpvz~zt~|}x{|~y|wzu}y|x|z~|}yn|yqwp~}}yk~v}x{tqso~wvmz||~w~{m~ztxt~}|{z}lIzzzpu{wpu~u`Qz}~~{o~~zpouw}lt~{r}xyzorlq~qtn~~|zio}u}{||xu|ud|}qyz}}q{}q}}yry~{~uzzuxwzlx}|z|sa|~xwy~v}w~}m}ۈvr|{~t|xzwy~_}}|s{z{|~u~kbx~{~g{MXyil||px|r}a~{x~t}utej~Z_p^~{~{WwG|ʇ~qyr}~y|yz{ut~{}ym{~qx{y~w}~~z{q~~xjwly}yp~|}w}x|k~q|v}{~yxur}t~}z{|~{x{{~s|z}uW~ky~i}p}y|}|tx{ygwx~}}}wy{zlx{|}~z}}|yyz}}yvu}zx}}~{vtc|}~|wmz{|zyuqy|dzyvsm{ztvw~}z}{r{{m}w{~}~|zsv~{rz~w~}y|yzw{z|{`~|}ws{~}y}{y{o}jwx~{{~|~w}}|~x~xv}tu{u|~|i~~~~~}optzy~}w|u~}n~zy|}p|wzzx~{uw|xuvrwxrv|s~~z{p|xz}ty}ziyxw{x|zvv~xvw~~}}~yws~y}wguyzmvu}vZ}{~xx|~~wjqru~}w}}{yxzit{~{xwpsz}h|t}|~{}xxjg||t||||{~{~}}x{z}ow{~~zwix~urw~r|tvq~vsw||~~ywzxz|x}|~wz}dvzs}~}|tx|}~x}|{{zz{y|y}|{xfx`~|unzl}~~wv~wz~s~uvh{w}~z~ui{{|{tyz{s}}vvoy|u{zy~}r~hjx}x|lz|~{u{~vu~yoc|zty}~w~}{q|ne~}|ye`s|yow}}zz{w|zvy~|`swx|z{~~o~xw{~|}z}|tt}z||s|vs~yw|l~z}v{~y}~{~{}|}||x}yw}wou~{|{}{qs{xl|mT}{x{Lo{m}tf|ujqu{k|xqi_}o}Mhzu}}w~~jv}xly|qtz|y}s~wxhw~quv}|~y~~~~v}x~k|xtzxwnvtqw~{xk~{{z}}xud}oz~nuwypqy{hmz|trz{y|wwept}ho{z|zxt}onqoaosedo|osv]bfXzUgkqu\oniXhj{mttmsjkSomqtnreokrnpfsqgnnwl_|Qcklcpogsujf^q}xtqfpnpwbnapeuavoufscjsav\oneenorXgqln}w~}zwu_\rwwoxo{~}q}sx|p}mug}}}yxyk}n_k~nR~^}~wqQvgszYhO}~z}yp{yzz~zu~tuz}vu|~~z}~~}z^vzxvtrz{m}x|uy}wwyvt~sxuxx{}q{txy|~}vxvszy|xzx{~wzit{y|r{}}tt~rvuzxdy|ew}{~i}{v~{f~wr|zr~x{{z~vrp|l}x~tst{wt{o~zv}{xu{u}x~u|}cvswzoYzbqr|z~jVw|wsv~|X}~g}r~}~~m|`krp}r|yd}}}gy{sjpa|ojw{|w}lr~vw|zo{pystw}v~~bvr{w~~xl{tyc}~}z{wrqy}uwwe|z~yx|sw|bo{}y~}~}oumyqy}lshvyrm|xayh|{~ui{tys|~y|t{|muxp{~v||zrk}|||y}zvy~{~v}v~z~zyw~zzoz{x}z~~}nzzN~yk|~}yvxqxtqg~umR}~h|l}|}~}~vx~}~u{}}}~zr|}|ru}l\azv|q~sy}}t]mrxxvx\|}t{wUr}wz}{}|}~}{wt|~u|qz~{zr~sl~~y}~y~~~{|z{|z~~n}y}|mz~zx|qy{}lnz~}}ln}|y~z}x|}|}r{|~w||uxyuu{nxsnwuy|{||tmrsy{}vq|~~sy{uj|~}yzttyumivs~yxsxp{~}zv}}~}~|~|wzxz{uvz}z|~}}wz|~tt{voz|yz~uz~ozruswcpz~zu|}r~{{~yy{||{{}~}q|~|w~u~~~{~~|w~~~~pz}}{o{{w}zyq}yv~~p{}}}{|zzic^}||qz}a}yz|kz|~}~s~x|jub~~~zp{{{s}ftyz|f~sx}xy~{s}s~lk|}qxe~x|}z}zs||z}zu{|zpy{xo_tzypk}~w{{}|z}{}x~v{~{}x~|~c~{}}~~{ou|{ow{zq|fty~|}n{~z|xwspzx{usb{}~jrqwwmg}vzyly^ryytr{v.~ztwt||rtupN~~}uq}\wx|{a`Uwyywu~iu}q}z~~l~zt{|~ou{{k|z}}{}zb|~}~e{w|y~X}vu{|uVhp\{n\|i`{j@]lyVf}v~y|rywzx}~~mzw}zvjxyx^nrstnuueyx}}xtun{{x}}zy|~s{}v{t~{yz}vwqr{w|z|vwz}|}z||sx~ztx{}{o|y}~rvix~yxxmqy|wUvw|xyu}~~tvy~~uyvyq{yysjv{y~{x{~~yzuy~w}}~}wx~{[}pteqq~{_s{~|~uuyc}y~}ovmz~wvqi~|z]}n}zu}ruyr{q~^zxy}y~}}syx|~~}||x|z~y||xt{{z~}{}|}y~|vuh~tx}~~xsyzz|}~{}|~~}{{~y~x~|}zz|{|wzs|yhvx}hps~||xwnmxzyq}ywu|wC{uqqkr}p||tw~z||u{~v}zx~ezxr||u{~|svx{~zrodz|ywzxwy{z|xq~{~xLxqwz}v{|}~n|nyys~~x{~~}s|vqwxOvq}y~zx{rz~zy{|go|w{vw{vt{~~|Ylzt||zt~vwx{tt}|on{xu}xsx~w~}uvx~{h~you}}|ux{~w~}z~n~~xz|~z~jum{~z~}}g|u~z{iu{m{{}{}x{vtzz{wqt|}s||x}{s}{zzxx|~y{xy}}z~}{{s{tzx{y}}tt{|{y~y~p~~|yx~rpR~z}stw~~~~~~y~w{o~}~v~~{~{~v|~{w|{{zz~~x|~~vhxy~sx{l{vvz~}|w~{yx{|||}~v}u}yz{{ts{ur{u|~{|c|}owx|yyuu~k{}j}y~vpzy|e{~z|xw~d~|yx|w{r|}txys~~z}uz}xxub{y{~vw}|y~}zl~~||||}k~x|{|t|yz}tlu~|otxz{}||~yn|r}r~|x}}{~wgt}x}}zp|{|~io~{}v{wx~w|vmo}{hs}}~utc~szsq{uzyy|e|m|qzcypz}|uwuvxk}}|{xe:xsyswyoyztx~~ps~q{n|z}u~BrzIeirhwzvǁ}~y}izxs||uzl}|}zz~~{}~~u~{~w{yz}{vz|}m~|}x}v{ys~v}wz}{y|~o|x~|}yz}t~xv{}y{x{zc~ww}|jvvvz{fzowd}hskwjmkqqnogzjWesrvnero_[mRvnpljmttaodkmlphussqlolknr}uppijud^contnowlTlZoi]kpm{ccqqopm`zVlropglqspeipk~chmpl|relouqkori}qpo{ipoammo{hninTnmmmulsoimkvoinolkwsickok`FopoUnYgz{l^jasiqtnjQklrp[Zs{uvuesirkgglWktmprv|rxkssxmkcrwiUkz{rkQjzlkqZlxonrnptZhvmbsaimp`nhtitnlfmoRZllnhojte{l|zk}mymaspnin|kxorlrfnopyifpqgj{\nmkmxpkjn_miooopoophokqwslqihlzdirqa]ndp{pqgsiiqssfvqyokXenpzxuxjiynmyle_srrc`n}qh\pnintmsvqo`r}m_ppolpnrlpql{jfqnjpmonigospGq^kppkmskwkoon`k{qgo~d|lnh_umyik\iihmqjyigRkilmjd_qmmsmq}mllmeanpnkblenmrhyh_bgrnrslqhqHvsmpththplvmsl^ihNkoj~tur`nfnsmkn`pgkqSunqntrmmq~npZersioYntpmgski\wlwimoopkvkmzygdh|rophqphnkmg\{[undtnhvhjlkYofX^noplgoi[YjqqsluhYyboijldj~_rppVppmzijnloSkinj^ng`lko[mer]sjxbxdtZumopYniQnutsh`fKjlq|elinwmholkpenio`o^hQWttmoZjersoqnjqVY`xkktcmgeosyagrvsquTlqopqkcgirdkgc^nlitidnXtQpfnigrr`coucyvlfs]hdhjuslmwkybQshef\jjip|pdxh|ojkYnginzwrlap^gifinl]p\rvddubnknrjqghjvuusjrnVxmwvpnpruqjpik\ykXogsmWlq`rnhnpog_~wfoukgqnq`llbl]lwrxdner]zmnrjTswjjbrqngpHuodkfdoogwqolkiqsntsnPt{omZ_nhvnhloqgoiijjrapji|utr_ypnUnopf|}nlirawVkvWhtipoollllRem]njenuopvpcd`oim{_mUj^ivhsblmmsozmuredfkjnnnqnntalkldmmpqq[rotnolnomqppmo|\mursqkbpsvcpnmn}l^roWrsnokpnlimxqklmrvvpJolrqqLqrmbzmoqmspjkqlsofvrrznkeom|pFaqtimzinhjoSQmnUl^npkrwlimlutklnnmrmeru]irnoswp\lo}onsoQimc5bnqrmmmqnkolhlmivpinqtjmZoaovnnmoqukmne[fqsgjppedlmc{w`obmqhfokxmpcg~tmon[oyhhkjaqeqpQkfpqh~n_yeoyznlcmasjedca{i`mfpplxoq_gl]\nntcv[vttoqlpsfqmqcegyS_aXmovp\iwszkrhrwnjmirsncjHsk|qjnw\sgthnipmngipmjmZgoq^{ppnumqlW_tmeogtdjs^qftirgpps}jlng\gljciiodnbrpgxxrlxc{alws[ik_tqbm|npqg{phektkfgjshsiosiurkno\kqTpkomiplmojriphlxmnphulmndQsenjmkmnkhnrlrmllqNKkdrVmxlnlDqnRsfqmnhrozon|kz{qnmYrgqnoon\l^mejkphfcmmeokool{ilkghqkq{jdlmmnynTmkklmq[lnxjplRlibnomj}oihnn{nmnqnl^pgnNollvqnhp|RqsP{lqlmmyenqojmbp^Onniknk\jcolnmjgoeoinYlCkvqsokxvTlimMqth|mcnnhod\oqp`orkilor\lqonupnvyi?nqmiplrsnoYn~ykwpist{l`q~qomtmnOvbluknpqrmpmp~qw[qjnokphnJf`iophlTl{poqsm|irmlokkp[j`olfjmlomrnrwgxpo~k{qnoainniurjqquNnpjnrnSe_oUqpIks\pu^popnpDkEjnpoQposmjluiUyI}tr}pjxrhlSnpqlwqkkkpoyxmoynclokfEppud_q~nlnpyxpmvqdouct^r|kWnywiiotrcmgpfnjmv{tnQos^sertfim]ajhqql{sfpvtwojnwguVyokllp}mqUlzykmainotkihwoTtaz\czptirkqoanj{pnfymjbnyokwhvouqpyvlo`s}jTwdqnh_rlgdpnZRumq_aj`shoiqtred^qksd|zjxlrddZfe{Yi^txqknZmedu^mj|uzucmpg~gj^lrj]tZ~~p~Zntqnqukitflpoixhmqlumbuh{uqxsqloknlkqoklnqjk_hjanwivjnmlfklsfllkmixllepmpg`psgkbmozro|gjvnljgao|k\slgip}mgqjnmw|cmWtwciousoeqwzrhiqzjzipkuplaxfrhfenkhqei_brt[_klxmfsmjX\vhtjlnpvqmlqppqqnoroplmgfxi{tgntthj]tIhhvrmojfhnyteg^hvhnidckndmmiojjr~syrwjmohq|nkhkvjkpiohoksomlsocmmivssivoirWdpoomonpujjqpiunlrvVzbqqwuOexjoYodhqdpZkjlejjvpipvyu9ugmqnikkpifgrkgg}bnlsfiWnj_ghnYtbvlm}pybljconiqNfls]jhmvkqopgjtlukv~zbhmjcntrlwb~o\oqgnUotlsjmmjtf_dc}XnvjilodrjkoV_ut|ikpmjplro_oqqkqelyjok}hwo\trfujlV^ogeortxdcrjeuhqdlnsuhglgowgeplkPqkVtprdlptge~pnsxchanovot`ixltkyjahjPgujlpqi~jzqvlpupdXvkitmpsqmzpzos^mxnblfx`n\CTxnT_vexffnoeosnvqbjqwqsl[hj}qxornxqv{wloV>glsogqykimovcgU`ijkznntqmtqmn`sghzxp`vpoefrxlqsaZxpn{ohlf\qbcihrpdjtmfMimzvXydmkjt~jbkf{mlkZtom`wctlgji_xletmpc}bvsmfvlrp_ht{fmvxomnipnnhitqm|upbnhjthnsk~\|lnlswlsobsqmrkqrlfflvenvocysstinig_qytpcwqj`t_thslitdpugpa}tmqkvmnerynpYif`t\hounkwlmknrkokfmo]mgsog[kgevbjibtfs]sorqcmh^inyMlfrpssqmh~~rhohlUhrvmvpfplpsjuekjsnhtsjpwoivkcoozpytwjeqkklrleqsp2lmgYlhrfXil{osjn~wuhkqrpxZprmyhlmujronuqeOsl|VhfdhmjgrvYitYppqorrn`pVszkpqmlZDxuluyzYxirmqz|vkoirqUkhytwqkjnrUe|mmqgnmjkhmnrngnnfurpluqkprbfmkiqfjniipquqrkkl||nxlkptqnrp|ehv^7jbsppenooliismfkzjwmaoukhrGsnqr`pikronqfppqnnQsvrxfopolY{npj\isnQklpvknonrckoobpilqnjmplqnnkoOpick`QnZphr~nunqnRqZmnllnnqq|nI?sndO`mjnmmprjynjmnsouhtknnpovttqmhy_mmgncenjl|llnukosvhnmrNnQpnmolonolqhtmNkpsosoZpimik\nUxbmavpnqQnqfk_ooktmlmtlkqtsim]ogplqrm\osmkmqqimnonvtjfwjRkl~qhmoowsonrIuWrgij[vqmrXmmkrovqplomkrrloxo^jmppkheonrogkoXt{:tyaoZoImlmpunsnmqlvmppmmg`i^p.hujkosop\jbhjWqpknenqikmfnuvtfkKjaksk]k[sqhqvl_njjukhBGmnjnpll}plmnenlurfPNpmnkmllgwmelxm~@qvolqotpZ]onkVorekomvjQ_Xgvpwmhilmwjlmmsnhmtlpk{Xykkdmn.Zxqky{}htmosrorqsux{v`jrmolk{hyjMcsmboifpshtpxlqpjspxnTlq{hc}wwav`dsppsnknqnsnm[Uekya|putgjanpsgn_|F{trfrcm^jCn_mpggnie^oojfysfznr}cuqt~rfxomegkocwcivh_uhpnsn||xkpjouJmk}v~toMhv|oVnyw{apfhhnglZ}stlXuXdgogk}z`bbjyhvq]|`h~rwkeZgrHnwUetmvqeblicnTOvimu[gdapqeuocrrnhnacjjmpwwj|_poocUlhoclp|sp\ettXxrtu|drtz~ypIkIshmnvYlpOsmyvkk_\qrslejg|tzqdthYsbqilvg_jnrk`oiu|oiZ_vodxYhid^evYcglD~cutresgkVtfcYzTr~Rhngmpnlodrogu^mqhumo`nVsrhjWpohgmbjtwrqkmwtosodeZm_ltfomitKTnPk`jasbaLtDjpqZqNnghZZkknJmqyThrxixq|puqxvof=}hmxhfYOqhoyoaC_ftsobpisyhmrftijb_sdr|ejn_gqsgfu\nk^fhqlrfs}hg`rju]neg|njldrtSspnvaQhYpaqinqgkprwrYnwnRhninmZnrnZhnlpqowrmpopokomPkHmrmqimnmnk;_njon|kousmmmmmonxop_gimhmjlro@qVlpcq,hjohqlkjl_nFOlrcopjmfmoqsohlrdhhlllmlkUlml}moo1zqqprozqMqqopmmqilqgmpTUporinopeul\gmlxskkntkrgnfBhllmzQmntomymho}{dPkmconvnmlamlptrnkumnp|lvmsosmmtnmektodfnkoioeuupAropX~upntnwpJipmrqqsot`sfwmliqidjujolihpkmcqlfjWokbrsjSirptwfp~jl]pmpnHnxkckakfmnvolen|usgnqfsmehaidhk`ftfqlkjpejmpqqqhlzqoohmm]rsgzmixk|kmlobzreumkdsh_qgphqdpmdogkpvttbooAkljsssv`rljukiqnkikhtsthemydjpfjlVhompm]rhh}driiznwqmoenzomkz|ichhr`hkbjlkihkzW_vjmmnpj_o}jwlsgfoei`m{kronbjhbdm`vioekeonveyqpm]hkih_kt{timr\uogvnr`krlht^}koqy[y[lgsqjjifmrmkhrhmukoll|monbok`tqxlQrmdp[lbtihk]fujhuiklmrkljofmigwjgngptjXyjkfejptunklpzxeyjehlfqkXlhcnvdovmyiu_opehqqjhvhj]nogimpkojhjp}ranpupnelhmVtq{mttZs}[pojeurzs||}jnj{urzytwez`vp{suvplmvo||yyzfqtmgotmossrpg|z~vvW{naz_kzzym{xyz{vquWj~qx}{tnrudwq}tjzxslvwYyo`wwpz|wsfjrppkv~zckt|wryiuz|tozpzvj|efqyywi^ruceolq}fomzjzgnmyi|eosWaxqkor~vwnn}eswv`hngu~rokanlqeknztprvlptonbllgrkzrbXvuweqGoqlmrvukitcqmjnen}fntisnbt[ocngynesiXljX]gmpkkTvgg[rhotvjs`rp_f^scqrwgtrAleQoqkmjotpqasl`nf`olmp{FqwpvncyppnqyzqqxelmusogBYgukolgrs_kkmhoe^w|rl|qsmxiforldwxOonjuppxqujXtuwffb~s{pjnxTqtlnjSrply~to{ptxmmutwullmpnknnkwqmpfqupofk}xlpinqmpsslokoni^EmSumqmTupDglpxqmjgcn.y[nokproToo:tkeohKkpholnm}qZ{mqkt~otonlrutvhjowvqkRlM]mherqUqmlpmsYlumkhq~rqqnnswogtll@qinloqSwKl@om~n\_nkipnuvIqcFlpvqR\nmlllqrxoci]kfsopmko^oGlorgvpmymlno^mtnosokrlpnavndjjohkqqppm\[mhpulpipwpzmmqmUno@bfbnjnjonblnvLvnpp}mgqrenjSktoziTqnn}gklopr_qmrbq@`{hoksupmnuKnqlnkTjlliibqOhtrlhjloemqSmkivljitpjrnsamoigmYjh}knp}wmtqpp7pqogmjUqnkUxsmw}]hqmnkhlr\rrf`gkqPxnph_wPtkOboHilxpkpYnnimpirSlooq|qh_nzumgrqqe~lpNoLnombhqoamrkgmolubkfmbthfjqmmRmn_hvnqngclpjvoxpqmfpqnvklhktpojfmdgkeagqptkkgnmpkflackuoikvniiYwapq^w}p[nutqtskcg~jipsqolonjwriydpirkop|niicidk{Visnszokjhs7mhmekjiiql[onmkhmhkpyiknp_gmnsngklri]opwmhhrkkbshtwth^loljkkonkvtfphdwolksvhcnzvljkihlqn|nyximfl\lw\|pqemipg}vVunmrnhqjTstk{dlohoYsnunprnqjkmofgrm_rxooqo^rainpwmmkolsesmemjrXoohbmhm{sour{l\t^XtospkkwktkgQgqiqnlevi_rLWrh|hoimysmjo~]nkufqjlommf^t{vl|Sqvp5djgoaillapbl]5niqpffs}unnjodnf{YlmswtqtqkI^geot`gs\vksm[rbTtmiry~qhositntslssoqglr|\mmpo6ovimkmnpykinjrmxootlnyo`nimrrwtnkncoXnoanmOds=i^mnxq_toqjfonnoqsnhaqskwbfTm_npilkrqmg~umokkpopokupsljkyxqlrm`nqlHn}mmbnmjKhnnpvosummndlkndpmm|ooskrmjqoXuihmG~Qmlopnjwn_oqjBmnLmnip~dngY\uroqgnnglullrimnmppolWywlYlworrn;mnnb{ejysTim`iwsmntwmfdqpp\eqkjwxn^llktlpuiqs_qbrgtloWovihetskojkgrwnihsgl|gjpfwjxniqoprkphoquxfeqngercwogrbmkooYpnvlrqpowldoqihBhsohnkxzphjdlqopRjmwkMYmng}\vq`}k9mjjq\kpukgvqsjpl_namq]mgav`rnpmzn~rcnhs7m{ztlbsrl_vfovqhj]ikrwsdglkrz^[oh}aeelnlqsrajzqpjuohhptmkiior_o~khohnqmms]nqtt|Xqqoro{grxssqkpjj[xgoumpl\nmzisqqpsisirmQtkMoqvsilbqhvkgkr{uooewpegaoqqsoowpqhhkfZnnmksvrZm\fp`\wcotlptlouro_uftjq]qmytdswleihxtppogdq_mesokqjgklwvpf{jntpbavuSdiejrqjnnqodtm]reywv`rfp~luj`i_lwlw\obrsjnjuoihpwljqoqexelclngwhofm~ovzoqWkxkjs^uoftqXfpmlevso]xjje]ngttaronth}qobpqsnfqnOh^jnkunhpnzmop]ronxcconmmdXmtpomqBplw|sYlrqxvnrpkeZmqs{bqph`s|axoqgcXvmimttjcnewsjprqinJ`qlZdfqpjlfbg{nvijqlLmkhmosjyfveoi}wstoZfjebk,qhztqowjiz}rkqbr\ljmvljaltqsQslhy^isj`lvstnkujfbm~wvmwqnwqutqrbfqwnjmwkovgXfWzgeuneuqqw`dqcsh{osgiwfolmqnokoplmmkpj|rja~opoimh`koajd_jmniXgxlpby\ljd`efdmroWgqrkommsvsuhuntpsgndlnidbmomfzduljZvaplgo|herskclltjhhpqllmvpn`llqhl{}jsptgkf`\sqgocplstjpqVlllzhmrdmpqmk^kqgqfjhrcwsbrjmsytfrsfqhshp]bbtmot^[uoW|dngoecrienVdSi}[oh]meopcztqzvxvjszomifl}sxliphksSsvSejlcprjtptyVidrmmkunbT{pi_jptj^TpfsljpdzXyxVVnfgjliopnvjcblosqfklvjmlptugldumUf^xpfMxiufmypetZbdVlinliWqc`jfppoywiukpfaZdovimhhnTydbvxrbgsohxhmYxsZehmuldgrl\q|qfwptgfc_osackhj}dpsavsvrYyfusopcdqmfgf`qsjuqshm~dlnbjmjjqolignrhjp`~i~jqkwvOnUnhl`plv^oliotmSofts|tj\~mocilmkore~fh}mrkfkn]bljrodlconOc}-mzf^jlpafmojxrmqq^{xnloookqwllzmvcpggTkhi]lhveomtduSs7]RmnqqtsiVt|YUnonspnk>koflwa[cizqjwsnhjVrphowgkwhlo@bqafqwSoo]dnn^jolnxnZjgmlopzpkq~mlrmynsjsjkrf\fljjafupk[uIm=isjn[hlbsqfknynTknn`lx^jQgejqqpfjl}ko[tmtgnph^up`pso^qzn|WHomxXi_atscYeqnkrp`nNjlbljtrmmnnoz\okkrrmqmlqpspvVyekui{mwpujjoqeklmpmn[kysolslikwojnjwofceSlnWffiQKp|qsoprlkpllDoenC`nukoznLzonrrdokvlkqqs`us|eolkmzoc}lnpb{hyivjghg{jesopopfial_o_~psmprrwquockp~|zgV{ktsvp{plksfNrkiiuoka`mmtkzNspowjpstvaon\lzwxh\nler`lylzooklljmj~ps]vrirakl\go`kygkzsqsohwpvcmtjs{ytt{mdu{kuklyngntstjicpboikkommjsjtvjHuZsehwncq~asukdxtjllbngscdgedp\mjnnvqfgcfsmi]shfcmrpaYdiqdn]uwdwaiskibSm|^heqXpqmtSKxlpdi\jfj]gf]aDvsfgqmtSgflfp~gre^dj[pbr|snozgklovg]pmilmlib\c|ngmW^gbtzrnNykpViXorbjtf^mjjUfm|`lujoegfLp\cip^k^opdmispZw^shzhWfpmfoq{lpo}gww]fgmuk^rOncqwqphvjmhqrsdhgnqeRa`vghcfl~|zLYapdrsmpkwjWrniokonlrmd\qjmxt\glgduixUqHhnqpmCpjnNkknWreo^rnjqdoonllgmrtqjnoonnxnobnmrakOqolqlyilo{s_kppipovogelinu_uakmmpoipi]j\egnpw^jlmmmun}vqorr`pnaorqqprmonkfp\ionxjrojomjiuyomllmhlrroojtl]osntxjnTHqunljmXdg|spnhlbkqurltmjiSp]\ktroijojulmnriom^pmq2}pxocklnmuNlno\Znl|itgpoeojksmlhoqftvnglqY|z'ulkpllpdygpoxblsptkr\Ypmrsooa}rmsmpspiqlqsdspelgmdbtIkorrtoqfmjpilovttfsmjwfSn>nm`vqjxsrYmm=sopkliomqinep9qpvJhlvpjhmhs_stgX`soq^nljsskRz}v\opksnrcrmoljgnqmu^iouwsjqihojbtiiRXijoqnpbq%kOiomymlirotq`mgruexmqqiintnvnwpgsmrugrkSnnphdiptpjoo_ilxxg\r]mgKrkhloqkdglmhgefjjlrr`aohotukmhp\k{nqsogpkpkqoTklqa|{Xrqk^onmnkkvjivmvdsikqvswpbsc4jpqum|tr`rohekakocppsasynlR[hiookqq$j\k_mlernoamqhwmpfiMgcoxppcm~qgmqswknkYvkmlumtebnlqqPrZulqhpkqujsrhhmafnsjk{2momktc]lpSljhpgohc\ol`slnplrqhrho_ztmql^eljoko|mgp`btzmphrkpcnbXhvxl_clorjkRljeluum\jqepmj~oimjwrec|Zuii_hndqnwlonu_lpt{n_pSv|kojjtxmg\yqfae{{gs^tlitsnpidnyqgjinoypiokklmgtovulho`Snpkgyekomhxnc|qxpmlodhmpkrbpppb[ivoYtossqlpjtpjmramnqgnqgsmhb_Xkhhfjnrqhgr^jstyqan}npqloqcrlmyowqhmhYvmnn]oinSsntVkkomsmqrbpmfixnmlkmmjono^qjVjppnaflwUk?pyopmmmo_telrmrnq\ow@pVjphetcltnlrossyqom{ksnotmt`vejLnknjrp]vkkjonflnmoqm6c{lpgnmpyhmhopregkptompmnnnsRnkKmqmeDollpqoW}dMmomo]]nnujljlakaa|0frbnhlmojmnnookqljppsn_spglol>kkw~Zn\pLeOymrkz~oiscqppisnopvouevnnVnj`jojmsnumnlW~m}btjpQpeiJjrptpkozfnkmqnoqkiagk_dt^cXproliorjqlfdZisqfscxliueo:fqmp_wdhzl{klpj}hu]klpiqafqo`tgmhktxmmo\dtfjmmhrrordimtdrojgnqprXupoumjjZN}smsygqmiipgvqpz~]v~dueyqkgkisriomjVolnmjpPikrgtgWsrxjgOmv_yidnqlmoicsgtyaUw~psV}~stumrllfe\~erehoerjXkuUkdkq[nqhtpc\rwpckntithpjmhoir:pqZojlNpyWtzgtWfo`x^jOmivNeapgysn{up|osZQfYplukmosj?urkVfwmiwfnsnlc_ycmQdalqjYqgiqdhfs|ijoqmsepl}ikcsrh3rxvko}[llfYlnfozlZgvqjjmmkmirylLjsojpekixbvilvk_hnDrqcmjpVlimlpmo@lmzlfokYlekbsoietl{ldgiilKrkp]yqgr`kxhkhijtmxn~nlpwnw\dj{ioXon}kLqPslrxhipt_rvlgBngsziphfqrk^patnnejqubgur{ryRrqqlR\tn}cripodsq}zmSsrpftmvmmlhpsralbtsormhqgtwpmsdjcZ[[lOym{nrw]ulfiszWu?lqp[vhvJrjrrjbg{|fvnokotmwbqkrkkrmalkqcekmhtqolrpgtftfo|~sujmmqiko;eswqjinjrkklzkM^np@Nl|mplmrosqmmyqgposkjkw`lm4nrmHmo{hnopkoijloawl_b|{imokkpoZpoZmlnok;nvqpqsraznn_mrapgmoxkrlknxrphpopRLpoq~nlvor}mhrikutlkquGqkppip{hpWdmwoWKmQnmllZstnkqpq|jmnurltmak=tto_pemmtlpwramnpolommolk~cypmn{jn@]Pngv{bpal\glsog\zlkpPnfpJsyqknsfoi_wn]ou`lyipxt^pprysf{wva_^Lpdk[tpsdo_kn~{rzusmi_j]fiRsii`nirpkpq}sYj`{iFqnm|Pnmfisgji}mgydzYujprtVmjqgnmemYmlpioaonfhuwmh_xfwj~hdtoZ`tjxtpj~ZfoVqnhkwqqunnhmzulXoqf|\njbru}r_dmj{nrluifpnnqjjkdqvaklrglvusfnk}wkpdogzno|ikxgdqukmlrk[kkqoqoenqumvXknVwiUokmpmjsnnl\Rmvnmsslfodnop?owpfooOnklmpnmOjrfnpegspmnmnngmypOgnrlb[kknkmpnwWpnitsmpUlpmli_oeflronjoZpenlnmq'qp~qomdrlknmpsanokmgoZ~SmcaknwblnnioktqIjkslxulm~gpknrqc|trssmpmmfm^prnqmlkzpllRVrilo]ojTWUmjebKqipAunmnjekawdrmjnklnnqi{hphhgNoekjqf]omsfvm}stRsqmqMUgkonbeonXomlpkrmoTpsopfnf^kUfgplnltsorywLvumlqvsqikqqqJ~jon?fqfminmdllogan]hujmqqikppadtrkieniqtmkavislzllohnn[TjfoEntfpqoqnrph]nadqlpmpxpnCmmtmkn~hd}kwhqtjno}qtnfongmknV\]mjcfXlstZjlrin[k_slqqnnH[lpmTknjkqhnommnlqpWsmqqonsjqqonosmduokpHevqmkml_nswobUlrlqnmQnbl~Sni[xjowlgnno}dpluZgnknvjnmlvr}nporlphmk{kVojnqpNppaqluS{nodm@oXqpxpkl|pmmjkqLwmmpmpng^mknqlSoxvXgnpvbm~eqkqnmoppkwnTkx|qodmplmqkmunlptkpnaponzuftsqmlmMVFnnpobTlumlkimqnntjdkkm`pkmblkgmg]lnT\rInspqklzsnvvlolgjvhCimQpimrnsnhjlgkqimklqRkdanOhivnnpnlhll\htjmmnxmktnroovtopoinottjgwmslumbsowppnUW:so{rtnmrdroonhnwmmnGpllipkprnXxmPlism}inpltmoqGpiowpkonlrqv3Sv}mqshmmgmmomokmlonnp_ril{mchqZCml{r_Ut_njirniostlnqQlotLmnpcokwkzqnoR~nzmnnnplppomR=khlrtFhalhqvlumcnntrlpnhijpImrPswdsXoxjgppinhGjwp]xnolrplkqmtnrfxlkWpjqpooo|pmooTnq}qor]xtplokzo{mmlpnnchmoromlnpomo^umGepwm_falUrmodjFsonmrjodMmnenkroipTM~OnVrokljxnlnlopnpm~plpBuWnmqnoj^Q|nmo{m|kfnglo`nlsgjxognia|jdpvdfjmsmmmqslmg}Z[laghjqZ]pdrnf_fqjnlqghynq\dyqjvldpWgvThjcwieepg]pp`X_o{n{vfvqdp_elvmv`mlhao^x\tqubdfjnamzxmndk_foltovo{ixpkZmvhhfhvhdjnein{ee_imljrlmuekisolZlerui{`wggik_u]qtqdqnuo{d_rXZfsZ_jwklfmdctSlpgo^nildwlglVlpgfole}jNdgpnl}ihriqojyotoknpnpjpqnbvotnkmmqqnomogOqdvktnnsqMlenEpkk`pZxWkklmpi~m(rqko]oekynkpokbohrukupsmmiorrofipXqcojlvmHxjmmVienionnplfontqotstpXojl|qoffmmylolkqpWoownTmpnlnnkkkn^nlrz~lmkmrnqRV~xnkhwliqmilqojnlnmm_qjmI}ssorpPonLorqkfVQbomou|mgtwqgiqflm_Znp|r`qit`ieuJkm~jhtywtZu`dqtltommesppvnyfgqlmQwmlQij`hnr_slxpidqiuljTc`roqpizhob|gMP\wpkojasqmlhor~kqkv}rnk?mnzrnf}vkslUng}flinyrmwjhknpfz~stnapjwgvkpm`kmbFgiqkpmu_tkhdTvx7pqpunlm[ujSumml[rCTatznjrmcnhZpolaphefljh{{hojnlhtkdigpskoehqxmelCoOtdtrrqnZpm{m`logghkkNgrXv``nbopbqjpmdippjtJpolu]mlqklpgqpntpausslqzbo|duxqmgb}OrsosY\mqwftnqYkpWdsemlaloqvrg`pY|ahlromtksqyvp`[xyhYu^qmk{pdijnrpqhq_kpzsnSopj^_spbug`\grpvqguqBalionqsqZklawX_qotUpuoip`rwYVpdot\myrfkrxocrzpidn|ruvlqqq^unvmjomrhomnckptnvTpmUdk~nknlgmoqntmhlUojep7tPunn>l}mScnpjmlpoqokomqYzihokmhmo_mhzrmonfkkipntmuXuqn]slYqopoQemtjsq]hmkhome~fndo{lupqqnlnltshorjZnmpporZmngq0n~RlZrpkjNkmDrmpq\Mllshkmo|nPF)tonounk_nklongolklnoVP\xldjpk|sttrkjtnsqpknnnvdok`rqgsrzZbnuoshlodgZvspmueyerbkrtofy_bulooswrlsbpproXopfqmowgmrt]urawnonsmkyjathm^vmuihteg{Fpvqofru^ztnjru\ptf|nthpTlonllWotfohqpgottsgs{woasv{jkm]fhqjpmcfppwpomkoqlhlkjihWpgxpoodq}nqsrvk~jjyxnrnismnYzgxpf{km|pfmntsVpjkte[ssjhvjnrlpnslvjmnmbommmzxmmrpnmlSlukmso~q}Rnlnqblnlpuosglst{njuqmtpeovjkqmorlli^qrppjnbmbnyDszw]gstptlno]tyjoalojhWqppqmopm\sonwmm~lnjmJsnookmknncqnnT_oqnnnwml}jqnpppeqql\loronm~Wm\rqonpiZmtkmroXrq\`qomolnrmnkl\n^qnyq`nmxnjllpmmqnpj~moojgllnllqOipncxg\k{t[m\nsml~dlapqoikkmjlwkypmrmmpmnokkfooq|njcqsLgrqpy\mvj^nnimtmxsjmnkvkkxnyqm`okxbnloonmovkZmpllmtuimqnprml`lqrGet[pjwnycqjqJmTgn{rqm`BkmooiwoOjmgsmktngmrjjupjnniprhXkt}opk|\oqmjnmmn_neErqonpqmmrkmtirinmSmalkiolklunhmnmpkpm{oknbptlxltmlyyPpqrdQuYn^pnfinqZtkm]rpxcpioWkhzpgynnZunamnpufnjmmpmjpqkoikFfrbqlqsmfkbiluykgmlppdqgqMvpmpYVg8mfjhvnRw{jmjktnshujprlgcokrUn{vrevrjosmldpxmsYlmiMAtkliorwntmdnwnbrmng{nsnkms_rl_ontZUsnnoks~lx}mspfykrmknlng__PzpasoijkvjxnmoiusoYplmp~Z|njidpkjV{qlhvzjwsqsohxponquvoiopemurqmuYkmogmoknptqrzqqceniqjmps]qknkfobqgslppiiSisotklr\mhmmlkqpq\}nlruptokbhrsaponklZwQhsfmiknmbmgn^ur^mopxhmsmlsxdqlrpskjpqiqYsxturyqop||mkOpievopkiqjdtlighcorkbmmgmsrspwkmllkjaSjmkunqzqpr[nFpmtnrnowgjcnlsmsmmsulqsvg\ligjnbsqkplepjqkioqwn[npo~^iziTiejp^Rqiagiuhkq{gnmlulomobiopflkonlmmroion_onjpmmokolpr-ioot|mtiqcon_nhkn_pOpolsrnzmDkZVp\ogeuNqlmqqapuj}klkpintsployXlonjqsqkqnw}pulqQrolknipkpTjhjwlprmlolnqnook}=ospoou]zm^mlqsJ~roPpmlpaseeiopqoxmoojfmphFjYoo`qmkimnbnrpnhlq~omnlbkqirkeoqfTooohioVsfkbqnmmrcptqXppkynilrifshtnotkPpoophmrplpvYrftooZxjtOpynxlvmsmwlpnmmnqwnuoPhoidjglloomsi{o[llfq{pljqlpnXTxpknmArq^lcWlfoXoPqnFhloGsodnpkoonzmjmixlmqpkpmmlqm_n}mrXldok}cm^mmlqcpoglmjWGkpvmmoo|cuUgim]mnoqn~plpkjqhmo^nmoUoLqYmgnj}gnmokw]qk`j}niunofhtcajsn{lklaZqdclxqokngt^n]ypp`e\kQhuQmn_tto^qhrsilps\m|mnppfmn^|fthmmmm\doon[vgYjhu|usmjqNxPh}Rwmaodlni[nk[olYRlupileOpjlSylbmanmgvibrbhx^yu^gtjcejeLklslo"Y]tsr\fkxmgmuncslwvmnmpnhlgneoscrwxobgekihmomeWhrvrPfk]qvlo^ncpbigtt_oSojmpqlQ{nnqspopwitvgmkwptvisjktjqplifkLenrzlygopmjfukokiZofsnvRgGYz|p{pQjm{pYVtmrmsqj{noho~_JtifgxosqlxInlkso`hmpii~jsBUk_ljTdmhar~urrgluhvgtox{t_lolbhvlsvqigpVhlpjklXp{mvyp`Jaonplyeclwrnvnria6chtltkeqUkbtrnW|uhQomtir_vqcrknnoxx|o^lsk`_ebujsjykmfR_hjuorneikproiyogyilssgoc`jlovojnptq|qpmujkqposhrniWqvls_nknpjjiupofgqatolfjmfgeplrgqnrmjsUl^pWozhqqbhqeoorjprsiutfdwqlsU{krijg{jppelpmezhnrnopngmvmhguJnoljk[yqheslwhldmtngqixnktlcelkftnitrhucnlqnfgiqmm|[tpmlkmrgvtm~eaoobkgkrmylgjjnne{ifitomskgnojfjkkemgkpomlxlkr`nph}lcnDmntngqotOonkslfqjpnqumVtqXnpf{qt\mpm{wmfsUrllhvrpcqppp_4prowlmrElB|ymnqo]konnpuqopsinma]rrli|oolpnZlk5jqk_TNmnhjo\okXopklsnsopj^Xphkqrv^qlkmZldi`rBnqpllZjnnnggysjk\rpmpqg:lq|vmsmpownlpomijofnunzjukjeknqohgto}o]UpeoYp`srlnnrjspQnmeTklozukmqonmdgmlqlilrnmmqvmjpnchtxhtlqpwqgmn_qLipllpmYk{dkgnbP]m[jrsrrfHqgQllmikqgksfoasnmKlrclnknh~kkgzmenoUnlpP_topnynsfk[opojtqsuqk6oqmnloiQFanplnm[lnknmpKaluqnq`xkqrlninonlwUtzqloonokcploopilmlmomx}cldqldoobwenku{uq{q~mk{iinyku`nqmttoalSuspiwgpqeyax{|tbjqktlblborglx_neqpqpauvkwXiwgbaqcio]vqzeiqqmoqahw\njessgifoopuowdrsqwjo^onTmlxpikdmo\neWogkt_ltinuppo|lv[ritcn]rjioisi^{WrpogomanRzongsncnpkavkkRz{qsa}jy]t`k]tlnkr]nin}dvom{rzvndpfpqTlttrimorttnpprlutsqqpnpcftti^qhxibrhtou\lwxp_kwdykligkyhzvtcsnk^kn[Xjrdv]grkjxvppqqppUrYtqrhpuufzjileovy_{raedi{u\sszqwl^lmkp_lxjm]m\sggpemcbydfZkenLnljdrjteYYmbjpxrvuk{]ynohX`upvpufyooesjmlqibgaolaolk_bnqprlpwvppnn~xo^`mlQ_otewXelkdngkj[mzyzmtbJnr|^iqxibSiehidrlrincryrthmpocljjslqmnjmumdpdo^lzkGvkltlzoilltnw]q{oq\igrmmikeoevrxn~iforhudooWklpkqmrmWsrmbksem}nostzQ7cog{ork{njmngovlrvvylivnrnxdwoqjjmkrojpkyofrpfzvpkmimnrnvpgylnliig_p]skqYogivmfmnmol6qporkkpxRtZnrokmeqv^xr\pij^~lpslmh|nn_onmoiid|{mupltqlqimvprhdooqj^gpiiPohehjcnkqgqom{phlqkul`pojolrnnppmikqkorlnipgknoqvnjZnq\jsfgjnoonjqqmeknimujoegsjpoxhkmgppmmlurilnhlrjhokcmcotlnpolqnnmmqqhlqdmjlnnmelhhkkn`khk`mpnbijlsuleojodnorpepnrokpzknlklqlmfemmpld|ocmmhrarrlhnpocpgjpumvlzjqhrrppqym^ikfpjikpgiqmpkmkpilogjtkkmnqlpioomlSmlkm`emno_vuopmosqrrnslniaqowfEtvwHkoTppm[kn`p|minsilrmnhtcn|v`lsnrihoKjnxkonlzrknqriphflmt^gwflylplnp}nmhcrrpvpcnslBmspqppigo{jxlglrrpqlwvfiWyrpodlZkginnnhgnoolnmvoomropoih`lcdlhtsmrno]nqnmspojk}pnn[sgjeo_kwfXcki_lUrodsMo=npomlppzllkiokpinnkrqlmonojoknkkvlhrmri]mtvkhnQmc}mlm_lmcqmgs~ipmkpnmtHigrsg}~arzkmkoqRokirnikqinlkmmnotpmhkpjim{gomk_lvhnMnlmknEkVoKjhjljoqsn}jpq]cngsmnkalninkjnyjnojnjlovokqmn5jniqgyl~jlvwsooGpmionpo_kmnpnmnojlnZkntmXoQpoh8npmpwj\nhlhhntlhxjnrOqqlpUmqohnooo|spjqh,kqfrkmojmnXxkwmnsmlmin\o[kYni|lqoaxnnsqo`qmokmriHhlCamlYq\mXkmmjoktkppnkhtnpllmmrmjkeffrio{rnwl}qroruioholmjrfipYpmdmozx{ykhqdrvqkskXelrmknnn`sropsljmQvpm`do`noijkoikmio_o_opel]tork`mbopmxrp}tUkolwkhmuly_nouomcnlrunzmfpyomrqiulmnwp[rqjlvmX6jlxoi`nlpq}fjnqpSzbkpgjtjPkjZrknlmxskmkbknmspmm^opkJr^oddtOwopmgbsg|clptPlnOoo{m}fxMolnYlovmnthymlksozv~nnkvkuthvgkspzdqiepdEkqlQomn[jqsljjho~qrhziiVpnstskonsoTpfhudhaixnl\k^xndlskvmhoZkSt`sefo}opvsdhiin`imauqlolnZhkkkhnhihg_t]hb|CardfshspcTokzaoNnnpbbnsh`zswkknpplkrpofsmmpdejelkn]lmnrxihVpgnokcmlknjwyl\ijqDgpijikpSnoknHk|{Mzjmigpujyw[lsnlccunqnqpnsxlsjslmnshpetlphY}qinselniglYfnmopuvqmrslOqtN~pnr_ookumntlr}opfdmojwdWeVjzdld`oxxqmxulpgowglp`tcldqujhrkpdjhpl^kTszpfbjj^~Nc}novlmknrunjvmyaZokneclpmvvrrhjnkptjjwmo]tfgahzklimXbbnpd{uefinhtgmplwtifpligSXrpqqgiknksjsirhiitknmqyxSulhYjtkqwmYqmrrjmu`coplcqp|nlmpsu_rsrposhfjmltspcehfmjinoeyfkowc\umpokjpwnusmlutkrmnkmxltiptrhipqlfnwovnxopjmrvvibepdpiofqcpjuorooyy{wrvophnfkrzujwmfo`{pmjtsyjiqiptjlmgonornsvhbyfqvrlhrrsmlqnxfyqufqtollkluvw\ktmkilntlxlnomklhmnihipve|olnsihkprgciqrentjkrouviyqjuo^okssrjmoqqmjsgrto{tbtrhlsp`jt{vqltvhiod`dZvxohq{iisaydm_uaspmkokjnlfTkpatfWkUxjnRdwrqsmc_umghmxlmzhlwj^kilovvhailkshqkxpf`]jmt_kqxqiimijkrf__s}qbitlpUjllmogmqptor]agvdoqkdollmmzrqeaxpnrmhkgeO|Xr{frkiwzciNqllwcakp|oqqrlhop~or{tpt|ldnpipoynhljnkufkicjtjnVk{mcnoeswjosovztlikcooqqjolioqbqownrZD{iovssmYeKo|dobRpkRgkslnvyoj\onpqk}lalgxmwvvml_mktSthchkuglfjzqnhijrqmVuhispck[u[jeqhq_i\fyrhyljoZuZkusrdrwspvxpupVq^ximnkxxiiwacqfakomaqoplqgqcpmdQUrq{bbglkbu]j]urmtvnjqpzctml^krqrbyy]qmilll{potuqspanjimZkmasZmbmfhTn`Jkcnplhsgbqk]plpjv[mmflfkposlsJqciutyaqZpmbqmfyshoj]WjtheQmT|iqurbtskpjhqumhm`wsllwaae[sspjuxnd%lpmo_mtoWjrQykzjjin^cnkjkmmbspposeiytlmXophj^jxl|mnlessvptktaoreRflqOmhoEqtvlktipsiWHs[WrUiwoqq{i^hopvnpWtulxmx}n\ntljkl]ylkghhoyqtcjuqwlpqSsuzhphsw`Tl|OSgkfiqeq`t@j{m]hgnmfoMomppfkiv]nunmGivmjxsmraVzlssopl=ikjnL_rqpycpthu{lnsqpvkdjrmumgdiemgnmojfFsgufmqop:i|dzIrkPd}fqs}lYr[MmwppjFpk|foenopyhrgmilhhbkiylouoysgkXpmnNglolp~hsrfijijnrildg|tRe|nzqtmijpqoyndpqgplpfpqkownrn~ebiqsfljssVfmtm\lhgpi_tuvkkrqzXxwn^qyhlrrfoix_kvyUiqhijyqtmsojjWm_moslkqhqjzu`rjZqnfkhghnhoh_llzoxqqnaqetlupuuoimZypiltoouwbqqssumsOfg_rhrrqsrfgZf~lmfvboimoojjTrsqxoPnyqrlcroieiosqfm~jnhsmkjlNlnqanoljjpo|krvllannWoTojmjloqmnqk{kbqqqKBoYnTo\oapztmw~pkisplejfqzWkULlhenplknjjmZ~rqhnonpqomr^ztmkobppkmolohj~mompoqbonuqwogkpLgnnilkmtjmwnmlksq`ylvmMnnOniqonky|q~GzmolXpoojfmlt^flap`oq\pmvpl[kdpqpwloixopmkswltpll7SenspwPnm]r[qnb`iionShlq_j{{hopukRdqtfs`kphnmg)^hwc_pyfpYcQgrkor]emdnhrnrfiqcs\{|jlogehnluusqjph]prhj`eoIupoTmh_{|iVfa~amurrgsknnopocnlghbrmqluoOwroorgmn"nkn_kjluzTlg]zrrjj/whnwipko`skontqvtqnmihomdip|j^aovhnzrlFfkgq]pjp`rrqoposn[gslisljinhrpstcnish~fMxyhdOnipelsqe^kqqo|ookpmj{nhnbillklppoQsmlqplijpooqyquojpoXildnn{oqofloBnrlmmomtkY4oN]ll=Xigkromn@oSoaWnnplmmjminkh]rpnm]qpplpdnpjounomilolGmmnocolnljpmmuoglmlos`piqlmnc{qo_oboZg|punonqgpkpejlm|qln`onhnxsv`lam`orimnongmnorlolfnlnd{kynjrYhalpwrsolWppupljwss_ieqpdpuZrhyrcmhpjohmhroxrqjcdpn]cnnxd_fpo]`eqooyllm`qorfpwnpxsn`nyldklbnhgith^{lqkgo]cdlqektjcqld\ssjmevrdplxqxqjiniwkyojprsmympelssjkbilq{jqjziqgqjhpntikneohqeflgtfetppllsiyroyihqmurkwy{znnkhsxkbrtqhjndkvnvgpcirmhk|rjmbp_nrtonnrpdhbgglofkmopxnnxwnjdhmegvmkwi_jnoiuqzokqkinpjoouNs\ttWlx.u`rtnHndivnokfimnuipVlWp~sP|>ppkpoirTrgyfhtqf:gjpqktsy]otom9jj[kupquiTmurnVpnmj7tonnGnvon\npiprsxloposnqosvom]ikRohndmror[fqmlmikkjpjopkblxzs`nulnmnnmqnopxmnllonL\jlkxmkjkmktWkqguxcnmk|pmlkmliqjcqlscxmo\nujrr{kZpsnocpnnrpksktr~iosir`qllmjmmnz_novy|njiyissmltomVqpXrpovk~wp^vVljrmonqisVkoxzrkqnoovpq`jfhfmksp^oqnessjygn|fu_uhssroitcongn~mj`uspeoosungkvvtkjnleonss^rpppjhoephqjogmpvoeqyhinxknpylzcpgplsloggamkrvqnr|rllYnunajq[qpniolegmupqqk]mo}ugm|kpikrapmofpknpj^olu_wmlTtrpcEkul]oopm[khgtdjaplSsztpfrkgpaituioVk`lqxgrfusimseg_kv^diqn`nFZvq{qzjc`cmq}Ofj{7g[|uinnn\knWnpUks_]nlutOqmpugpoptmqstnz\qleiSbYhg\gjnodkmhUjqun_t^vmpho~pgqQtnlvfdLmhpnSug_fenfigmzjig|o_jjclyxg[tryvp|mtilhqmiXnjYjokhoOnrgnrjcnkmhazdrlnntAkgpgmSnmkbkbksqm_ju]lAplTlqYnhSrmpkgrbkp}tim]rfljgrqu]hmlo]uirnomnpoiol^ikgq{npjyio~[qfwVhenhmmhsbpvopafsgnlqn{keomipnckrqhonhqksgvpiXsvyxkdrbqhfxsktvfrqojolnftslUrnhTgnqbnmefwmopajmwYvodkqstldlqi\jZkgkitzmdmhpcdsqYorkink[vxjrlnosvkanrkkk{pqiltmerj]tkrlonn{wnkooqolowjkvissp}pekojlx`lumren_bqctgl^pYlmrljnrrxgqwnmgfj[tnovcrlmwg{qmmzofjnsokmbi^^htnmmnkioosiiwmksumplpeylamtfmlsil`pqhsrqqnkhomsoqnhbsmigloijkkgphpeuulytnyhlengmrtgjoninszpmn`ktgqm^pwfftnkogcnhmrlimornglxaosljonnlxjjjrjjkmryrkibhlpjbjmqqg{h`gots\bsplpdoqppXmxoxudlkqqdtinrdoqirfcrtqlrjzlotewouyuperkjompr_tmnjfiidWr\qerom{kmjkvufqiyoexwhsewgjridiumnapmmoi\sorjaarqhnotlgozpgcuksajVboqgo{vtdVhqoqelhsrxqrvrijfmujnvoojmpkrsjvrhgqc^xquntjped\etteolbxihlnnk^lqkwmnsqpnljrs`jrvknjnwsmkljnnienqj^oljgpoaomjorxspXowpmnrooilpo~^jZkxTjlcvremxjokuVkoplknpdorkoLolrJnppoyo~mmmrrqitrjnojqjmjpkudlT_epzGmoSip]pr~orqSonjyrooNgsonOohponmzvuonne|qqnkgppQuk]ilgoGc^qomlo}wlo[yppwdJkmmlxkznpe@|tkpqxfsmloqpjtnqmlkmdbktjnwotTiqqhgdpjnoimsjgpnfalhmooimpnYiovlcolnQXmmojomilklkxxp{qonnhiorqPnommsmm|qhjeorolikeTnvkoO_qblkqnk\miiqpogmqhjkplnqqoh|nkkLm[mpm]numpmq'}opTq|penmyqhliopomlhTQnhkmqfymjjffnum{eldonprXnoxH`njgplmmnomkfrasBsh|kk{qmvlqqrgpnnlOmkprl;mlpo~fo&w|mmof!ovylqki`iwm]fju|glu_jUs_ngpwobdlmWoqUnkWeroojnk_pXhugmognptnTlfnfnwunoq^u^}poljlstsnzlqmmuqvhesptuidj~ntbirkouohtsmkcJn~lnjop_okkboovsYru|n[owrfpr~srsvwc`ozsmkwZglnj{woebhnnphr]qtjptfnlmqoojjso`^r_lmn[qgd^Vhnlpqkqggkfr[_nfnd]}srowlec_jqop_ijqmrqoftntusupntsrplyvqpUmnpjihtorxniqqqfmnr\p[enwed;Ygeojersbkjlsvqfeqlknpypkhorscjvau`kfppimripslxmosmkoqp`jSsgddroomlnuperoor|kmljnifnIkH|nooh*jjnlftonjgrm1nznkOocnokkq~hmqmjo\[ajoXlnqGko]okmlnmqpnovBmjooqtwmkknn`wuRpoj{lOqqewoqmudlnYmnxuirOWYkp_oogpnvnonsmlinlmkqm}tfcoSoLkngtnntwPlkirrhlqq4jukmtsqrZmjnxinnrkhlpUnksorqsurmlimlmsrJo}ZqWrunwsplko_qgpiqrk`{jcPs`Tjmblkjkqxvosjpnrimnpgilr|uwql}xVWphblkNpslklqjpgomi}GYmljmSsXzsxnjogil~cokUnkpupupn|znwsfnppmkgSnunsmjo`]jnroimqo~ncpPrstilujpkiomoio[llonPYmnodmkS~mlwtWgplmjhmomnmcpon}isjcjukdnnnplunnrllnnqnnnilrmjhvlirnnl`onsoo]lunorcrocn|jmpnmounanm|]jhlsznnnnpnkjmamlmnqohonpptjohusnndot`lmwkmpopmmknrnilomkyhqo]kpnontoonlonmmhqaxqmnmrmgetooes[nvy|molnom{jhmzlmpoicomfpppnql}m^kkncknkjnuncnppppkonpmpVzbjmklkolp~lpltqndnnrvlo`cnlqjirmnibmrgnehg{lmplfojmlnmmmvogyelqkmifqdprovmpaepltgqsnhomiipporgjidiljlkvpqspflilkprlnnqgprfnkmselpxovlsjlsgasmkprptqopjqdomqrlqmlmlnnlomzpwrklirlrrnqoklkrojoqagkoqjpolVrmigglknpqrnpphminklsslkqZptvnumskbmklrgiiolniksckksngkohlnkkqonllitvomopnbpsnvroqpopxtrmllgrioonsfqqkt]qonjotninkknrlnmhmjttognxopfamrtenilnookiknpuqplcojpnhbqyvoytmkmlmnir]oqmmlltpspqtpmnhmmh\jvtmq_o}{pkpbjphkmopnerisngmnoynoknjonqnnnsrhjpqlotlulrqtmqmn{kisspsoyudrnwopqmpqsrpntlg|ms~jjoqmmqkoodllpnmnooqqormsqoxolootfwmvtogkniltnji]YhupjxpqkinhplpmeP=nmkmown{ntoalwvxkokqgkmhgromtkjUmbhiqqoenkofnkmyepptollpssojxmWnqkfmg`pfq^q`itscpwHokjkmwvnulpfymlqvhohojplakhnsjnnpkjktTlt^pivlbj]jujppkeXrkodnmwmmnsopdrtuik^nmswuin]uVrkosminokhlrillqppupo|ynsapdovnqrhstsxlnlnvoqjdnkbxlgpnhqslvosjpoqmxopplbrsisenthueojllqkkfvkahbbwlvopppbhagmhmphkpqxfpgjNkhnigmnkniprel_lmlfmjncmygfixnioljifjxnjvnzwpxrlnlidmcos|okvopnlhrtqnfmowjotlnkr\kcb\bmfmomhnuupovhkjimylpjhnlit|~oflqpm]wkmkrokm{wothcfrnzjrWmhjeodqapu\nphprsjursjji_{qskhhomotj^rno_ffmmgfmnkpunqsjgyopp_qilkrm^horemwnlmiqkxmrvookamugtlqjqjkjkXm]nhoeosojpnovkgpqnkgnsosnojIn}hbjfjhjxlqihdjdlt|Uuispls|uiprikqndinfrmrnaqmwnoimqooo}nlokukhiftpekndenjmidll]impkgjbxqfdkxmksefokhnnapkdnkscmnm}dlwnmhlhjmmllvii{noxpqnjlh|mmkmnjoglnbnqoeqtltlkn{nilioknw|onprmmojnmpjjqmoocmnsolwolnnpopsmmrfmqpphlhlrvdmlpnsnionckjknlnojpnkmoslljzmpp\oltosZmqshmnnqkplklotroyjsnhpppglozl\fopnzormlwomo|`cln_mgqosnzmlmlnopjgo~plmntobgnmwntykeiqoymoll_hihYioqmo{pnropvnin|ls{otkqqomnblgohoomotspoq{jgonommnnvhrqpetlfknm}npj_r~qnqnrpwjxcatpjpeyjlmpkgkzqxcuhiokhrlhnhndpgqizpigppqkmmrnqmlbip`epgkptelgqoqmnkpplwg{ivrnaso_ojjmgknvtgqiqsmninmwlljwujklsnxoplimofjnmlnolpjpnolpmeuqqopvrsprelpljmlplojhnnnglkuop|iisknhjrffhilimnpnqnmrmyhkmrrojgmklodoqznjnkppbmmzqksrmktevmkltlimpjlnhmirlplmkkukqfRojoprmlnvqlmk^qhpomolpkinlcsnznp{ob\hyml\onommXlm]tlloomlmmpspqjxohh{gklmlmmncjnlgimnlnhoppopqnxulkhhqqvmqtocklpntm]lmmulryinotkrofnlmmqnptqihnm|{ooonnp~viofqZlqx|lponlkxcoocppooy|nqrnmslminrfbsmnmkofqhphnitjmkmml_l[thlpmmmyk_mkobywqqmxnlppomfbppndpmnflsjhjopnpnmsqpVpomlqorrnl~hoqtswmznrrlmijtpknnnm\qfpqnnonplyvnunmtlofo{qpqmmjqXpgjnlko_ostnjmlujqkqyojrp_mizmonqoolmtonrujompvlsmwnkcpmooonklosa|qoopmndkjpdplboujoneonkkqZivaoqro{colzomtmqieu]zpptomsrktmammpmponkqlptryootkfknnnUojsiluntokqgwgllkpl{fluijjvpnjwiqlsmfnlndnxilkhzskpnngqruvfkfko^cmqlgomrvlpgoqiq_lmxks}oluppoproqntkkqotnmirkrkwqgnezonfvlhsqtziysnkkqmcrikosslmtprkrognzgjqrneggjoridqnuuubimjnislnzhlujnmonpmkmqrljk_nqhponklkpmnlmpipnnm~nnlungptrlmmmuvi|rkslkrskoolrjqmkjk|rpqlfWtkjsshkfjdqlwgthjnmocmikinhkjnjuufstllmlmqqznrgjlcoqwpmslbnmnqsnnh^uhwlpqolrjpmkrj_}kgxp}hnqkpw}]nnquYrhphqjvdumnmn~sljgr^lhppkkpqpkskmnnmplnrkmpmkmilktubsnfqopoxknsnmlktlrqkeolmvpofqrhmcpdtmotiakQmhosqhotdmljwippwqpnmsoblj{qivquopukymrnslqonkfrpohxmionmilngqeholpnvpjpssnjeooqqomouqnmretlrspnbmj|pl{ogkhsqqmejqjnkrapliikprnnvmrt|Ytqjsonkmlnilhrxpjnjumpnnpubnwdknmaqphoktqqlolhnmrim`nknjjetlsjunromxprnqxsnlki|llioirojtkptindr~lkpkjolpokgizhnwopzmocrllqhfuuq~qlegtiqnokZoeplkjonmqpyrfnntkgqolpenmlojwlrhrmmlwnmekqqqhvqj|nnlx`isqdvooapwpoponqfronhtknp{wknnznishkrqohyndd}mpqsjnunukukhcoedoisfgxmnsluqoqgipprmpknrrs[_elkdgpckmnsrhtkvqijmjpoojfdirqrmqlqhjrqjnb_nspmimyrropyw^geogrypolflplnvfmkifveropumnippsss]fpqj~nnmkhhedotohknwokbsllois]wimionttypnnkxlsmngloxfsjhozpjihokokrkmb[kotnnpko|jbfjjoxpei_sqgmlv`oioslkqsmogpgprjslgvjtkqmsmpvmsm^qnqustlqhjpueiqohnepjk{`vUijmUptmjoPqv|gomvonrgoqlhgpatulvkrlnar\nkbjflnfkpoohfqkl[s``ongndpooburrigmoiqkjjsmntq^ioqminivPpqtnhmjourirutmllbi`kseqgjfqumkquoonoonhfkkskdllopxjylylcrjmswrlkthjqmqlsjwlnqckjmnjbmnhltsoqgrokcctmtkhtmq^lrnkngnfnsiorjiv{ojvhomlnvnknmxotsoogjqhvnqlvdunqfjcwjjajop]rplhiattskolqltimijfrgmrnelkpkfyhdukxigplnlrqhkijmitpfknlnylnlmusmvunupsipqhjqdmgqkpkkplinjntmgsitsusfjodifhswmjifuyrnpdhlnjtnkhouojhjinsosxiprmofrptnhkjlhponqgjjrminmmemnqtqhmktqnopxo^plgof`wvqnjl}mrkwunbmfhonnkitolon`Zhobgdkqkrkmljnmsplknjplslspmquprmqunsbnmkrihonlsnpmoqlnsvjnkl]nYjmeolnnnlotmp}`olnmpnbmlmtnpbodokonnool]ljjkiqnntnlnkppqiokwlubplonrmleqpnmmmmimsnnl{oqlokdhnzkinprsqzqop`ncpsol\ooqmdkmn{rqkoklfnpqjlyrvktqosnrijmrneomimwbrscmeh]mllwmmwkkooqrpnpzpsdjsgpMhnhqqppldnfkkdnrrqiomospploqpgnakenppimkqomnuldkltmpni^Zpmoksmrpyppnsgpmspib]qoppoltlsotkoootc{mwnnnivlhxeornexpmumnrmomghahqohnkuontpznkmrqll{omnkpfxkzlgonMbzqktpwsrnnnspmojnlsknmrlorjlltfjpmWjllkqtkzronkknrpnvoj{tenuvnfrttkmocjqymncrhmnqknpldbftnpqqorhkxpsopkgssfohepvjv{zkxndVcn_gpbgpmqitmongn~qkvrotdkkooroopmmneifpfXikkllsomoiosnnF]mRrjesttqwqpomwngq]lrroqtsgimnmhrrtnnstpqqopleilkswjo[pmgo{mcmtgqrnc}jjzXVfmhssolpyepnkorsmjpkoqejlkmlnfomhnmltosfikheoikbpnmsbisrmnhnfhqmqrrkomkk`mqgls|jqpepqmnxllnlmrdmppfkwrpngs`ojcshnhgvqmhim\kiqsdbrzthosrplpxcnrmovmhnnlmnihqjqllo^ktsjiosrihiolopjolnnwijomrxoskjiohbqsjmldrnspsmzjomnvkqynjjqfkbomnhnjmvlopkpbkhnkjmljnikhjtlmnngjmsqospprevogmvigcVthUlkmZtjvgnmndiSss|htnyikotjmeuyyrtmreodom{olmhpiintmkjpknmsdtm{nqitkkppnktmskhrpsprmlpoiqhgmrmdjqqcxygowrrnplql]fiisewqcrnlrrktmjoqnbcilhqatxoal\mgrprjXnnrkonlnmkfnlhoxkf]pnrqjplrqoopxmnraqoglrtnriojcsoenhrqoiesnfonngncntmobpfrrkoolnoolkmgntijoomfmorajlpLqqkqmolmtnmor`oYoomnnrprniXcqoqkxporqnpoqoommtvplipnmmnkopnUzpborlmQjqrnmompppiq^\mnjjxlpnnoloxvpnooknno{oqonnlhnxslzonoVwqonnoplemtqomllnkqnnj_fqkplmmqgnmblnwpql|mwlnjjsong[llnosfmqvnmolhlwsl`mjkpkusryokomormmnrnnmvupsqpoooo~txmjjiroshnnqttudzmr[xoqijnnglmj_olifojmkobkmvo{ntqcwqojajptqjoosinmjpnojkmhoohhgjZrlsnrrnppsnpmkknmlrtoukdfewpqlvylrxejunhfnlsupslmfjmzvqnj{nrm{plrhqqiljqpxkxnhqhpxlirqno~ggkonmpjksjjihkpkgphpqpvpmommujgjtihmhgwgoeapoxltmmjqkhqcwknmiollo{ljnmrnohniqnmrorsonkooolr^omkuljhepipsbmjznsrsxpvqqooglgl]rfmtkie^_mdmhzg{vnojhomnvryzrlnlhmp~oumijzitnkjggpsrphqsl\t~tvcipeukkirrriogYxontgjximnkijfpjm`rvnqntomolpcsleolhnmpjfrg{ktmnqb[totf|jki}qloqbjsgholr}qmnqikhjujlkimidmnqairncfkmfoqhtvz\jposnxmqjqijjkplhipamdmjkfhhogeholpgtnudfkrkprX^pinplu~spuyttonvksqzoeysuutonsqoouruwonkjpivpomlnrqvlm|mnuoobpgorphqjwrnqqyl|svswoooemnms|rlpnkusnorupsvenr}hknkjvkukepwlxrumqqosnvjlpmhlohvwsyonytxwjvxoqmlungkynulewrqttplmmhqiytnlvkjaqrahkknkphkqvxtilvmrojzg]pju|rrmlvijtrojgmu_nkggklfozioepqopg`dlgunpu{qndq`itnumomnjghrzenonopo\iiemsgqmgmtoulspnmkrkxfeiermtlneksznonmrndm~kkpmmmtkpkuwnq_rfoppmpms]l]nspnl]mmvkipkmfkmlizkrlr_nymmrtgpmtmdj{pu}omqusihq\rpmmlnvpmnqmolljsvlprsviosanprkkl{homwlpkyqumrjgexnpjcrrthkjnkequxnoln~punsokuaprtjomrkjykqkoroprjtnkrvorjuonuntykmvzkpqknmkqslmopdo_npnmi|rlbihnomqommmMpqnoqmpkdoqUlrhpl_t~mwunpkkslooiupmrptppourkpsrutors~llfq[ilonpoeomqnmnwpnrmwpnkxrpwomokpnlmnjZwnpqlmkepanXphvokbsiklkxq\lkVqmro`bominjmookhhfbloslkimmgrXomomnmmnmoophnpmxntnnqmlmknvflnjqjmlkmnpkipjoslrmujqmpplmlvemoahmmspoommgmlm`mnzqrskjkqjxpdmpmvn_jlsprlnonjocpznojumXdrslpnpnkqqotrWmnjqhapnpqnknbiprpmovyoqkonbmnltoklllknkqovjmvkkminl|jlnpsnrmhlTxolnnoqltklpaspoutkpwpnkwmtjt|mntllhmrjtmmrembtnegpfllkonxpdqrnmtjn_lmpvmqnmdltpmkxqojwwpr^rfpmldUmomceknjrhkxomnqu|rnphqkperkdknjtghnmqnrkfqninsfkjcqlmjllriomaqqoerkqofskqpmiooljxperlspqpnvipjw\omiq`en~iflnxojjkkqlsniiigjjqmnmmmpnhjnnotunzqhnlhgmsqjpqvsklqrhkxjiniqcoqhlhtj_nsjhpolroijkepirnbmercnmrsqnrmqrll`tnrktkzpjipkkjsorgnjpojrnlpubbmrmpofklptpgijmjjcyjrdikqlohmbaggusrkentmp|pdmaymhtknjllsikqqhqdcp_fqn[ramhmhurpfckrmmnlpplhnpu^pfcpfhmeotnrtiltrqlukxonsthrkmhosdoplrlvsonbkbhrnlmomonlerehsblsgntnjofphlhpqrhsaksnVkljvmmnolrhnhdlqlrehmsmjrrjwmqgqknnnqprwh]ficuonfoqttgmhpj_ippulkolrsikqoornpkpuls{alonpWnmookommqpnmkqmnpjomlnpeplopopoonn~hk^sojmm[oqFlgr~ouocppojjmnoqpq}nlkmqujmkdavisrpqqvomptoowmwkioonloxmnpnonirmn}mugmpl_mumljnml{\~fpoormpkvnrnlpkmonmqonpqipmmrpfoljn[vdkomjkkrnj~xponyXoldmpomxkjhd[tqtnirolplspolloomqpnocuuyngmqnmrmYnknitelvqcqkduvohpzegppikpmfboxxqpdlrncjm`tistjujlwzquwifostpthn|pgryonunfqwkwjqvlnrmnoo{voqrnquploluoterimmrnqcquvsoesrmqsaprxlm[lrlldgnrfjplpwroloijtugmzljlsj]ojmpplmmfwnUvnomognssqitnopookpsptkimxcrnttwlonwrqkqgkoo^jktdtgmulmsnojploduntwsarnmrnmhnlpeimnkaodoWj}juopnutwja`glegpjnXklrljqrpkr{citRmucjjlwgnn}qnovhnijvarpogpkoomiktrsohvhjserohlpnsZpweKj_isljrioc|jongninmpplyut_opfknormnjilcn\emle_hpofoovpdkysklSpmmdjmiqohrnoodeuqpnokqsyverivojkpmvtqm_mowtwjkqtomemgmmlsrno[jvwenoWqjomjli`lnkznoljtmokqmemnmrnfnokbqvutmjrp]rdhtrqkjjhnkkjtlolfjyns\hi`olmllqttk\qewpkzohkmpnkrhrqmmnmumg]afmseqpkovnqpogsbkpgjluiknmhilmifpbumpcjnlemalqojlvsnsynqlllgnmklpqkojonf\jirkqkpdlinmvqkn_grh{nomonplwhnljncqrnn{jnhkpsX{boosorqtlqpYhhipj]olm[rqlkkphqqmrepmulerugmmnpojtpoofjjkmpqojmvmyfpkqmpkhmlzkqhprnfliopmlsinvm^horkkunhjmyhjgpniimdlrqqlllmlqoulthruroonnnjpvqomjknwldhoquqkjrlmgpjusvvnxneopdyhygpntmljoqvgplljhoksirpljlkoqbggsmnjrqqrjipiuriijmplvmeqlnkhrkktnhnmwmnrjtgrknunnlowprhpmeqklirlo~llnnqpvneqjplpoknmmpmfrnphulmigdsswjpmjmhzqeqlxdrrsrmfepnkympwqiiwmulegllcnlnvnsznkxpulrknoowflksnrslootgqnbmnkqtnngkkpklnuakhpskxoxlhshe_dlqvjurjksfhpkhunlqqdlrrhsqqpjggnsmbnjiotqvjoqkrirplt`pkllppqfqrjerfhj`hiemmho]dqoixjprkmvpleiimnsmiooleqpmpqqgnplhsmipunskomnnitmkkonwtoononnrronmimdknmfgqpncnhtolthnojwkpqcrumnqpmoohmophm{nolpohpnkjjgq_qkxgwrpwrndqjpjrjpnzqdilonomcmljirqovjoorisloqknlupjvhkrhlpdopqoruikmikttYhlzqgplngnompivnqlrisrn{nonrnoznjnptkqiolgalhnernriqnnfo\mWfforlortlfkzfikhnsjqk`qnxrrlyhmextrovjohl`olmkmlotmko[snpjmoennflxrgfkw{sqlvnkqnYqojllkjofvlpqpktnuhqjfiojjriofldbjorlnjk}foqpb[n^qjwnkpvisyitnwl`dmjnmrqtjvmqnjd`antpmsbiis^^phova`muulpqslmooqxljkndtikzlYlkwr|mnulomjmpnpdonvnvpdib`pnnj{tfvjqpljdmjopylozqhejnoimkotqlnotrlno^tofuqlip^mlpr_mnh{\wanwolmzhurrmp|onsgpjrldqlnsmrmnq|pqxwnut]sortklkohnqlphkpmhnilhirpowijkhsnoielpou}oskqgnlklsnhjsqpieqnkitsmjjluuqi`tmjcsough[jxnmoxypkcuk_ktnsmorohuiimgeupenmwlonhzmllogonivqmlobsjromqrnfrrrkiortzpmyyqqoqhowig`mfumjqybrvnrqftyxmitnYfunrnsftqnljjpjaokcpgstosxnrptnceejiuqklmmknjokdkhkqpfqomspvmlop[entuprhrmp|{wumohjhnsfceoetqqknqiqqufjkkidplmpuzjmomrunmkqsmslhiqqhmcmk{hkkk^jUlljejxhnmrisqinnodnnlnrlnpypuhqdponkqhvkiqn]kmhephqionoqwlmjoojpfmlqqoiinhospsyuokrkonmgmqsfjomwppmhniabeonhoirtnymmklppsltloYlqompr^mmhlmqnswswpkqnnfkjhunljklqloonlwbkmoqm[ojo^lmnbnnnhqlsqcjnnnohplolpnkmomJmojjqwjjzmlfoqoimtltnoolgmookkpsoksll}snglck|oorpmog_nhjlnrpekloloimptrrlupnjknisxpnnnqlminkkiijnmnokmnlmnlmpmmropmsokmooq}qmntpltoli[npponmdmkshmmsojrnntslnnjl]ompmoumnipotnuniplonofponQuozqglflpr\mmphfmqwjnlonenldmojplsumnmjilcsoTlmmolnsknilvktikn[lnnnp`mpqwrnflmjsqntkmnqujwqogepjjirfllhvknsfoenumynhonnopkhlnbvj`pnnuks`Zk]skqskruojxynsnZoqmerhoirmkmnkryflgrlgoomsjjwkbovlognlnwoksnqlljlokrhokpnwlplnqqpjuleavqgnpomlJh`opufqllohksmmklqsnpfmuplunmqplpjliktirnbjroxgpmnlomqnabtmlmmncpfmkqnnbplolbrstdloirlnommgkqvormonqomrlolmmqpmq[vonmrvnrhkqtskwogpRjSozkyqjkmBsnki~`xioeprloqnprlkptprzifkdnwgjljnflolpm^nhnr_hppsZouoxcckljhslj|hjoqloflusnuzoonxgmqdqfwk_rkokbhiqisnglopxnvnnmqojnjkopflknqmiqtldoklonstomniqtkntlipolturpqillwntqjkpqkpXl}nmpmjbsvppvtvtzvmntnplp}vpgqnsogjreqinammqphmo|nkinpovpimYjquorlfv|gxpZiplvhnrnrkfms\ghtrueut`oqaukqssujlpjn}hn}fmisrgqrztonzpiptkdmlh{lmunuulrftqooentormpr]mgqqomnpjrfiphksrzgrhkmdprqmknqdnUqmnjztaksskpnruhqvl~jsipinqtq\{jlvnshs~gqphpl}lnnhkmsiopi~tonmninn|hlvnpmiomiroqjqnampopkmordkUopnqjolmmjllonlpqfol`lfvsjpybijqplmrmpmormntmokqnnoj~pkmaljsmrrmanllhpnkoorjoo\mqmnjonkoplkjqpkjorkmjulnmjml|emn`msvpwm_oiqooqcxh]mljupalnnlkpmlktegxQjqmlmhnqnljnqmjvknooppk~zllhk}nnuY}mmrtjro`o^g_siqioymtrfplkqrojzifqqtrin\rkcwimnpmjkncawj}rsmq^jml^klesoooplnflhroqnjcmrkszj\ldrglunjmmumlf^lihlpknmskylI|lph|ghpklrnqimpfxjomnlpom~ikendojtimixjjpfgnnsomrptuomilktfmwktqospmYspmeklsbijqqnqiqsinoujpxys}[sqmtmkoqllymjpgmmoaplge}opmiltlqk]}llsjm_sukpijqh_npmlehskrzlhu{oxiotvolppmlnmtvulkptthgqwlvejcmrgofroissooklmmjieopmiogwgrnjpvombljrbguwnikgtkcqk^qtmoy`apkrpm|jo~pnnllviopkimsmtlmshsheqpkmspxjiiltloijmjq{ioitnkivmdgpojkdnnmipqmkprcpovony\bekoililn}nlmisoin`hoqektxhzinodll[rdpln|lfpojozmdpjvgjnnqdoomjrlhqogppifmknloqxmisgulapompnspndjpkmnjjhqoupfrzookwiklom{lgtmnmXsflkoqmjzrlbqrqnXhhkuknpqplqlorgxkhlkxnlgmvptr]rkkjibkzourrmhlqrrwtl\mpiojpxmklmgwlqkkjnjnsiojgpnlirpioigem_spqo{~orhwnpmrw~joYgklhslllirsulfbvsxkkoljtiqfp`mnkko~kfqjornmwqooznmwrlvgrjjuttsmlkokonRiqom}klllmrktnppnelomY_mupmnmornlmnrylfsmlpnujramzoXmpo\mnsjssqnrnmxlwonkoqefiomqpmgooeotmkkoqnlUlqoqqqpBkrpvgkqvqpgmm|lnpgmrptiqnojgspowp{oollqnmnrnlpjmpjXppltlhvjnhgmpmc}^l_mmpnwgpsiilpnvinmsjnqtfkXpokljlsoklmqqdmpnormopqnoojzvskmtknVk_pmtsvjmlijjwsrqierpdl^fpo[omklsimpjnjoiolooqjuuktvmsrvmvsqhkicpi~rjdvsingkmsnqkrrlqmplcsrfqndfnqlqlktnhjsrqdimkan^jotlotkismknmkmijqjlcpjoolsinbrlrzknknpriirljitksqlsojqljesqnmlgxcgmarqjkr{oorjmvmrojdfqtmdxqutmscpilppor{mtrmsprknzilpmhqrcplkn|piqqhlrlktkpjnnxolwjmmkhppntvoplkoknznqnfnjsmokkmmql`punqoosrnij`nrrlurpnrfqj~m[opoymnvjblnpnnntoy`onhiuucinnqrqlpnkqnVpnpmjinpppqpqrdqjorkvpmr`pwmlkmepllpsqpnrfrlppnokQrntnplmrmqnmoyoljomimfudmfhnumxoeq{mmjnxnmrcnpnmupmpkjmpknidyq~rqjnoomomqbojmoqnksplox`_tnmohqmeheojih}^lwsxm[mplpkitflmmmhslrh~imnnxtnmnoqfmkkqmphnmphplsvw]qlqo^mkhfqnkpvemessmonnimgoqrjnkghjdgirqoqoptpmi_volvmooqprionarotu]njkqmqnkljmmil`opiknlgxgqoikll|lkmknmjklfmlonkpjnlorf{fmkj]nlkkklolptmfjinlmulwkom`ommpntpyjsqrsoksmoynrnpomwomjnpo`ealjilfkmrfsqlpknkkhp~dtpknl_fkno]mljpqllnphlksynngpppolqpnprmnirpnlqp~loVmspn{koogoqqntjgopnopl`mzfmvfjpcjmiwoknnmpkklknlmmnzoqkpqopvrrrplpjklyl_|mokqmdqndokobx|mmjoZo_qoroloporojnlYtklooimpienopm{ncnwp`loqpj}ltgrmllvwkjnnmpo^ilvwuponnmqppjnsponpnnnbpnnntonnqlxlnZdgoopne`jnprlvlipptkprljnokbsrnjnomplhlmbgq^ljqliolnnkqhkjkqrqc]rnophqqnsohknhixlknqqpbojemeltu}zkmoqplpslfprloopm}pmlpojpxtpql~krpooorpinoovocpmqjrlafZlowmpmxllkomnmkotmjp^xkmnmlpkvmjrq^nhr}pomonophlpVsomlnymksponmqoSepzrjpkklhmoumpmqqnojmopknjoplfkp{cfpnrnmcneukmqohnnonklpbjoocnukdopqnnsnnZsnunvmpnoonomcUorspwmp^keninqnnnitnnhljmoikmXpp\nvfohosqmlqmropZnqqgsmpunxmonqlnmjdskr_nmxrqoouzmhloobomsqrneqvknpmulvknqqslpljqlkn}vnlorkpfqyo`jmolmmimcmmolpbmqwmponi]nmnnnronn`_ydxn_oknmmpmklrnmpoltopo_ufnlplrmmdduqjnsiooknsrozk{ipktj{mkrfkkvmj{fhmklrmlkdvxjosl]hrkqwllkkzkrqmnkwsk]ojnglrolfkhosuuiqkplhkouwjgl`qieiekgpvkuqpfgntiteootmoxrrnodnnufkkoqlnptrhomjlmeqinlisbmsunjhkfmfp_irjlredjpfiillkkstwxjknoqn]rirmkhxnbuirobodooaogehi|stjimsmlj`lntngsolhokgoiibqmkmoignofbksmnhgskapjpml|wqnnojplnpsmjoklngpnneqnyppntmorjlljfpirmmgo|npcphp^pmjknhqelosnrmwm|Poormjdnqwnjmpmhmhpujdqmqolpsioyyfltapl|lkvl^pkqrkmjnlmlmqmxjpoppslospdpjppnmllmntunnqmmoawvn~ooxpzbkmnmnmjvphpjmrouopm|rlqniaertnn`rmylqkmqkjpokonfpjoUxommlm_nn[ohsig_`jppokrk|l~sjibooicmoeemmpyjlsnijhkpkryporhtkto|qmtqsojzosjjdpwlcu`qojfhiigmpssolhijoknoujot^molqcprvopOukq}qtpojznlodlnnjgxpqnwgyiqkk]ptolmnllqkqlpqakisymnsoo|isehsykurhlkpjmpzgrsnojoxlrslghrrgr~hjjqkrwmlqrimilekcofjmhsoponsiurljmqlmjdmmrnjmsklpeompmgppoomoi}rhkhnvvjqlnlskpor|lnmmfpmngr^mkn{qprokmpvm{nhulfdpcmjqfpznfqjdjoetgnklwnkrjkuljko}pa{XxkljomsoqSvrmexSwzqgkpojnmoktnsujoqnrmrlinimrpjnlhmhpkmps]qnhZlaokhwmopfqstgjilmooyhmipstnkshdmtknop_m^llnkpa_luikjishjjikqnhkqerzjpxojrlysmnmqnpqlqpgop{fhfljdrekwumhro_qnplopmqnhnlflntmnbnnkmpynonsqoqpnkgjp^tpcrsXreoowqZospbnnrpnlmkmokpppxjkrqushnkpkmorkqqrmlhnrvmjotspnwjqoodmofgirqdililrocjhoqmmhp{knjqyhknqqojnknnoelji~pqoqsplvopftpTm{crjnqoqeokq_lmrrhgnmmpkqoujbudPpnvprrinhomooonsklxtmncefookkppyo|ommpfbjslkoruvjqspigeprpllprqosnapopqmlm|qkfpx~nwlomkoorFckcokomlnlpnslrpfloettlqemnkpmropkrophgihormlktomloir\qitpzfnnnmptn^mjklqujhnntlmploeoqkpyjplhoo|jpoqxmorrfjzgx~lkkiomljjlonnmrnnoiknijvsltlmlpikhsnlmjtimrvmsuqorkooupatopmqqpto]mmnensgclfnnqntkpkprfoopojorpomgollnpknkopmboqinmnumlakn}mscojnqpkolmpluojuloonlllsmonkqsnrofoopproinvgprTixrfkollqqokjqsmjjooxjcpjnponmvfpgkomlznppmZqlmnrlohndqpofu_nowqnltnm|konimjmslm{_pnnnmlu`wncnolpzqenmpnoqfrkeasqomm{omzlmnpaigpumsgnlzqpvnklloorpsxlnpszk{mknpmmv]ponhsijowpclenqhmskrlpkqj}mlhsirnnvsmnntmlnmpoijqnkznoltm_llrrtakqmfopnqonulkqmopmmnmsmjf}noplaononroklnihrnmpqhknqnnsllwconkXppmnnrkugonr^mbsjrqpll[kpnmorpaorhpnn|mlmlij{pmoomqnpn`lkvnhongqjqnmrrqltgUmmpnltqqopooomlkjbndlljmkoqqponsnpgpooqlnaqqoxktnoj{_oquk]siphqnqlnoerionqqoorjmgkmmmeqmmesnrqgltnmllmmslksqnjm]ltskrlrkomohkm~ornkpiplwnxfm`omorfflZooulq|obmsookqnkqklmrlpngnrpgmrvnispomlnskqqnlfknjk[sonjovc|qosmkounljkillwnlqkrsa}tlqijrnghalxmnpmujouxpnrpiolnoonkmqsygkaltitmgmnppnmkkioomjknnmpcnoolmlokhxrmmqnwmorrmo}omknqrhkkfrifporoqoyptmfnsnvqfqppl|vslqpllsnuphmkzpodkjlpolm`lokqrqvtqgjsnmkqsuorltxnjqnropvopuojmjcpauzjvopgpjpljnkissrklkjykpvntllqhrqkmolmxrbogjnsplenjowrxnleepmmhnppmpliprlijjmslpuoqqkkiosbknoppkwhnpZwiqvr[nuqvwxovplyrlupinfvqnsokqopmvkiogfcppnpjmwkvhlmko_konoijoplitkmllkohinoYmihokmllmjmndijk~tocqevl_]pxmonqppqoilynqorkmmnitoaopcsojkjqipomoxo^cqhlihmhmoiqmeklplrqpjqmckyalmn_qmnnnqpm|vfqornmockrdmhnomkxkjquirnmpkjp|pniqqcmZneuelnnfhkl`~jhkkfbpq^jntqrw^ebexq|rlmpmpmtkrqnrlnpooofwchljmpnoytgomrrvvfdqljkwpepnmkkkmniksnstlhsrrmkhkqnypnipsnmrqnzookn\mnhnoillnopvnnioslnhomlolppimntvsoppmonnlhzrikqui|imiumjmwmzovflinnnditmnmpqhiopjqoprvooj~rnmifmsqpkkqplknloqnkruclpubnljkpjkmyktoipiifmnrfqmropukpifllopphljomotlonpin_r_ynnpflprqjolngrrnqkdqmtosokqnihnplmjj{llhimwiffzkdpljohoknrvjtioplwrorniojtlsgqbppnweqhogjfjqxounrmtj`mmmqmriylmfoltnmh~qmjminlpqrjiljpoomhtgevsijjnkipicjfkd\omniqelprssainnjlnkllslntipoqoro~nvvrueprlrqlflgnkk{uulcqrowhxnedkomlmgpjtmjnmlfmtrkjjkcpcqiqjjorjnn{qifmin|mpmljgjqksnosjhyYllqlZjjmcsuf\qlokkjfpipjfpbsminluvjimsrksRp}rm~}l_tnroowmrfnlrftpskjqmpoklvmqqjmgmnmlcupvooqk]qrmkoltbxjsihr_iot\rmjolmjk[pnnmtinnlljasorkghugz`fpkvtmoeoqori\tXlpqbojnqapgfbgonRrntmnqrqqgtlcyoe`tmkvtgjionzkm^hnhkqjrkxrZmY~mkom|gppjnp^trlsmgqeojjmqlkfntlreilf_pnumorrlnyjpk^lqjpokqovnnnk}mupmopnnnqnijemmstKm[brmlnwjhnqpelnzkimprnrlpnsom{qrYpdrhuqlvoq\l\j|qlmmnSnlsotnqletvthsrsllppsdolpqpjomronn_`anmynsodpiyonlirqqhps{^ppnmoouw{mtmlmUlqshiorwkmjsinqtnqopmgropnpmkh`Vnm\mnnmopmommmoplmcpomsoppnun~lnspjojkmqooxoapprowbqponknnrkokiollqbolnkljdqpnkknoompqm\op\nisejoqospoonlljmnmikoplvofch^cowl{omomjnnrxnhlzplrqolmnjqokpkwrmpIlrullgregmln`oznnwmpnk|qxoxnplgnphommknoljjnnxkmokmpfjwpcujsorkinmomstphlqmmnpnnonormpmgmpoohoqnpnsmllnooomlroompnny_[xnhlqonghempooTyommziqpnnk{qlrhllqxokj{pqpmyjlmmcjhsnjnpurmonh~k`msdnwyigkcqtpkn}knemymmnpmqfmlpj[gpzlviqnoomorqsVmllnosmanqomhrq^sfostlsXpmqpggmkmkpcmommpnkjiponqtjponmlnmqqlmpplYmmomgsiahmfmqhpsqdrdpmor}nrmunoom|nlmqooonrwopdfpqolilpinmomqoonpmkplk_c~mhmxkpzq{pqojromlqklitonlxqmqqbnnpzqomhskolreqnhmompmmqmqoonntrl]lodmqwrqogozmqlxumwoglqmtlidp_`lzioslaekqkmrnsdkwnZvolkttpmmqlroyjlpkmnllojrsudpookk\rononm_g|lolnnlqnjqlloolnsrmnpmlkpongq}em{lqVnofslpnlnacjbvumkp_llmQknlmgn`tsgzkxqounkkm{okoppklkmmqXtnrgnmnngbnnqotpqrjmhhnmqkotgqpnshlmxmllgklkmwjnnjnvqnlmkjmoolo}jxpnylrolrprrmjpjnuno}nulmlinljjl|knreoq[innnmmongmkn\jmjhibnlloknp`_pkofdnsjlqifnrlip_imnpnljlziofmipvop}llpqkopmlkejnqnnnolhqpZnhhoZl|pvnnmkmxqfqmpqnqmownmoktrjjkkmohpolmmgnlmkolktpfpmnoekundmllpshamnekzvouoqmuqpmmmrnnklkmkmjplomlnroknog{r~onpnqkjnkrnSkimmunn}qzooipnfnkunji`kmpqomon\ji_ohmokoamlsoronopwrjllswlnpnpnpwfqppsko|kknovunlqunanlkkqlkmo`nlnrnonomnomlnomoz_oonnqmgvmhmnqn`vno`nomjjqjgoljnoysnnrplpmooXjjonohpmrilwjfnqnrionvrlphlrqkwmfnqiu^ppmnvjmcpgolmhnookpjl_nooxmmlqkrrmvolnx{pfmqokpppjlxobpirr}ndnmlonpjxopqtpnqi~opmponopuum_moijrukilppmmjlhtdmoqpyplpnnmpqesmp{lnWoqbpd`mqq[peoo^mmm}n`onhmlhgnnxmnmfqnsjpmx}nppqqokhxpncjomkvjqjkmpovikognptmd^mmronqpwjr^hp}liolgmmynnnqmlnmoiplo`n]tsjoinnuinqmisauriqxipxYionqkldqmkpl[ssmdm\zlmtlhtfsasicffylyjhwlojprkrrfpmohiu]nhon}mupnmbhophsclngpllkjr{qdppj^pregjistlsYbcmdfioumhbqmsnltqloXslUcovjwglncokhkWhlhslqhqnhnkhZnjycmJienpiagnidsnnmojoqdlmxiupxoqklnqri`qhtrhnokiklwnlhrlzjokmfhsurpqolpkkprprmbehlsokosretlhnstomtvollioklnphapcipmripkluqijqnomrdqonlopinan^`qspkofinmkfgnlmnpolsporistje|{qnvmgymtrjpofnmdutjnrmlniom[hnkolfchlhyxzlpnnnrpiswrmunognqlhkjpmnmnmyglinmepcjhoptijjbnxndpxffkxqmfnnvrpZlhjmvqmhinoppjjrpnnpplmqlrpikklkmrrxllpnojakllxmzqkuxtlpkh{xbjmwplhuojvjmjomnjnpklmqolimmkloqjlmpqqpirjmomqoloulspkieqjonmkmpmihombqlpisqpnomtnpmnosunlpqnnqsrqnvhjmofnohsjootqkqmkqeknnnmlmpqmsmroomnjimqsmpfmqjmogknloknsksqusponqmopqnskmnirkolodrminlmnnuhlennmpqpnmmioqoplkopooorqpsoonnmnjngojlomnnmjkqmojrpnonnpnlmjptiliotlmomvqnpjdnmpxpqnZglmpgroongsmrnmnlnplqq~q_lo`jk|p~pl{ninonzwmnoellokpoxnlynptnsh\ouopolrai^qupnirngnjmplnozmojktohppwpjtmnohqklnUmomegallun{obpmgnjnsqkoknhjZnmrmnocwpnltojmiibr[kohgjjnqilpolromo`mprpqnZgwpvnpornqmntpspoljqermpzkvncfkqpojwmmnvrfcpordojsnonenkpq]nlfblqltrlinvmmmknouphnkonqlnlvmmpnsmzpuonlknwkgmodq\mokqklfmwfnlvldcxkjfpqook|m_ucenkij|lppnomm|bsokZlo`lpooisonjtlkmm`llt`hqknvmqmolmemmnjonvrnoYopqnokm[Zilnmqoaonwmmlm]inrswlqmcroprmlooqiinf~slnqkxrodpronpqjnmmnokozimntnfkodlarmsssmqtrzmlZcckrlrtfpmhjrvouowd|mongogqsnjlfeqli`i^rmlmbpthnqinhepiktkipfntkontkecmgdmmesoWhhpldmop}mclsk`ronlrWqlnc\fohsoluklonjhbsdokjginglcqrmjpnkqsnliplmowlr`rcqhnlnqbknroqplentpnlnhnqosbrnkgrnkjvgqwlwprlolhsfpporjkorwonn_gnqlrkxomgluin_nulrjkpopksmsqesnqrrhmql]nrnnhkormo{khllkchunjfnqkqksmrpoyotrlj{mt]nvfqmjioesqdntfnjookhnirkimpkontkokikfkvtotfkzfmqnbntpxiqkgnkllqwcnhlikjtlkrqjnhujuopklt_ljpihntgeglgrskqqzjqjnpmj_ggqvlqimjlcurklujiirvajoqfomkgrokslinhrutmuupdmoknqZkfwknorqwiqmoonhnppoonnaonogjzolgf`koinhsuphiilmvZirqlmpsq}lopkjmhYjlprhpmqkoWmuv]shk]torugmrelnqmhepilokfkyppoveolqbjo^lormlnvkopplVhwptqslegsm\|]ql]Wovvqk]}k{hrt_plmlorlnJpjinkjcmtrqposrfmr~okPwMnlmslllmmztlhljnloloonTuosRmjlixpnoqglzjsmvsjmp\kmsmqrstnjrkPVmpgitbsldoglkTXpemkaoiqnwunkb{rtnppnmknmjklojldppblTdoiqnkiqqmpvoonnmmoqjihjmpprplpknmyqmkjmphklniopmmnikWfrjkpnplkmmjhjmnmprhladquuhjhqosmrmnimgorlpmijmomwjnrnuosopkkhnqvkjhmkqknohmqtklhopjpmmejqqnjmniwothhpqprqpjnjnvooqenqpphyjomiihnkphmklrknjqhjpgjojlcinlmmkeolpopmjkngiiiiggpgpkhnmmpqmheypoqkjmtlqnmopnmn_kknmdmqonhllosmoonnqmkltncpppl\puvdnwplpmqarmgnmjjmnokyomklrenxsz{nnmlppojkZknmmgkoomlpliooghorggou~nlrmmxpkruqqlkdkos}wtqpionm]ikoomolopwhirwhohlolnzogm`trlmkjcsdioqolikjrhmhmkpmojrmioephu~cnqploumngnllrmplnlujnnvbooohjennkednpklcqpdq\papqnoq|pmmwjopmormfpkkmpnjllmoopmmnkmhlnpomlmll{ju^sirmmngorojqnkqvqolklj|mrcmhkqfqylqxmkroqhlsptsniml~ksqnppqpvmnksplmjhrqlnlndpmonbpknrxjnZk`maloinknruntnonokllpmnmgnqonllrowuslxmnklmopslnrni\lmrmmsoujjsuhqi`oqqnlnoepppppkmonom^qimmlo^mmgqXnllk[iolmqpmdvkspkjhqhb]vkckxn{b]rmkumnp`n|sa~pfnr{oecmkZmppsdkaqmYfhhon`lhhtbsiigimksp[nq`koqmamopqjqrojenlflkkZwdkfnpmmsjmpc\omkkkgqjrjkqof]tdpsklngn}lN}lmfgngqekxgfvadcethpmolkehkfkjwplrm_lhejp^vX~qlqkin_alijmjmgoxjf}scgqmQjkqkeqdwmlops^qYgbjqgmvlxokquk`nOks{cjklipljtgkjesqvkulqgnnokitloyzndpiqsupl`st`dqhnlhbnovmijbmkdqutelkepnvmpsmo\jkjmummnjknss_cpzpqkefrziXhkminl{fyjmssrwlfrnkqvpjfmvsofgnsokpfrmscepzixiofronqqkjowsockmsppkjemniikueojfklmtcjnlokkk^jefsphollfvjndjl}hngyymjjkyphklwognhplqilb{omnhimktppmobsovrrtivfqjqqnjwmrqpncpnlmemmhpnulengojkpxlr|mw]nfvdlfsz|lsqhnkphphdok`hqyqgptporbtprvi~iZjnaginnlppqno}lexojntbljucnmfulprgeujhpjoknlrpogqngnmimcrghpumukmpntownitqrmogjcfjjfmojrjxpniojglelnmfxqpmzsharyimrjrnmnlcbldokolinnoonnnguoi`qmcjlhrnflikqdqornmplwqjiprnlunpl^tisqqpmleqiotpnmqkomokuogprboeSla`qahpn`mfpmypwnroumocmwylvrthvq|emqmrlpLhuoxrokmrfoppsplsgocphvooqlsjruqmpmmm_roqnolsmoo[hgmfqhilooaqmonknhooqonlnhzdldnamnhmtmlnoitvduvqqumkimnplnjogom}xVjqmlomijukjmqlonikomnnjiwioykqpl^kmolslelmcpZhqdrkk{oqmfqonrglaqcrqhjqdm^rildsqgfonprtgrmh`jmsknup}kjwfimooqlqkktiihpyrtjilnnyskkn{nioenj^nifoiwrsmoe^svpuogmfjrlirtxritmkvpyidgljgjyommkojoqnoiti|gnk`ioimiiijmulwsispurdnmhqufniprqmpsmlcdfrjkjxjemrpsrhnpolyhqeeommkphlgqphoirvqmqimnrokjnpnxhlihqntinhmpietomqykglogkqolmjg[mmqiooqrrfdidjbu|jhtcrraornrzlqnk}fgpopinqy}whfqlmilovyqqr|ilmntkpal_omknegqlqmtqne_uqmdlkhqifolzyoVojqmfpvlghnsyoijlklonldqgboiplbkoxflgpkogfXlfppi^nongocpodmvkecqqjnpnavjoq{uqnaqmsmirtoWnbmllijlolzpjnmmrqgtirnkjkjmimonmifimpmlqtqnppilm{{mqjvsnnzimjZjlqouukmveoeponnnwomnrdwm`puml|roqoqpltnqobsmvomlpnpopnpvgoVtmamsmkkppplqkp{ow_nquldpmltokoltrnp}iiOmsylrimrmopalmppporlsknhlbpbpqtnmnpsjosnkisornmrpwUmmYcppfr`qblnmlqirmtmmrlmppzmkonxinjjcirvhoommuounloqqjmhlmozmxppn_pnztmlhutvorpvloolpimnjlqlmioobqpkpmmln\vnoekljknmimpruogncmfnhon{tookneropmjuonoujonpolmujotqfnnlxvhnnimnlxsomrnjjkvonrqjuoetqgnqkd[plmqinnllzmxglroloewdmnkmoramo`njosjoooimdlnnopjkfkqm\zkhmziks]snrdkppktrlonu`mqmpnrrxiqq^ulqbmoqqlnmoloopftrtpontrqrivhmkpuomsqiof[jol_pmqldoirmyglqsovhsinrmhnkoqminmpkmmjkhuvlimepjxkihkfmvhwjnmojoplqeurmpjvnkqpogogi{lkherqkoljjnhntijjsb}llikmisqbopklndmnqrmojqujknqjjapmqpwsoknoikiuovnkpqgnmnpninislmkomppgkkmbolmyjqgumqnqnngifd`mprmkovt^ooglijhoprnsxlhsonjvshdpglpstllnjqsresnnkjoqpnnnakto{hfnouhheqwktitmpssjhtynkotpqksheuonjnkyormiwbmgrmoqpjczijemmntkmilnjgcnkbrujnsvgrnhjlmlomwmngbchimkmjihjpt[aoxqonpnkxqduhltmmjuylyqp}lgkymfoolloms{nsju|h^kil_hqmmkfjyjxofjqojeoqmglyroowhmxgjkdoucijljiukqhtinnnmjiiqv}jnpovmplozslinusksdrqprjjojftlgjnjqkgshjxhllljlvlmtjmtdkpovzdullxmioilgnmjpmtorornpulkqsnelckqnjkpuslpnofrqsdmjmuhoqknyjkrfilqwmntoovzmkusausqlsqpnnlpqnorojwkyllpkpzkqstjsluiqfnnmnlknpnmjmmzngmnqrmskkrmqmrmoopjipjjonfrxjlopknpsjtkqrgklpqddorpjhmmikqpompnhlssmslqkmlqqxposlqnkqhsjnosqekpndjqhsvougonsstpoidmeseqmm~k[ovomnttctoloqkrsnsgrpczvjocifr\inkplqngcokimkppwmooknvjkmlvrqmhnuphkhrokbvekqosniqzrsoklnqt{mhroopowqboikvmijolrmilghiqdtpsmlwwhhmnssmhjkflrempfabtgnwjkjtusppbmmqokjjrnknrlphmoljoommsyjrgwqnpzvlknyopoovjmmoonomltkzlnplsmminpurvkspoenjylolotxjonlmnrqhl[tntnnjntngmwipivqetqhkpqu`qkkksaot]oontonsyjnnpkntajnsirljnmtdpgoklbhnwreknutl^hofeqckqniouhvtkjq_moznoibjmlkXcpolknnkktlhl~md\knmfjrokooopjstq^lurqrmmnohkvj\oonqtmmfnosr}qlrpu]si{dptjnorhrm__tml`ml\ep{odpougvdslfoYvhljpq`soorl|obmtmglsnfpkhnkt^fpvlpqyutdgoljln\ourtqvqaXlnphvnMnopk_ktpo}oligleirryppoimflZzmiokavpmsgvckVk[sxnrqqgqgetd{{mhjgoosudgllc~qusrnkhilo_ptkmxkqkrmdoblbplkqotsuumh\nfbpqrchitilmpstkjmnrmnknymrjjuulxxnkqqZxi^iqoptuojZnfcVv_hffgmmllpemprhn^qmupcqbqxunfpvros{rtnnpkwslqnspsjpglkpajkvhlmjssnolfknl]jtrrmgipexlphhiolntmqlooirmo^nlmslpqdldlimsgjodqqnoomlmmjmkgpkqqnjjikngkegrjkmmkfk`pixosimmkronsqjjmbjohpqwhwdqeqvgqmjpanjnZ`oqphgus`jkpnnkmmpolknrjdlismpmockkqmmqdnssQppkkjpul_qs^tkuiopkpkonoooodqrtlomo}rlpwinioqjllxsqlbncvnormpohjbnqkjin^ksrmspgo|soeYpO_o{m\rnqns^jemqoplmsbtmrpfmluwlkonqslklktunrkpouv_nkapibqfmummkgk\kkeVxkp}krheRlcnuvdjnmqmtajirjmmno\jqpobhroergnlj^vapkm{q\poxykq]eplmtqnzjqwhmmjokWnpnrpjwicnkrqqnnarkckoqgkZkthjKmp`pkrsnlnannXmfmqlpqdmqjkqlqrkkjoeqmpkooinpmj{kj^zrpinqj`psklmomtnenjmgvulmjlpomeikypovphvjsrrqzo{npxjpjvk_hlviqyjpujmqklofsoltpmhoqiroourolkYf{gqloodptjunhppnmgonqnqqohlqlnjkonmqpmnKro{k\hwpVooomoimr|qneomhozoovpmdvnlo\oqoksve}mppkoqflYnhgoklorihjq~}kjofnfijzndntyrmkpwrsrjvlhopjgliqkvrhnfilkjmu\qmofkklkloqqjmqoqepniqeqpnpmoqlnnmulfrs}oS[ny[lbofofrromkwkknmlliphwpu`nzc[onlnppnjjmNodwoiok{jstppmnhvrkpmlpplomxknkrktmpnlnnuqesmqnrmvpkalnmkmjsojrxvomqonqiuvnxrrYnpezqhpnnknwmsXunqkbimlafipkdhiltdsrcpmponcpkmonnomnqroomvvsnlmwnnWcipmorbpndp`mrngcmnmrpnnqgro|jiosploqklnnzmlkkevitld~omslbjssoulnnnuohmppmjqoosqlnwjoklolopnjnoqfnkkfkml[o}udlrfxrndoknxnprossttmpvrphjnpdflkqkmlwmsnqkjoqOjoq|jmllqjhqimymirkQvktoolkmkkolsnwmtqolbilmdnjo_pomnnqqhqvnonqnpjnjrjlioool`nqiisonioklspoljqhltnmqqml_mjnemhljdnpqnKzpumyonmpkoolojgoiponckqrormlhjmonnHrlrlnynnemptkykuopnfimbiymoookmqpg\pajtulT_kmnlsmnXhbpkdonqnnrqkfmpgdppnvndnmonoqeomk{m{oltpnnoc`lmonimhohnnmmrmkqpjnofoopppoqkpnudkpphjoosoolmltprzomoqtfopiimskokrh|iilhoqploqnkmmnqplomomoj~}vormnnbjkokrmnlzlbrivxlq~vqtmggiknc]mopdennqpncntsz~sljdihovkjdwpnbkkjeefqg_pipdqylxd}equpohdntofoq_yffias|apmgpklagilipprjsv}cj`anv|qhg~fkksnopsjoqmwfwrflhjlommimpvlpfpenz`pduisktqnqpxmjqcp}vmmndwknoooltso{sngopzqtlmzpjweprolm~ktusnilovkpcnqsiWrqhmjrlnnglakssorkolju~kjketgshnfwqootipljkkntmjuohilm{qssnkllnnonnkr^lhpq]msPpfqlroZpiosnn}ymolktnmelg{lunu`vXokolnmpcmjmtojjnnMjljoomrpveoi~oqQmnfpvkoqhbotifdpjnqyZnolp]lnmrfmnnjopnjllvolomoqxllqjkp_m{sxnykmotvhiswokrok~ln}omppgkrtrqgkkjntnpynkmompfontpmm`bmtmylqppTxphhb`mmipuu~lponZronpyhoouonpfppnocxmmunkhnpnsoqnlphnqpennurjyntnnkvmsqZlndnlmsptnoqqfonblmYk^tcponmrlgbphonmphppfmonklgwuliiqoeorekrsmkkpqolqvmooornimusgoofmrmnpoupnoowqnokmnhchqlsmpl|entxmmqmryqqrgroolvpnnmlspinlsh[htboqnmqjnhmomplknlnlpirpjdlqpnaxtmnnvhnxjgomdn_uqneojjmumsnstngukvlj{mkpdmvjnufipamllnrn]noofipluvmmljponhtkgljcedeljkqplsljmlmlfmevxmlgXpjlfnpgmkrk`gipqppplgfysozlkyphslnvsjytmkwvunhpmksnimlwijtfZqymmjshfelfjhplpmrqdpwomnfiqjnjitrgnhgrlnlhoiqppop~kkjteqpmnoqjqqmx}nnhkjogqjmnnimqrnkqrlkjjknlmmlokasevyloiplmplsokrtfngzmgnxkiptncblvvxjem`jl|j{{mkpxiqd}ovktnrvsqonoqqjddrtipriou[uoplel[lhdluqirimp\wmdqdbfprqrsv[nnqqxmsnnsrospmplmkgipgpktoohqlri|prfqhnmkiugkjqnjnhpojqjblfppojurmpiampmpltw^xnrkjeofttnZnstsqkqnhonmglqolnlmqno_epoqrlgkgsrltigtklodpsqnkeoVomkcbnmmnrnethq]kwkrrhjhoimtgmnlohplmdikphvkdkillhlneihocqinhrrdoln[gqchjjmqUfmplhqz`xqqoaggaxolhgjzpubojroeuogkkkp^pimkcinqrm`otoecjnpyrnpptnlyom^ksnhfeijngnofiplhqkpjjmsolkkfiomcvmlnidjwmljrrlriozahzlhhtitohmvqlm`nnalpopfmlelsmjliqan_piqo^lrtjuukfkeqelYqhi_\hukpntU`lpZgicjpdr_popv[juV^WWlWroishcwjswxtcooulurdvlppuxhrajhou]tkopp@unshqnkOdimyoih{fiWuio[jqYisr_oxurnt]VsgdnidsqankpqimQfstrlwgnmslrunSsuupjtjmhnolnsqmxtpdjwrjyrp`skggmomkteelcqsnqh{k`pflqmnlpcnqiMRklgjmNvgcqltfL`rpvhgpnsairqjarprtjlkqWjhlihpqu\mouilwdkmvkjolkgplrmrllmQvnxgauoppYZkkpmnuhbqznpppnptocvumsfqjrenlnrmlnrnpopljkmjr]suphkklutxfumqzlnnoopiimmgiraqjhifpglgpokmwmlnqkoElio^simojelm\pjjghRqcynmrjoemhmpqmn|olkosmfdoutbissqjtvj|gpljtdmpo]pbn[qjrmln^piknrkobjnqqnqmtosobwlwfjrnriour_pv_lmjhinqlltgudqpnmgunkmopgnnmuknyhyqbloppioutrloelqkjngrlpcqpqseleppqnhngnnlophgmepemse^lcjhsrlkmn``okjf{Xllwokp}sypljmhiqmmlhnklrilpoikkoloozkjrqushZp`odkiivnjngiphemkmnqmnpntqlroimlrrkkomjs_nlnsitjimllfqnpkttnkk_rqjhnqlplfnkmjhjlonfpqmmmjiloavomqkhowp]oojmphflnliopnznmnijinquqmnx^mvmfmmqroqllomohsnaqnhqkolsp{pmrblmpovnlnlpoon^tlmdomrj{rsonrokpsxqplnhnlnnnrmollffksn_onbpljntsnjjboqrltlmn`ixpnxmei|mqyplnurrohqkqnnlnjlp`txmhlnfobrgqxonjuplnnZokijl^omwnlrsumhm|Xslhrqppomjxnpnlrnqmlpoaaowotpyopfjjookhgpgvooovlpmonhppoymnhrplbjjrnijlmbbm~mklpmlrnlhqsqqskolfcoqwp^lypmomklqqkmlprmmnmmgnosrp{`jrkkklnoioipunpimovolkjtpotoppmznuiol^mqgnknfnzmpvnon~UurpbnqklqlpojmmokoqnkbZlkpqllrmmmhnismzupnionkkemjwUpnnmupnorkojkmlzhl\qopkotmonlnpomonoo^mkmjlYsqpnumnTpponmkMrnzpplis{pppbqjvqlnn^qwkrp]tirolcovpwpq_t~uorprihvkoyptesgtm`khoio[mrqepnedhdnrkditrfnroptlrrFfunnysxoufrqorxvkotltikmomqqnooozojmqmwmpltollmopmlwnnsreojlonljeirouktvp_mnqojjPwtnrmnphkmvnqirebnulpknqitrWqrlprqimlhrmnvmmljguulfmtrotonilxmkriueqlnovloljhppq~vgqxmtknnmqgjpohkmyk}mjpjofpdqYimetf^bhupnnrhdbknprppbpmiom|tglqluojsovgkcpjnporipntqmhkokmpl]qekpwxrfog^vro`mplilponYlmipkgklplotnoqnmkkqriqzrmn3pjplmlkhp]sfsflgse}moqlpmjlmgnnkmmmljmnpjmlm_oqsolhllpqmvtestiureoornosxkqemgmqmnpkorqgljomplfqm]sp_rpnnfp`ivkfnqjdloo~`snqjhovlvjjneldnkjmbtz|{xbowjrjwhismmmyjgnqilnmzk}nigrovizpmormqoiqloovqeopysuqlikwfommoksthisgqisostalupllnjyuhqfxqqixompnxkejonqtngns`knspdpjnmiillkfmndhomdopf|qiqjmxkmoyxmnjorkrilpjlsojnunoskroskkqsjwvrnmjljpnqllpmrrllotojgivrmphufppvpsnholeppgqmsrqpdknomohjtjmspcdoornrjlkljqqpwkkvpncqtqjmmnozukojqonjsnwgoirrpmjkmoqmwqh|uxbumjotnpmnfudgmoiqfntmpnqoetkohglnnmnxusoomosmooimjnntcqkoyojj[lhwnkpmkpjgmoosmnnqppihnnsgphlrsmkcqpmnomlltkllfgmoqrfmne{rmsjljponrmn{mfqpmpnmqmomnljromaqpng_trkqtpllqjvogxemrnoqoodjtquknnahmlqlvpornwkkplosrvlcjujfssperllsgjrxtmsfjunqlvrmrlhjqsovnqna{l|qwqreuoldjkdelrtgnmsh[_kothqdobutrdksurioosnhdnmmonysilpslwjergunkkjnsteifsnomsxokouupkighpomtxojlenlo^sq|gojtojp{qh{ii\rsnsprmhoeqsppdlepoodhslrmlwpxslorlrp~wqvqpqrnlhqpns|kphbjngovlqnjmn^jpirmtkpnmmKc|on{m_mreridkqpximftpnrfpymfonpnrrmk]mpphmnppmmpnmcnldoilrnjpppsoihvgi[m\qrlqfkMhpllznjhojqxjmlllnoig^mmsqgjzjmpvrpi]sUknoelmyirjs_hrppqpnsqpmko}ppmUprrpvslqrRmlthqho\flmoqoqmcopohwrfprrxmdonkq^nqlrrorqmmmsnlnlksnncl^laqxdvkmnepqqcnhngownonvhroflinlplmmqZtqlrdkhhhqsntljqmmljiohmmlqnrmlpoguplnxklrkmphqolqpsfblhoj{kimsccpnlptqinrnfpolpnpsipnlmrjrgsmqopblWmopflk{polnqno[m]nnhvwnrfr\omnldoolmpponomjnrmnpeoltnhdofilvqejbjssoyorngpmlhopkqqlkngomnqqmjqmoxkmnoonpqqopfmrpoplrsmplmgfojssgnpkhknqprn}npqqjlmumjrkskqouquohmnuiyopmpg`kpsqqoum\o_npbhwkpwtmllnmkrowmljmojkwidniphonkmsTsrwktg[smkkmmjnomgfjllonoltmlnsrokqsjlnhlqyoqoZnlkmqsplrqlooqnqg`qlnmorrmmmlorsnqmtlllojppcakqlnpkpbpnqmnnlrnmmmf|smqmutotnmosktmpqnmqojpnqlkplxollk\lsncvpgomezohkqnkk\nqlmomnmpqhpwnlcoqmlnllomkr|nxrohmkfo_|lnk{osn`roaiqmopqonflzXjoYnyskqrxnjpmjlj[neumnpjTootntqqooktqXnuxjmZqximnqirukorsjlkngknjipkeqiblmpppkqkkmtalqpnop~w}orimrofqxnfmngvn`iljokplsmmnmlkorjqdafqrjonofpplooqknpmpnplporhko`k^jnrjroptsgvonm~npiorp]nopmrssmilmnsklqniklos]notpplpmmonpun~momqy^mvgo`mmnmmqqo|pgnnpllnuncflgemqcotkgpmnmnriq}nnjtoeolopwoqrqpnoplefjkeqn]lpljprqjorknn^ennlpdldlnrnpnmmlrhlohlmqpnuseqsnposn{}iylonpbpopkpmolglnqqmlpooopkrjqcqrjnonjonmomqmo`nomxdaakslimnzerplrqarppkxltoloonjlipqnmpjmplmspqlfmmmumknqkpkjminojlvmpprpkgqksgnnmtnqlejnbpqkokonqomckovcrlgktjlrrkopmnmpqsqlimfposptkmgqoomerrdnprllunmkfomlicljkltqincoulnomllnwjnjqqroslnjlnnkionjlsfpojooqonspsuol|onlodnolllplklpunldnrboopmppiqonoponnjpplZmckmfljmovshmnqmuglmlklogysfxisthngtmcyohioiarutpmeopmmkikuopzgehtshnbpnrproj]snolqzsnjvspuvpgZqefgpdtlvwmplkrpenlel{njmumiqdznpsrfxhrnkkrnoslnuqjmposksgmrhofpqmooynnlpfquoqkgqZqlrlrbjkksorkaqtpoiogliltogkojd{ujdsmkbyxotstxpnkkpiqlrvlcolhiqmomkooopaipoofhkqohpjmnqohsrgjsmprtqmlnqjoopososmqokoolkntpjpmrjqnnoqxprookgmoksknnysonqrzie_nplenemvmmekqmpkoqkkospmhijnqlummtmnnrnngmonngoxslqtsquiiblnj\qrmkjhtvmnlocnkqhnprlfoipnon_jtnpjkjomgkihpk`omkkmkpefqlsqosmqrmr}qmfrrxof}ojmn|mlnfuqonngzkwjotqmtqnjmrmmmnoqn`mmnqmsnsuolpmnorlrqssjlonvmmvYmnmoz^ujo{mmgmkjevrlhnwrfnkrhuxlhenenrnhizviisnlgkwnfqoimpnegjzamkmomrlplasjqniqjo`plhbkhhfnow\pxlgdtii`mprvhskl~ulsnskmonxhpejzh{irloijtslrTRvtvl~lhoiqomgvhbihpljlfgoenlzqqonno}nrmrmdklbhjroosjkgqlgtrlmtfqxrpupznknmrgl}oxoqwphxpnkrmvhnmlemhkmompfn|}bqgiazkhhqtjrxkfm|rbolhlgmojnemhhijfpdpjjglZmtphipi{jlnmojpllhlhmpbmcngsrgqpq~kkcnjsjmjnhoknstrmlWcqkwchlpowllmqlrsnqsqpjmydkoqkwWokplkklonkolrgiuolnppkophmolktnpnlekpnlmnpojimcimrqqmmiodplRlpnosftrxpqwgnmilbplnmijghlrxihpk]nkmvnlevkmmjkqfet|gnoinrr_knjtrsrqnwltnbenrgmojlozmlmpnmoapinjbj`dbjtpjonsgfqb\jtjlbmkmamgnmpkvkrldmpiim_nitqpqrwtngcpidhdmthnibdrj_envkmjonl~jjmlslqipningkpknnntmqkslsonomvtplopeqzlfuhpnpiulpicypuoklltojujmimlofmmklslt]prkpsklgadlvqkmkmnemhbjplntujneninwblkmgblrioqqpouplnjgnjlhnmsmplmxzopmponopoplinpelmdrnzspynpoopqsmml|emlqnnpimnl^nmpvmroipn]lslrpqkpvmkyoxhrnxntr`lnoom`nkkhqmmonwqpqipnnenknpnmnlpmppVfmoo{rynlxompfcmnhnkjmmqjlmpinmknpmymoojmojqnmutruoerwlvlmjoalnnShipliylqlrnjnkq}pizsolkkkllkmqooompqokmnm{kemqgnkpokqmoqpmtlohjrwmmph~pow`rnqegfrqlq{xeqijmbjqoijvhhocnncnqkm[nfgkugljwopihphqllpaiocgk`moogoqttqsmqpxpahwquugjlmoompqnjfVtnljpptcpitulimxokkczlol^nrmmensnmpikstqiroli}mhosionguhclokrnlijmgntukejxqnjnmmprpka[ppmfnrjqnu|mokvktdpwekjnjhpnlh}jZpdgronr}ofuphiplivchkpm`okhdgonqnkppgnwkllZpimlrmpmmomoigmhqjmnnqmmnoqjmromjndkpv_nmmuokkglneofplnmmlvmgqlyrpmsiljpnlpmbrjrqonpplhonnppmokxmloorlwlklpmsolljphmnoolqvnzknrnkoYmmionmprknpqnvjoppmno{qeoyhhbpxwspronksraomXpnsjsulouiltoqgmjwmkhzopponmmjnlklmlmjnpnjjcpmpmplnjpfnkokqymlptmeumkprgmjqimonjmqomolpmnoononj`oomloomnnpjdnppl`iuioornhlqomrnmogoomolonpjrtwqyqspqpilvjmqpoipjkajpjtqgnnnlhmognkpnskl|prlmnsokmnpokorkpmuhpknqmpmlnjlnrmslqlokohvoolpor_oinaom^omjumkpnqkjcnk_vmljxplnvppooqmctcopihmmmnmtlonmolqonnpomgjppsyqjnnmoppojkfrmpqsnjrosntlvhlnqlkmpopooohqnnpkolnehgmqikmjfmhhmvkj}mrgogrnpkijmjmlphq~hujmmqmlqeknvgtpnvtgj]oispfgkrmewjlknafoqijqnlpfuolwunbvkfwqntpn\oflrlorglourcogkjpholikmqtnomkkqkcojopgkuutrjpmljqm_xlgnowko]kqlpookrhqlyoisoom{qnxsjqiorrvgmslnnsiqojiikljplrqrklkjmkodomliglokp{orkhjlekupniqsmjjkmdgirmelqoyitprvnnq|palwmisemdjplsjpjpkgnpnmlximfynnnaqnsptoujoqlkftmrpri~kpol^vmjwkpmmpqmooqktvqogiknrvdnpuontonkonlitillwrlnrmruomgrvkpqukrrqoqobkmdkq`rmjikofmjoqikoljglkkiqloooyqpl~inrgjkhgqkoif{oprhmlpsjrqoopqpwi|ibnogimppn|mfqklknprmgqqjorqmmwumr^lnnujmjloomnpmllos|rlpoirong]xompmgpovldrrnnrpklunjymptoTvphoknrlnolnsmopomk{kolrongmhjjmrkoiqrmtkukmmcplrri`nosgmhklnmpmtmqplorpopfmtmtpoppfqixoaloqnll}{nlmmmpnmjusysqmrk|oodmnpmemvijprsrwnmnlrpmmklkkrknhmqoosfnqrjrlojcqmxrynjkngjrjoqrlmodquphnueuoqwo^mcsjoqrkontnjgfmhnkkmkyjolkrsfetklqjemhekWfmohmpjiprljifji^qhwnvzjrkcqbujfupfzplngqutqmr_eponoflmkpsmmnqphvln\qplmkkh^nlnkiucroklldjjogrommpenjlqkn_kxrrxsixmnkqqdzolmnsbkdipqnhYqmtjrnkjbrgvppnrqnjfmqklnssbdjonhjublmmhmjtpuolljoplnmjeprsjmnoenhoudjhdnokmldqnmojolsnxpsc`fdqnhnfonXwnppoqduoiokpliqmlpjkkfcvzuksq{otuknfmkojnfllqjrbjiqqY]tppjmxjlsnjl{pvnoqodoltkjnqqzZjrkpglsaqlmotrmkslvm]nsn|mjmemecsictmokiqxjikrgkqlmrfphyntomLpomxnehqXnjnpsinijjlsjljokpxmnsiclhjpqrmnoksliljlkomjkqiqngovrsstpqjilmoiosojqllqtqnloklqmmnninglhlonfqmmlcqasiqxleonpnonoqjnnllqhqemllokinppttrnobqmooolnjolrmqpwotqtkjonsknmqmtrrpinktsphpkpljripinlnmmumonlsspkkkrm|mhhlnpphikkhnwpqsopnmlkjoogkqmmmkrvntnkiioflmbjpmpqqmlpqoqfoofilkjpn|lmhllpjopjlmnomopqjhilkmkpnkmormlsomlloujpnjhjlhrnmpnknipinohmpmlprolqmonqjxlblkgsajpx_nnismnnsumhljnmoqlovourlhYnnocmmzpnnmpqmrkvknnmoknjkmmpoomnnpknqkoklqmlnpqooskijnqpsvnimppakpoknommrlnkorozcqlkpljprjorolipenktfonkolaqpupnjmntnlfkotmnlpoxllsjmrqnkmpommqmljropomtxmknodmm`rmlkplwunno^nfplpmkpokoehlpomoppnmulnqjosrmiliqlpkpooj{yrhlnjpmTtpbokrdnmqmfosneqommhmsoueqtdnmr\njrpqlkjhqjopfopjopqnmlqmknxqnjZpgsnmglgqlqnlqkokvmonbilpmpqvikntmnlyqnnnopclnlimoohlrmpmkkpobwmqpnooyptkmfmimiumnwgppllk_ohsmjspnhnrpmnnpnmnjetonmorcwkzookkjlkplnqyonnkzkojntnhwqmlrltkjrvnoipnginoommiqnmmnlmutmkllppigrlnugtqnsijnsnspnujslonqjmimioqqispnwtqpnkonhkgejkpklilzpukkons~kqop{nqwmfqtlqkjsoqmoerpoowprlnrmonjrnpkhl`tkynmiifkqtooi{hrnbmioqvjq{mjnokreesrmllmymmnvhnlmplplpnfllllzhrnnlmomnjmciginlrrjroqklkphnrmkiipvqnrjootjlumwjns{dnoijijgw`foovlnnepklfkkjk`ikuikelkgrwnko]wnmidmhkskgbqjlliorcirnhmowmqwptxmeekmidzgmbobnjokhjijonelqtffghlpmhioljclpqlSrkoqppvkoolpmsfkpooojmrflmqqsu`ka`nnkpgloyxsairsonmapmkqphshRoqnrhjmq]drwniirklmmqdkqcoshngiunqopktm}orihipjjvbpsmnpnr^qjwkgiqwkn{knsmuovqolkl|oljkmmqjoj}pubtmsqkumuop{rqilrk[hokltjsn{ofojjpmkkqspkqqfmqknoqkjgtjksngiqnklkirqnqlgkmmnjqoivrmiloolnkogtkopdtroieirjqnmonjpfolsknaoqprikslrpouhxtklnfs~mmklnvqkoeXpvlnquevmonmofgqvqkchlmcoeoupbokntsnolrtolloponmknomsjqpskklnrmkmppjrpfkonojkhoknloYnpnppolmlsnneim\nsqmommlnmgkmomnpmotosltonloopjoopmlnopnqqqjtldhtip^kninnooouleqgimnoqymoolpmoejookrnlrlqsnqonmohrskltonja|pqmkmrrlppmorpvinmfnrkknmplmnmhqodkrtlsmxopmnqmphps`mlolvgmllrpolnsoojgqpfoqojnnnkmppmppoulonvpfpjdpmlpmqmmknmuuoommllndmsnmdhqmrwihorosdngqoknnmmmnnksoqklmsvqnlonkpjllvnlljpjmlogkoplkho`qnqoslluomjmlhlnqolpqtnkotymnntkillpnmnppknrhetmokmqtiomomlmmqvmsnnslpfnmkotsqejmrmwltpprqslolpmktnllpuqnomlli{llordjpmqmimjkkmphmsmypknmsjrmkllkvlpnqomjmksljmospkqkponknknoqhqtolnjmnkolnquqmlj_jkjkmnngspmipdqkmomjdolpquuprpfoionhmrpoqsknhgpkomplhs{pk|movapsnonolhptgsmmkknohkpnihmwkmrp]rrtl{kfiknmmkgpkiehlqrhnloopllhcqjmmllkqmmjltorjpfjamoluploklnoiqxpqmookrmnmgplmnnhirjirjnoqnhmkkon{kjherqkjijpZsrskmnlsomqfibomfhmqjlikonpkbllnniprrrnrvowskontscrwemmwpsttXjumrmwmronzsnilrtgdns^qZquptlwetmh~gmur{fooqlpursqlgmttrqnomrtlpiguovugptjlrjl^prnrirkqouon~rxqtl~qpomoosooryRrpvokttiphnrzqxokofpfnyjpujisqwfjkomrimpyqjhwqqqgojlnfssrjgPqkrmrm_rvlmrtintu|irotdrqnjrvpiqmewfdmuyqsggrufqlrqxepspmzp`sqol^ntjrqrlsqnhinipmeuflnlnpophqnekoonnnmhormnmrossxwppotrmkpqkknlflnlokglsmkronijglkkorholnfosooqorophlikrjnpnsronuqgmpqmnopopkrprsskjfmslkriprmmnlpqoqqmhqkpofookqisyjjgpppimrskikpjnkoszpohqurpgqnppqkrrekmnqjroplmngukkjxqntnpomrlpoqwuoyukppmquunmdmoojklqts}oqlnthmmnurlqvpnkroqknspppizlvmknmlmoomoj]qjpqelgqhr]lnotnnjrkn`memrjlloflr`kkosj`qzoumlpnmrpvnvmrmimmplqknnmjmmso~mqgno_jchmkjhoiqiipjq}aiimomqmzlmwnnoponktpiZjnrknpoct]oblnnozdglpjmmrweonnsnknggnlojoiqnsjrmjrprnopmpmoennoooqolnlojfnlo|olkmkupkjpnonkqjumtklmmickuplonovnpnlmmmk{fpm[kofpmqnoommopelpwolrmnlzlkqgnmnrjmhnuppplnomssowjonqsdgrwljmlpolplkxeqnmjnelmjndhmnppnppivuqilmlhmkplotikrmrovkrnnrljojlnkmnnpsoopolZqqirhmkbnplqcreqsxdjzqmosptit|lnpohmmoppkrmnrchkbqn`kpqppplnmpmnmnmilqoqnpnkgkxopchorkkqugsdm_mppfdjhkenorhojpjlhnrjskorhljqcutznptoigncommmrtpnnoimmiliqqoiqtmtjpjogxkpnfsjpqutmpnlmnulshkpxnfwunppjrpmvulqirnnsqoollhjrpnjmjnofkoolnlqjkplornqqkpupolmqqqmtrkogoolgmpolnohpdnkjqslnlnnmpmrpjhdm|mtoyoijemmmjptsojssltr^kttnlpqnmkonoirbmqnmiqoltnrqkmpnrilplnniidlomnmnm]kjpnnnmnllkonppeknnoqsipollknkrujhumitjxlnpkrmjh^roprmmpplqelfhfjljrgqmlqsrjmpkomalmionoptondmguvojmoooheqhpqlpqqpjikkufllmtokomjml`olmsdlimninplsloohuelirfjkmlenagoqhotsrmmmvjsnmrnjjrllmnrnjopjoirjtykgoqpjqllnhmponcsinnnpnqmmojlmimqjpsrgqso|qoomnknanpkmljnnsonljpnhppmoounmlkjppslllnymmjtnmoolhmbkoluorqnjosmloookoppnldlrtlsnggnlkojknrptkknoqolmjonnpqmlplnlikuplqylqhomraouoinnkl|nulokpolwolspknqmrninlljpnlompohnlqolnetmkwmopropkk}ppmoy`qq^jknnnnwrjyrlwqnqnqlqppmokjokolkngsslnfnomkpoepplmfglsmnhofenrmmnfnpkjhlklnqnjurunomilgjpjronsmnpofsmopstklrppoqmsmmpqmhpospqqozkolploonnrmsopqnnkqqjplnrtknovrmhknnskpqlnqsk\nghestkojliiqsnqnvlkknkemmronnqqnmnorpmrpkqnpjurkqrlqooqmkiopjkopompmmsgljmowkpplsltjwqrmrirqnmlpllqpmpikbnpqkkqrtmntpkgolnlllivljniqnknpsehutrjplnsnknmkplorqql[_mnnntmuhlnkikkjrojnnjoxfgqpookmpotvinilgmmel~lkosrrpok]pnnooppdkjpoppnmwgmhno`gjjl`djkkrmjqimhmkrrlkoliuwowksdlcdphkkslhmnpjldltqkpphimlqnumgnvhkqrmlulrmkmoqojnlqjnpoqkm_joqlolrkapi}rfjiqji`mrvqqncqintlllnrponononminmqghjhjhkxrsnnlurnbkhhosbplsnnnnoqklu^iqmlpooioltidkji`kgrnjnfYgenkpmqroofiksn~ilspknohdqiogpjkritnktpjkizjdnflavjpgffmkjgkmk^inppm}piqtnrlknnsmtkwVpiopjnnmkolnaneeiqnmmqqgjpopldinmnhljmjjsnfreutklipgosfulhh`Xkmkljoppfoprojmyqlqppwroolqlkkqemijlmngmqzphqmnnjqe\rrjjltqintnmncpfpgrqnqrsqhtnkiitnommlimmnkjoksljnnfkjoswoimlhultpqnmoooinmloksnhhlgkqpmsnlqnoomgnmopolhlmmhkkiqiuomkklukdnresikrvjgkskoioisupjjpnqntooiljkmdjknikmlqompkmjsjkmfrssnrmnkoocnikqslrqljlpgjpjjjllimomommhsilnjsfglmnqomllmnzmejmhqppnnnmjnnolppqovslkojiciomwmnynrskikkolfqqnomncpjdwmpl`gklohlljininftnimkmyimudmfymjoolcnkkrbnloiqqoklmkmnkqnowlilnkjjirrsoivlj^lxlkjolqpkvnmqojlmrklpmklgifprjYljoilmklqqokwpmpgoflkmqi^plplnulesjlkplih{jkjksdwlmponglqmlg[voppnitscnqtrqtpoxnnklnmvjpnwkmhlkkrmnmnogfmijkmlqofunsomsnjofshtoplepvorhjpjnrlkonnkrislteqynqkgjlsnnhrenelkdosfjpuio^mlkipmwohpimqikeqllkzov}j}mvjnmkniijpioloiylsmpflqmnlrlrfklxVmkvseqpommomjexlokn`onotntfrlktojpjmnqhomkimfrpipvrknlnlatWehlqnnkolemjjcmikwmmoSojfnujtsinojqmlosjphfolmjrmktkqp\mtjstm\qklk~lsoowxonmfgwlwsnlmogookzpkwkmjgrbimmlmgmhmoolnmminpgklphigqpphnslmrmkmphqrnnqnnlirqpvmriqmk{jnhplqjqqodnksjomlinpnprldsispnorlnrrfroqspnlirpmnodqkrflrnnonlmgthpmjrniqpnjhpmsmprtnmlmppkowwphqommtpfephkminokrijrlgliupleonlnphkommnkkmipmlmtl^rlqrdimjmltimlmtnxnoomjbqgptnkqqpglghhuglgkmsqwtmpplmsotkhhlwrpnnktpmnuqnopnqokimfommxmmqjonkbmnjkmmsnmmomopmcqkjtnkmxtosloqqprpzuojgnnwllprmqvlklqntnoqhlrionmelfpqmjhkdpipmtrnpjpjmgiqkxrmpqonmnnnnkppllrnm|lhoiqnoonppljlnklntmnqbmvmpngrpkr{omqljmmjnnvnkumikiomqlotimmvnknijpnilomnnll`pl{emqoldonw^jgfmoqqQhnkrodolnotrjcgknqiqlig^[aenlrplwriddgat`iliqlmdomuetderqkjmnlsgdomirldhmvineaptoj_`empgoqtmpfk_xzopfmq`keqroJsqwpreiitfgmvphbmjymlplolnmqucbktjjglkpqyhpl`mepnqkrtvqrbjfGkkmtgoprcmoxkojm}lirnnkphbsjlorm`perrknlqjtkiqjfkmdkcikopn[pudksmnqbpklionmljhqkknmjmronzjqioqpkjomomqRvjukomjnueh]rolxoqjurnuihloolmmnmhppn~jtitkjyknrjnqplomhmnnqjmjnmkroutpnotqquntqoumnlpzmsmnqqlnvhnnwmumiommoloqnmmlppkkkrlnlnppcmqqriorc_mwlnoodmnrprmeqimnmnnmnmhsgolhkrpinsqnskwomnpmrngklo`wmflkompmojlrljelmmlrqtkrkicmiopjtjkhqjmneos`goslllqspnlvjloqocrkmlgcskrogldqqafslpspkqlfjrkomroiloqoklomsopqrjsgvgxihkoklddwirsrlhmssqgjl{mhmipqkpijnsjnpiqmdlnymtoljpspxmlnjknllkindsnhtqttsstmquqolhqlnmlonlcoqwqnsgk{isonrfqlitrjooknoliipskrlrmkkmnngmpinkkmknnvtronimoimlifqnemkmewlmqoooltknjjrmqniqrpkompkqhnoonjljqmkmmiplpotmqpopjkkrmnpootppijolnkqkohlnpslnpoolrmipnovqulqstnqmmqpojnqnqpnplntmnsnomqnqmmnkhqqsnsqqqootlqoiorshilkpvmlpmqinijpqlslomsqnpvnjmlqrioktkpnmsestmqknmomiqktqqonqrmokximipmormnqpmlnqiinntnospsoppmqnoomqnmonqkrpriilhnu_spjlmrnfnokoqloqjnmqolmbqmiqghmsqpooegkionqsrplqoomnmgnpnprqmnnppnljmnsoopmpoplmmkmntllnlloomlsmignnkmtlqfl[qijtmjrknluknghlnknhurspngongrokqoknkoqlskklqksmrkurpqmrsprmnmmlnrlllklilvlnjkikokhjoomkpojnoqjhnlmoqmqomgoilmlokllllnmqlrkmlpmmspqooreologltplmpvoqmdonokkpqompmnmhlmnkomqmklgimmlislnplqienjogmblmmqjpknsljlmkrpniomWpftogirlkgoppnprdzmxhqojkpqioknnjr|ppndrpcrmfokqlkpqrsnjqmmmY_olnnmnlwnnrknmsqkponkt~oljroodqnekmoki\kojnqlntnlvmmnmgfopnopgnlvidplsmkmoimkjqmmxmninlhompcxwummowknlfsrlnpexmnkhrmjmrnjlonppkkmgnjmsvoknkqnnglsgnoolllpmnnntjwmijnklgnjnsmjmhnvqmspnojqkpnknhgpuwpkpavnknnmlopptpkpnprlsmjplppjlpnmqork|jmooupnkllsroknopnojidnmqiqnpmrpnomhgoonqvbnkokqlelfovqpzposjlcpoofkosk_elqnprommomommxyesklsoqsoqqjqlokmnlpgemnpj|qjojqxlmndonlkiedoulxqjtsgrjpsklUzhnupiljmcqmqqlilxnn\ktqnnki`sood|us~oeopdpihssqqphlenntunjnmlokOjrguniubrtqkiyowonjqli[ktfigrhphjnn~sklpjm_plenhfirmokm]hsljm{miksk~gnsphutknkgrkfopuofkokpmrtlpnjpmqukrjoqjqolsoW~nlpkfjmphquhnmtqnqriaolrkonfjn[ldqdnjkngvjmmllxftmyhrpmtfqhpkrpnqksmnmepmkkrnqnmkjhl^qonotlrnskllmorortqlfhmjlwmmcsnooskirovleumomprlprshhhlms`soooooplmlqhnjjqlkskrljkntoprdpopjlevoktnnqjoskronielllipmiojmrhunnnnrmrohmrmiumnlrjkqmchjbslimwurskpomkqlylqekmliukmljntoiknnp`onqnnnqrpjepnhkupmoqroqlrsqlmrnmormtlpoiuqopjnurlpn\jnspxnqqvqrmtmoqmahqnX]qzlmmnmpqqmonzopmnokhxntiluoYolj^mntoumjnkqk|lfrnhqfpouxpmonrnihmtmbnmkqlPommkpnobiqqqiinfllmmwvommkntsrgqnoddmjnmnunslmsollmlnpnrkqZmlpolnsrinoionnm|alaomkkxinjafommskmnpmmmolrbiqmqokpmqmlskjmmnmrpkiqknqd~lsmpilpsignqprpkinoljuskkmjupntgmgojhpjlivmolkoneqomlnlnlknlnjkqlkrmcsh_sksqgpnilojinjjrmjqnemjqkgnjqpkkhilnrlooofejmeopkwggongnnlkhvomqzotvmmrpkekjmmqnpjninnrgqdmmqmokjminpn{mkllssmknkmpjqslhnloooowmoophpjhpxqlelhjhkqmnpgqljnmyqvlplrnm|nljqtnpnpjpsinnpitohnplmkldrmjnqlrsmkfnjqllrnisolidmkmomplsmomqlimnepngolnimutpnoekjlnmnngislulymelqnznmzshrmonnmulr`pwjnozeklrkpopipkrlepnooknmmnjojoliimomntzopqq{knmkrkkpmmolnghoonqlooXpqtlnnllpoolqplppprmpgrgodijkoupkmponmpwpmieuosqqeormnkgpmootnxskulmnlminpngpmuoinmlmxehjlomfjmvfklmmix^osmolkvphoteqoopnplmnpkkmmgmrtlnlokipkkmrlmnmnronnnnnhtmoflilnookiuknqlaoilolmtonsqjtnriamtqokpounmpjvnoksmpmrlorklprnonipseskopeollulpmljplpndwnhmpkrkynilmnlumhjrnoojlkplnoejgmzlm\pqclgqnmkojimpshlojopllcimtmnmslepjmjjmnpmnphlrloppopopmlikykkjilkplwploohpornvnsojin_cloqkmknpkmnmnoqosynnctkoqnojonlonmytlnlmklrYknhkmovlkonjouifoolqllomunnsgfgbokkrnmpnssnmkljlqpjtpkmoppkksopnfpiwokokbtnnmtollqjkmocrnknjkaosonjmnloklmppnelpmmpnkwgiopnlwncotrennkmovnkosklktvoltppkqboqrptrloplpqlpmrpknqlmlfmonptnrkroujmdidoqsojjkpmqmtnjppwpmsolmpmmkoqplmondhlnhcnboqpmlpsronjgmskmlindlnfokmomqpmdojlsnmllmlmodhn_mmrrsjslltpnwjppkoopkrsnjmlvlmkrpsm}mlnmlrnnsmkllroqhmokmijVimtmmptsnnmkoshpqjkkdionrloposmjuikomt{ptmnmoqmnmmpnopq|nmzrnooorWmvzkoylpnmqjlloqkpkommjmoexphnqonjmpebomlkhckfkmqsooloqmqnpdmrqgolnimoroupnn_sppklollmmrlmibnunlplmcielllvmsnmonujrqnjsmoinkhksomckuvmilqqnn[kpfiknpumxpnomjonuhoknookntnpmtrnlpsojsirklodxjlmlmvntooopomvoinlqm{kmnnrjplhqoajnqpiokpdolmlhjrjlhlljchnmlpnominfmibtrbonkqntltnjopmqkoolo`icnopotlk`bplooqmqknoumotfoolmokooitnlqsskplqnnjlnjkrmmovpkkmuoitnqvtljuljoodkkmvqppldociskiunjmsqnglhphvsfknokztmlpniqkniwrnolruimoontqpnmeppirtmohokpkrqhiumpeqkplokjpezqolmwoglmrjokuyonlkspgqjplqthoppgsoplvsljkouqopkqlmplmglnodgqroogjtmplnlhrlsogqninosnkrhxjmllhminx}opoihlguoogmnknypkqontrippnorhqhkltqoioljpqnkljnnnhv`nekmkmmurqfqho^ljjzqnormoklpklootMmktsrengvwkkloiojjs|lnkiqqpqmlvkononoiimqhnikocrppl`mjodjnonknnqnoosnqlninlnvmnnlomsynlomrn`vvmwnumpfrolmnmmsqpjkkfnvqnkoroknuiiozljlqommlongmnnnkonnjojobqnnspkgonsuxknpr\mtmijlrdumrunkjnroskiiuqkgslirlnoeolqijnghnrsmmnhfljdpihpqpjpoknnmolpkwiionmjcoimplqnuhnphkjghouklpmrliqmisdrjrimolrsgpkworqniusomoompljpphoqnjjfimpjmlrtpnrpnleqtoomolnlslunlfnonqkojjiijilpnvkojomslkinpnmqgnmjrsnoqpkpknhngomjmkolomkmgneqnlvlhkppskksrflpitqornirjtwcuqjpfbokpyqgpsuowkljrnjmrknsmsnlmmkpnqoonj_shmpnjjx\odqpkfkkkscnmlhjgvhlmmmtmqikpimqnlpjnqtogplnnoorntixnmownepkglgmqnrqmimhqnojmprmhtnspnglqaipmmmqlnvowu`poqtooryhjrlhy~omcqpeqnnjvkmwlnlionopjrjijmiqskqqlpzmot\tnkpfjbqmmnorjqlpsmsllnnkmtsqamlukjnkqltsnnompqonknrlsiopmnonnmtiomdnlkqnqpmmqpmqknkmhmglw]f[jrykdoplctmwospmpqikkmqynfrxxhnr{oljqohlrjrlojqnznmpmtjnphoqnnlocomtpellhpoqjubqoonhwvnnontmlnmqoinnqmllpkhynnsomlnvnlqup]ps`}mfmokjctnnTqnnoj^lkmmojntlgu^Lor{kppmpkmqplnilojlnmmj]dkqkoyomzlsppqntmnxnrkn\_frpprejkqpimnipsmmkqlljnlminqiousunjjpslnokfrlslrmolnnsomooiqnstlpqhbvgklunuphlojingqnknwmxsgponscnostzqnrqlrplqoismfnrqooqoeokjhtpyqprptnpkkkohnplnkompnulkqpqqmpmshmnpmq]ornkrmgsmsqqnqmrlnoxopkrksnxjrnntjopmnkndmesiyncqlrmmpmmhomlnmjnnnnipollokqonnossxqnomsrmoltmqjbiqlkqlpprhmn}nhkmnmmlnsnoqvklevkjnovonclkoinjqmolignjnpmpip}ektemtmijlronooljkkrponnircqqnqmnmllrsoomoynmmlbjnsojnsolnpmme{ronqnjmvlnnnpnmmpmpqrvcmnkonmuqypbqmnrwhiosnnmkiwpqmlnlmmnnm|jpmmjitpuemmljolnllqkowmmppnxlpneritnmnnolphprlpohiorjljkpokovdmhoupqjtjknpjkojsqqnmnjmmnjnmkknn~imlinrqortqgolknntffjmplsknimkljlkppnxnjmrfllnjnmoomnljmlkfkinhokilkqfqmp\knfnjkmqknindomjioppqr[nnomlonbmkjmkmoolovmmxqrmiqnmkocmmooepnkshmloonndmncnmklsnomyrqpkrrislukomonqqnqnslnmmlnnlool~iumnnknmoooilnpo{jplmjoumqfmvfkropzprunhnilpjmjnpnkkqiojnopnmpnnkonkpfrndlpsfrkmmnkgjuopqxlqmjmork|om]pqpjphpXlhlopskbvxfqmfmqkormool`mtpullpnjptlpotjrpnmiakskqklqnnhnxrxmopmknklpcuotksoplmqjqsqnhfnsmo_gpoiolmiuoluxkoqjtqqwiiqlli{ijkpjthoqposmoolqmvollsnortptlhkolqzpnkqppuvnmfelpmhwliolqnjrllppsrtjrmunookrotnpkoxnzrlrooqhn{pkospisqmncqprlhirporfvlpmorsgiokpnojupqpnqjsohitplmnmnfdhrpnqtloonkimglsoqpoootpoopinlmorpqjmmqqlinqrnnokonvlnnplvsmnxrlooonmgnnnloptkpqopdsrjnusjlkpjlpyoo]kpjjoxmntgqormgnqohooopnsonnpsnqnmsruuwkjopmjqmrixkqupjeoompirmoromojprsnpromdlmooynnqqiomnlnjulngrmmlhappntnooytmkojmiomokumjloVofkqiolnomppt}oxkdhnpugjnvqqoonroojkpspimrfnsejkqhngqnonqruyhknhnltfklinsoosioominhmlpmpn||pmksnbmmqkmjoohjjjni}mqojhhoohmpqnqucqifomtpnqqnjoonmmrsmonpnlrsrpthononqthnklsltmhnmpirjhntnrirqdjlmppxrhrknjioljlrreollompmltqqjo}uojmmnlpjwrpomklnnioolphfoqlmpuonlpmjjnlnqmmgqrreolnplnopormwkmqmnhpmoqknoprjonrnmosmnmjmnfjlimormjnlrlnlmpqljkofnl{jltroskpomjljmnnmotooqqknmpxlnmnokjnijonoslppomkxnxqbrnoptmjmjjnnrhqnmtmqpnnmqnikpmknnkljqjpsilxikkkszks]qfp|mnpfpffhqpnlntqmlmllnomidpopvwvjrochhnppkhmpqpkofqopwwVnpifyrkoqspshsnhdoosqqqnpklh}rnoleleojklmrjokqoouupllokovisjXtqlfunmdlnmnfnulrkawgpmqwqdpmqu}pjgiotkqr{otgnsfjlnojgioklolfksjonnemwmonwkmtlphqdi}hjknutodmZimdppnj[tqqlmpsvprmqnuodkpskntsoonphrfrulmnnnwprumiloojolcjkvmwrnvoorlch{imlppcntolopoppt{kipomlmmsqsoktqlnqlnqlooiorpgmrjbqjnpkiflopjvipwnpkym}mtl|numnnnnposqgmlqqjnkgnploqorkrnwm`pqnulnupkquoqslokoqixiovvoilmoxlmwunmpmqunnmqoirfolnsrhmmllfqznmolum{iluljjrqpnpllptvodooppuplhkoqoYlwholpoiommntjpnamqmrsormqnpnoyjvnnoompqoonnkkomrdomcijcpqjlnnqohnttkmmmipnulqgqxktopqrk{rpnmmlnhkpnoohodmnprnlnslnup]kminnslqkmmsqpooksmmm_mimnoppnnmqpoomnrrnnno~cpkmlnqlnpoqprxrdaukrnlrrihllbrolnhuolnjlonpjejj]sk]tqlnomoroqnmmmhmoqnsrpjppnxmnkzonmqmlmqpopkbsnkprdnqpnonjfmnlllrkjfqmnbnmnlrlkmkloomdnimejqijiZrllpmonrmnfptjmqqgnjojeqbjpnfugnlnmokpsikhlpmmkjmpmlhimnwqnqmXmponpmodkkinforqgznqpn{ninspmnkqjmnnnmsnlmqldpmnommqhvncqnwqfrnlxomnjmns|imjrmrloummoklrnprujjanmvoqrknm{mqoonlnknu_emnfmlloerjimniWtpvh{jmlpomqhipjrrnqvmknupoflzjonljocomlnrksqpnmnmhplsvu|niocnomkkrkniisnomulojouorkhtssuklsnlooruo`lxsnpjjdmjomopmoompntrrapsnkfcrkinmkneuolncdpgnnmuttoqmnoojmrn{nqslmljonjkhrpbmnfnvhjk_mnmjuwoqvonjrrtoqplmjooptonnnkjkppmonkjnnnollpoonnmoiwjjnrnomt{lolnqfoonoqisnnovtnlnikjpkklmmmoqopommfkooonnqoolpnmthocqoopulngoimxnplooorqjoqlsonpmmeotgokpdjkrpmhopepokpgkobgiimsoonpiromp^knojnmmskopmnnppnpopngsypoonmninkpnmlpkorlpkxnmnnoqntqenmjqZnsnnlypmnoqfnpwnlongsol]npnlgphqslnnqopinmrpomqntjmmwqopx^qkmmnjmlollnlnmmlolkjohonpopjmpotnmkwnhmhsthljmomppunnnnlnpqnluqnwqirrptnfiptjglnqzomknxlopmkmtko~onxhmp^iuiqlhkosugi_oklhfgowmoylo`ankvzb{pqknrlmnhjoksflopqqrulmillpvoopnpphkgopordqlknkklpgpnQtlnnnx}msmmmgotpnwfmknospppmkinrqhlroknmpnronoogoonntomakkosnsnkdplloyc^kooluprsljlinknpwlqolqjnkopmmhkomjmqnmmulypqnqponjmkx^lpsmeoqiwpkk}ngksumgjiqmlmopgja{mkdrghhkogknkmjpmnlokopilvslqgproogmlmrmqymonmsrmlkvmdmdppopzuoolpekunpsqknfpomsnmmamqqnmjiomgmorof{vkepnqqgqmpepjostkpqrlkmprket^wmpfkmoqomlloollqkirqlnpminlulkolrr`nnonwnnhnplqpoqojdmrpkokqrooloqloowqnonupgoqqkjonpnoqhmkklskfokqhoplqntpyjmolmkjmpnopopzo`pplgkoflrmoohxnrrqimmmntpjkonnqjfogmvjm\mnipkilnplqhqncjnk{ucjnonqphlhqnknjqnpprp}tpmjplrcnsolkkipsjhmkpmlpxhlmutkomfdlrtimqotmsiqzhshmmjojklhnnoqnnnmmmmhr_qjhlkmmhkqloimeoqompnpxklonna{jkzspkvmsmu}^uolqmprkgmdvhl`jnqajikkmuhnoieqfzdndpiwnmompisihupmpqmolrwulqjlsilmqnosjmlnjWhleckjknginnrdommnnhlqkimimosja^pgkgghkqlrisnmnhjmlm{sgjhxmpmtmdhoilkjmojtkhflnpksoqsmquliqqSokillglvvko~kjmmpooqoioqmjmqeardkmopchoqepkhlrfjirinkspmokqkkmujnntlqpuqqiamnomexaedokounrqpqnmmilpmnnojlqaykrjqaprnmnlliknk_fmmokmkoklsnotqkiszwpsmlgojnmumosmm_g{llhpimmwcjnmhjg^oxlhkwqlpnmur_sqpoprpvnqnhstmlonllkmhssmljhonosihibnnnnjvknemklmmrnplrqVjk[rqerngpkgpmoneilldskhhlnrnnonmnnngrmhphmhorvopnndxtnqqipunpexogk{lnftosnimpqlrfjrmppptnsl`konnnurqiprmkorrqnuncsfbuiymksmlqqdljbjnsoppgnqlorllvrrvxjmksxmxulyohffmkcnfnnhjqhiolhjjon{p`jjlminootphqihtwfpmfnkroykjmhprlnvl^mvpewpikqeolkntiktk}outgnpijjwplfllqjtpsnyrmdmtstosrokivnqpu{gknohboninootophgipqnnsqbugokrsqirisnljqo|wojqnnoploklinlrlvvplubozormphpionolyknmokjxrlt|kwnimlksnnhmmlnmkmphohxnhiswjaynpmqhlpdrmmwkmokmpogonuoovnommkllgnvmmksjuntmpnl`knlhbeinfopmnookmsoomponmjmlopmpmsbnkouqqlnomgr^snnlihmmysmlomqnoaqnikor_qvios~noqnnkprnspllllnpooxlkliqnenkopsnpjlcdllngpimkmqnqqonjooickpmtonkqwokofmjznqpjkmmsokoslpnnbo|~opnrjvnqpkpmlldmkkspprnnmojwla`wdghlntorpnbpkgokpp{nqiljkmtnnnrZpoionknionnrhnlonknrleojjmtmonhkkkommqpmmppockolpopomfonvnrrotolmtknpldhrottmpmknmlrkmnlqogqhkmnnnnlmkkrtopmpmminnonpqnhplomnrrmnmqrmvhnqmomlpgljwlxjnkr|ksrkqmvparppjmqjlnhmjmwqoakgjpqrwrpioklsnjn{wcomjsnpjlsnxnetpjmslqmwmlojrrgmtq_ndohqlnpnplnipestgipkkwjnpyrslkopnsmulknjpkklolmalpqoonuevrgmnoxnozpjqpffnkntqqnnnlhjqfojprmlolmulyqngepsqtjhuiihmqlnqwnbtkqmsplnormmmrklnlpnookoqwpoilpaoknrmnptowdxrlnkjvgslwjpbgpqklrnfqnmlpqeogfljkjicnfcipfmilklkopq{mgrenongkjghiomijrluplorkymqbuhkjhmpmh]otv_rfrjnlgfghmglnnmqffpntmjjfomiomumnUnkkmsgfeljonpthllolmlojlurtsrkluisknpjvjwericugqksqkckplexhSdmgpmrlskipsmcaem~sjpurruninvlfimjtjqqhljoijniljen^rhlnatfogr^nvfhjqgepjdojlfefqshtkultkjovin}jxx|xlnpommlqcpkjlnnhcndqeniobompstpmtsoslqpfnpkkqpvgpyifkYr_uppfomtssqsxpeudqrrsrngmrkgospllxlpnnmdolhuhwqmokyqcsqlhknZklmzhflombojdgnrnkipbpqrlrbjrq_ummilkkivhklpsglgckjwskqppcoths|yjdioLptynokrjiqlpknmdolkrnm^jtpmqklwpyonomtmnnwrffYlgtkngksroqhnmkgmnjtdaildsmpkkthmkpptkqbfrjfjmirhmoZopSdjmmtvjqohlmcmpqrknooj_pfnnylqjrvloimemqnmotklvllmkjsonkkhlripimmnknkqFinnninmijqvjfkiklkxhlm\oliqooljktposvohpolpmqqmnpgpk_lqkfopjikkymisngpkvmmighpjpjjrymjrkmmrrrrrppsihbnnouilrghokjgsinonpjqksqjjjlolbosnnjnnmvijmpjoihjpjoltollnkgp]kpucpvlfmmmehokmnnnpkkmsmivnlmm|xukpgoojochj]lkionlkprrknsomwpqonkusoommtonto{mssffpmktuloloqhYprsliohjorqpr|qmnmopowsmndsrtojibmkjoqtolnnkonlnnqpokonimhuopzhmotrmblnjpmopjkmpjlklo{^vnqkojklgopmnmgngknfg^lommiympmrljnkmmnqrmfookpnmrhrlnmjkoommonjolnqmoqhqjsnnmqnuiormjpolmnopoumf^objmpwpentmqmlpikupioooepvpmmimjmiqpknwlnqqlmrnnknmpkrnalrnz|{no_leo]kmgknnqpompooldnmnlmjuhxmgmqnpy{xpwjononrqnqoolomVomtlmnjnkrfsrpo^oqmnpmkdpnknlomolopjloto`ninoxqYoporZonpmonoghmnvos}orgbqntkok{thnmnlsqnngmqhnmoporgutpdnnrrocjoqnqqqljkQopooldrrsgjpjlknkhtogmok]zkrtncdztpjrmwhjpm^trrhilpeotklvmqmmoknrgmlqzpirmiqltlrloymegqlzonn^pirzqjlloknknikqjrtvokklvphoqmpljqtopjdrimnknj_opnporhtcqpqaiiqppjiorqojkjqtlmjujtokqskiiskkgjomqmmYnz_qrohqpekr`fpmtlolkinnmommoqo|opbrnqluolnppnsgipgrscpkelocm]loruimojpmkotmjik}opltornxlkonfgnhnlqsvwnpovuioruiuurlbqrjwnpljglrklhnpssmotjqqmimjjgimqlvhgkuposlopqjsogfoklpdksenljlimoqoqumhjrmnpmsnmiulptqtkfqmqgwltmfl|ormwqklptlsnmglommnrlskkhkqrlstkjlzmpplospospptktmonlnjwnnvprnmsnjlrnlpnooliucjlqoommnexjqqnemhsyulrrgikphhoepvdkouq}cxrxmkgvqnreyrniolquyplonrsksqqnrbon`nlqqcsmhkcprn`rnsnjtnklnook|iqimkqllkkrortsmjugppitrkomrpocdmmkhohqntumujlgjotnmfjorfvnojr~ioidpllsjkiolniqlfolmplvtqoqkbklapiorqnxvjkmlppipmovpnmlklknmnl]omniutonhdkmnqnrnjqlmlpqnqljmioYveiqmnlnklclmwmnonppmorlkunsqmn{iwgsqnmlkVimmvhnmkjnplotqkmqpijsoosvophkooonlonpmiqomlt}qpnfjlmbnploknglisunoqflnkklm_tkn{moaqebkkhloponummknmjnoepmkmqlnfnolp]tomlmboonkhnsoqflhvmlmprtnmsmtmn[tjoopikoicialppnojpvpxhltlllzmoiortnpjmjmqokmipqyzqjkpmrjnvl{momlnwstpmmlpirmqrsouqqniiisorkoslpwrlopmkrqnupjjhjnmrqmqnmnppvqkfthiolnvotilllppsoqftlnkzwornnmnjrurqjiowolstklttmwvqjkihrnjloswfrrjolmjqmmnqhnsvmnp{slrzjsfqykosptkmfmqnnnmhrigmlqrnrqnpnoliclrvqlnanmsrsqpnljqphnnmluegwoiqmtop_teqeolnnposjkfkoqg\mjimnwmmhghqrpnvqerkkqmqlneriopbmskomuqkqppkkosnponiimgwhrhoinenipivjjoghivmtfjitsmsmopkilnnmaoprhmkofolllikdqonoorrqolnjminkiflwljmgiltnmfpriljpjemorkrniUomrmrpncfkkzimphlimrkqjkmmwquqkorsjmqpjskpnqqmjqeqhginlwpopjkqssopp~srupklopoptm_tksqnnkotkqeolnkmkkklliksnloomugiqjrqorokoglorijlmqkkpdsphn^qqiotnoopmrmhvk|rromnuufnvpkjonpnitfvqkUmjsqqflmpmrmlklino[mmhmfkkkkmoqmrmwpjnjpreqjlmmlrqemmdqmvoklopfqnghkmkqomplkrknvlnlmtnpoevqkkpnwqnnlmnlklommoopmyynlofpeqkfvsmnslvpokqigoqokkrqmjkqnoklojpkimqnctrnfmnjnuorknmjmohimjnkmoumjpwpimskrhmqlqnsnnoppkjlruponkqr{jmppinjptmmjunmmpitlqmnmtmiqoitrtk]rmqmsinrmvmkolpropnomlnhopqqolknmnqpqkqmsqfninopllujmbnlhoonjqfjolglhqojlkkmtiqmanpnnqmxqjqomonnjonqrqotopmqnromoqiqkkjornmmxjjsnluasqkkjnoigsoojqmillmolspiqxxnmfnmngippapgkjnurijmhoiqoknmrotknlljnkpvlkpogpotngrorptgmntlglhoopqiukimslinmrhkuubmfmqioidejnmlmhlulogpjsroieqnwcqlolojilowpoliolxmhrzjqsmonfowrommqponpmmqnomtnudqhmlsmnpjonpgprruiqhthlsrptknWjmjqslmnllqjpkolmknsiqogemqqnomqlafhpyqqrwpvprjrtlpiltmlljbxprhrnjlhnickfdfheoqqokj`hnqmopphqmpojommyqlirjjjkkkrjmmqmwtnlrmojmpplrilosnkpllrsigipgvyrnmmjlqopqmomnlilhqtuhufpomhqlkprjwtnpjlvnmufobqnpzdsppr}jmqopq|gknlkvrnnjghxlqctnhninqpiivkpuslqrmipkqhfghkrslvonhlvopkrnimtqnlllopikqflpmpvnkmppnphqntcwosdtighjomopomkrlmkmfnlgqickmgqjkimhukerpenrrtpfjnrowonofpgkomtssklgpppsolnqqsqsuqndnrmvpq}pjktnsjkntprwncnrfoshoonmlrghnrsm_inpom[mklmmpvrossqlnerlomlakhurlsfmvmtpkilnckfkpnowrslmtlqchmkmlmcispnonrntmocorlpklmmnikqlnhpiuolektotlkqmnoptrlmmlorkodwsuoqqposojglhjitmnkuhnjnlnlnivngohlgkomjkmljlliphrqslsxpfmrpnkmlijtgornpqqfzlhhkynjjmoolopomhho|pjopgrlscoqnqlqltooovnoonopkjolummpgjgrjohfjniimvrjhsmpmxnmllpkqikflkhqgqlnokllmfy`kdqnomklqhmmn^hqglk{omqmsvujkynprnmfkqiroornngpklhnpnbqxoupmkiqmkrrmmkopmiikofqymlogbekkeoskqlivngjqpvnymkmtwqocupqnjvkcllomdmpcrpqmgtpqfmrkksumudobrgopnkrmmjorootxdiqillolnmme\tqjbqsppfmolo|pamljsstgjtbkmpn\Njwmplsnwsgnohslqlmef`mvq|obpnxwkdojmvhkko`clqmndtlqktpilmuifhqlrqsljq}oijgmoosllnkwuocdn`pnxlVoapmqqslgjftlowqqfcmttwmmrmwpikvknpjSll~bpojgipzf`qlnojoeoquqmafgcoionmn[Ukdqqcgt{ohtkmblhknqrZjfnkrkoqkxnorsjqojsqmmonkmmqmfnlXertznl~nfoiknklnktymnmnphelnlvWsxtkkktojnommmqkjusrpprvwupknigelksmpmmqspnlithloqiimqprrnfZpkmowmeifhjuklqisjrmvoinflosrksn[lqjonskjnorgnmoqmkhjnmmimbhnpsovppnhhsiglpkklljnfynrqskmhotoflmsmripiplhjpgqllj]qo|nfkrooihmunnlnmtndqrmnoolhqokommopjopnslzjqejfmlwjyprgrmorjmrknfommsloommrqmylokpqmmplnqtnmlhqrpqndlkledqsjjtlYrniknmgptnqujkpmhoorntdl_kirtlqkojmbrjo\oqmrmqmmnwpkkqnisojxpgmuptqqnkerpjnmnlnsfjqmnunpkarjhyqsomaqlUjqruknpaopnnmslomljfaphpjlpfqkopihotlmlkksmriimkjlkmmiroifsnqjmiljrsmlqntoojgklocfwngpmpnmqf`kbsvrjnkaoamuwfrtmmnrcmqipjprrgksnvoojllpwpmlftckilyf[sprlmtbonpkqnqulsumppgsommoqnlnpnmjinmonlngnqjkknpjPonrWdrmdondomjm\qngoplshurkrqnnojqmnqroemsnmlxqunptryqo_qlrmsoohlymnlomqkkllkkgadn^nqsjrnvkmvsmrnhlmpnolkipnijngmkokonggoqjoguglpwojqiohkomiomoowermpprnvkknmytomigmilonovnlnqimejmsjqsnjmolthprtlkhltmmjkkqnlkji{mlionntnmnoknlmko~lphljkojnnppoohrpnovmrnjozpkmijjolqqllmqlmklijkpsnlnqlrlljpqgmpmopqgkunrhlnrbplqprjnumlmqnqnmpipneumllrlnhlqomk\uojkofne^qvhnfjkomootmnrpmknnlomjmpvdkikgtmmkpklljmTodlqllo|plnlrmk^mkiqshj~omionwmonnlmpioprnmilnhllntkofmlookmknmmymmjknoqbryl{ornntexmlpmokqlsgbononepmltmmllomkmoyoleiljplhlkntlpnoljlnohrtppmrmmmtkjnnrpblmhkmllkofpmouvlqrnmtoppkxowmnokmoqopoiiqtpqvjussvhponipsiqokontmrunwrpnmkmxcpjfnnerrrkpovqkooqhqjqgtrmpgliylpoodnlvprrsujnurkpnomsjkqnthrotpshppgmthtkq{ejommnqmhnjrnpqlqwfmpooikwpqvqlxopovikpijhnlgslmnnqqjxen`mskbniviofkgkhoiqqihlmnhqppotxeliqokqlommioipelhlhhlkonSklsopqmjpmonolojpoqpneqnwpooloilnnjQqksmloooikmkioksnnqnoocoxplnolorleaojgmwt^gmlmroplek`phponrloonknnnkgnsmqng{lpnomlonotmtrfupnmimdinlnmnkmolkolrljlqsonjmilnmnisnltkmknhgrlroolsoennxomllvjpnblnmnppxmumqllkpjmnolrnppnqnonkmmqzwnlooxopqnonnkp~wlymfnsrnnopkpifmkimkqjrc|rjl}ronmnjqllrnmjmsonkmr^fitorkounnntnptnsbksfilnpovipqomtonszkpjpnkpnoqjhglhnholnkpfmdysnusmkrmrppolkkqpkokounslrqskurmjkqlqnnjllosoxfjmlomllkmmkohiomthiijghhuvmnphnasxlillgsqos|kklljtvlnrjeojsimqqbn}npqqlzqnpttspmkllqpnpgmqnnglnmepknlmqnplonnrkgmnninoeihlnnmtnzpvmnhjqmnslajfqknotglkrrpm_mmnvnmxrpnnpkpm]nemowvqnjvXoupplokjlumkvnhwfammnkkoqoqjlvtnp^pomnnsolqgnmtagsnqizbioso]rpkljlpmpmoqmqovvokroopvmtnpprhpnfunyioorqjplopmilpvnl~jliomtsgodjrsqjinoqnkoommrrjvmllccpkk}pslnjlwopnkalkqnnnwjpqnVjmhnmmpppfqmlhqrleulnqmodoopnjrlqopklojjrknmyksrjoplqolfnnljmloppnvpnpowhosgl`mfmpvmntllunjmpsllkpkpnlqlqnooimkilllltsnokmnljoronjzmvimijsmglqjjpntnkokpotqohlurokqnmlpqqm~ilqvsnkpwrrn~oqoihuokqpmioqnkqiblmeqpqlpmlsoonnqnoslqlqftmrdojomou{mklmnhmrmdkpurnomiloskopiivkmjqltsrmnlllqonjppoqlmosontqmqrhifmsrtlpqqmukwnlnsjmpqjisnqrsmiqlnoprlftrqnqsopnlkorrjmmnkqmkumorbptonrlonrmllqqolprmmnmnrkemopokqmkonnoophnkfpjnlqtpqorkrpkljsoqvglgkkoelphmlmr{pkirrnnfqnklvhlnqkojocmkroolqmlqojnrjnrlmnlrolkqlirtompqliqwmmojvdqnkiqlurevohrmjfhZnjlinqnpuorpkgjp}mommmjqqhkpmtpjhqkqjmjjlnpaclnloijskjlgprgorpolkmmqloqvlimplu|fklmnuvkopjpiwoqoinlnlolpjjlbpdrknpimjoqnrjrpprknolk[irnnonjjnnmnpmtqrpnmqleilqmmkolunqrmmloijqipiioh\lrvmqpshnpmmpljpnnmkmttnlojlrlnlqmlopjjrmopsolfrnmlnsozulqtklqpjjtnyomnjtrcndllkhminmimjdgiomthnoploitnb[qmokikimfquomvrpjmorilnmjilosjniqeloteosjdkmpmonelgolemlsrihjimmznerknqkklnxnquhpnhsskkiomokmppqnpowlgoelnjtokqfntzigqkoclozqooutjoorxnpvmmkwvjllrpnmnlgqppimgvirkqaheqlrnroqlocgomugglkkssfnqhlryomkcqhmjlmp_dtjioiepqnmohvrlkjzoilknuklmnprrttp|opimihismdmllprxnqirlfpnmmdpnolsijspnkonoerlknnqlnfprmcnliklqhohoshfqskmjjkhmmpglmspkrjjvlumtnjljsollmolpnoqgimqoslrkrcpojkssojoekomplllmrplulnlmnnogrmhtminmkjnmklspgoqqhmslvmtxtpsgjljtumpnnqomjqjpnqohqtlssvppnimoxqonossobmmsoigriuoqrjriioonpqfkyolgkvwjormpnhqlnqrjpruoliprtjoxmxohvqqqnkxpnjjrakllmnsosqoatnsi]iuvoigeuomnipjummfllhijooucsisoqulqumkojchkprnvonornggjmtdqnqmhlxoorobpqmcfkeprjvsoyrjnptnb|ngtm_xm^rkqljpommjxjggnpnmhrfqmtmnpbmpcrpjmmohkqftlgqrujqkjrrooomjjphcxocormrypowelmnuononykplpogohvosnjnuoyptrxptwxqmtusnqlnprnmfjmojnsnmitmjrsleytqelkskmojrsltrnjznrjqvmmkgggpjqjpozimflkojnokiogwlvqlwmlpoiookkkglzrilhfrlyiin\hqmpmomllinhloilsrmnupzlgqjmspihtnropptompspcqkiojmhsgjjlrdlksrktijypnolrpnplqurivirnkxmgklompmlnbtkeprfjmml^okjsksklnrojpsqox^nlonpjnhnnoqskqiorntn^orhmojnklldpmoflmpllrpmc{mpflolppwkllpmopitqijplrvpinnmkhmvilsrallWrphnpqnolhoonhpomnYpqlmtniozjkpplnlnkpooqrunjonllbkqnpmolojgdiufnlovonmhnmllo\jkmmlmoonl|\qommnmhqpnynumnupoqmkpicomnotlnhosjlrnvpjxkvipjkmphhmmnvnnmzpqmninonnmnn[ermmonnlqnnlioljkusqnnmnndkwmloonmykkpmpnokknlemrynp}hhngpmromlmunqtlosqnkopmnonzmplunponkdqwelqkinvqovoqlVomnlqpnplqnnnlsnjorlpeXrnsjmlsmqlfiinoxomrlppjinljk`jnqk{vmmunnnklmnroYlnsomqqnsmklpopmppjmpmtqarnmlxlm^xqnnlpMnonq~noqoglqmlhnoiwqqkhlnfbpisnflqq{povopqnohkjnknpjpmkqqwow^skqqmtqmkonpomo{duihnohrpksqmllnskkkoqxnoqrjizhtrsrscpkqwnrpltprkqpjjnmnoumpnnoomlnqqumkpulnsxprgnjovlltjrllmnowhqnsptpunjehfojmphmjnprnihsmopoohpngnenpqonepjjctpomnmdtotomppkkltrjqllqnolsn[srrllooxktoqwljtojpgrnonmuqlslyhppnnmlsxsotlnlrjlntojrsvhdnkqqkonmnmpmpnbmotqriqjsmkloonkliekqripnklmxozljlqnmjrjimyocroukphkqkoqcohwnlmunmsmoemqvphpkzmjrqmsbdimoifpsjlmgmoljhnxrmpilmikmltowofmxmnplglnnpqrigmopmkqnsopolfqqntrnamrmmsnurorojrsipnrvslmnrigm]nnlno{ohjvlrwkkolkifmpslqjsneffsntmiiopsjhxosnomqqneuojsorrmmpqmspoppnujwkohqo|kqpjnueotwphevjkqlkhxuznbnpqmjcitoluunnlkpnnqzpqo|mlvjmjooqqyclrfohrqtnkppnnsrqtmqvnpgpvjgfexolmmpqhnlmfnmroylkrkgnm}sdll`zpqnoofpjtsuqtlmvsnqlnnmqrrnvqpbqmkpiqqkkqqmgijxqrpjpkqrmorhpyflrsolynfkjofmukfmummlljgpljljnntolfpjlouxmigmhdnrfiiomhklplkqjwftlmolnpqokirzpmtrv_pjnkslolhlkphnkxjlnlrnssmlvkqnhlqnpsxnqkpmmqpzq`kqlolbqlppoqobmqtpqjkmpkjpnveolnmirghlkohrsmw{qlghpjhqnonpjgdnnhpkviokmnunpntinkxpnlnvomltsqjsponjnmlompgkmpiVhoriwqqjkovrglpnpqnkoinqroqplsvjkpjelmcmqpmupprpjimkpqpplsronfnhsnruonpjhosmsrrjsrmkorllkosipqlionquiuspgqjpnpljtmuyqqsllnmnlnskljwqqqtpsokkmqsnoqrmqprnmknopsqomvnZoqqnhmiumnlkiohtqlnshtkjkqvpjmoonneifmmypotopjtncnmdomntuhqsmmgkp{mjqoqnjmmpmkvfiuippolrrpsjnorrrmsvkmqxronhpxjpnhmipfplaujelqrpmmgwoqkrktlnprmgfkudmtnpfjxgnegooqneloiifokhummkmnnpluiopttkklslnqjkrvkrlrotiillpnsxlqtiomnmp{gmtqr]uupknlontmnpfqqrntlfhnntoloekgfjmcclkefwuplkoqznqjvrpfmqbbjrolqnk^vopqnldlltnpvmq}n_ktjsoonkismmk{ohnwpkokumkmolkloupmglmqjqkhiqjtuoumo]pqqlqimnlmkbjivjnioqonpnonnjosrqrrhkuusmprjsowjmgmmnloumjhlinbqoojqpomkgmqroklmqn|pgnqhynlkkymoiompfposlnpjhnnlkclpipopxrrqpqjrjtgisamnunkmfilqomhmtptplqjkjpplyinrooihrosqnoqqmoissmojeocdnnkllpnmnlugoosjsmnmmrwlmrlorlvopolojmopsoohmmmknjmoomhmqnnrrpvvftspoqkmookokqmpjqurnkqnqqrmprpqomiooqonlrnvnpmnslikqmpnklqqnmemkksrsosqojtpmllnlnjnnmokrlmvfqnpntomkknomkqspnlqipipnnpmikpmhoomosmhoplilklojnojtriltmmlpnjnmlnnqmqqolqlqjphplsqulinoqhnoomrnorooknpgpnqlpnmmirkiskmhgijnnmomnnopoinlmmoorlrrpovqqmrsomoqoniqqmkkleojmsqhl]jnlrspojnrnmmjlmpkjnoniomkmluvpoqqllgrnjworofpmekvlnllnonkgiow^mwrvsnzpmppognhmdqonefbnkkommn_lkqrPlqtnqen|hmmosrtnmpgnogfllpioslhkpomkookmprmkzWplmokorypolhprg~sncplivj^omizmjlqcmmdgmqimm`gkqp`npjmnlnknommonnhnmnrokjldkgmnjmtlknnkummmtqijlmncqnirmnopgkpnonrimmnmothlulmmqopqmnldvmyjionqcmngqrluompmln}nknppmmq{lgrolfxlfpuljnnkmlpm|kthllmfgohmksjpiqnmp{ngrmrllqanmrlqlonhopoqbhsnrpiononlnnoholqmpi`fnppplntvrnpkhns{punnnomoorrpolojjporqkjhoqkqpurlgolqoqnlpnonkpmjkmlowlgknnrmmnmmmmlmojflmjmimrpmnnbpkninm[oso`iormismn{lhmqmmnojvpmim~plpmnqayl|hjbptono`pnimnonqonwm\um|Xqkmzzrllpqmjfrdm{gopmkgknqmorohousndnu_nnvklmkkopmjlngokpgthmnZnrolopipnilsmigkUololonkguofmk^nntsonlsruseq{jppmecnn_qjrpqniauhkgiosto{qfoslppomonsnLudmnfmhknrsoprqldvmlzpmpeimqmjmnfjgpjnor^vyiqmjlmmcnpyowvgq{nlnpmqgjhmhrrgnqirmlqkknynokqsrplnmmrspynmldtlqvntp`qusmqxgismqko{joomigifkmkqrbkopneqlsglmvrqopjjoipp~uknnlxmemsnqpwrgkiijgimllpeqhrlllmornouljlopkj]nnpotgpmjoqusuqkpuorklniphrsuhhnnmrmmghkqtiljmqnnspubnlphsmvkhrjqtqpzprownqrinrlsdnkps_nnmklvponnnowsmonjkspnrf}kveRnoo]nbmlnncpmomotmhamnjokapuruwporjmoomoant}lqpi}qolpkqnlloooalsmshdmvtlloYmqpionkseznwmfq_otoeljmrumktpj[doltppljlrovtiqnzocqnoim|yntvhppoujpmqsjnnrnyqzbojomspmhocopjoomkprmnlrtspnnloijpmovnacskrkmperylqnlfjkkfqrgnimzurnnlrkozgikmvxhvklyrp^oqfmhlogoafsndozp\mqplsqkknc{epqhqrvqmslVpdjflmqgklqrmj_egmma_tvpdzjsolx[fllitoxahYpfunmpcmppknqwo~nx{njbrnr\infteqn}fjogtpnnlknpQqnmkukrejos_sfdghconlxpwl]{nbfponkhpi^]jnxnpvtmupnut_imqrppnnpkbvmhhxmsfmjlkiqn[f|onlrcrmmuojaekpkrf_rqionndoidkpbrfljirpfjyieamlrogpqfkmsomtjn{mpqoeqclnnlmnimiqiqmlsrqkepnr{qckfnlm|g^oupojmplwoasphlmbqmst|lmfjupllklpnmkofpikuitmnnvhlrp_rokkeqyukononl`vlqnlpkrmn`pngnrlsrqolhnnoh`in\keghpbiilytppkmvplemmortofnpmlnjrkuhlnsukfnoi_rfpnrqtoiokWmjkhiprvkhiihvjmoqpm}nulhxzhzol^lsgntfrlhqmolimhmrkypdop~qgk[lsgijppgoljoprttngfzphs{lmspnd|nn_ugfvhnmkdxgqmlqgbklilktjleoYqkshpimt^onlrlmqqrfnpkpihbmpnii{llvqpmlnknvnjekjkmqkidjqfoelpwmknnwnvl[kjpnjvdoqwzk~gnknglquslmoohf`lphryktlmpyjpmopwwotkemfkjnlmyznqrxnon`lmllsqpnk`pnqotmnqolspjnrscounmtpfqnqfmko|mtmdrnbnnlokomnjomkqvino~sps\lmpnnZnrncxmpnpsmmnlolpvisqnupmfoo~p\eopt~qthnzplmbcpmcmfmrkv{mmmumplrnqxopkrop^iro|nqqlWu{kxnmnm`gnlKdponjmlgkkrkeohmwtgmmoiilalgorkpmqlqnmp}e`jpnkdppuhumojthhojmyllpmnsekli|m~r}ipkss}tpuolvpahqvmpryqyfnqnnrqlcilgpqlkjgnznmlptqrlroolijokaqfyoorndqqfpmtm`sgvglvqhjsyidpyykrqxohxtmsptokwrmuzltlqgnnkpfgon}mmljrmrolsjjmzl_wukkqmlmartpxkmkgnlyrymqkjjrl}ncitntjwomknugsasrgynjqwrzfjnkvmloreqofkpimmwynkovqjjgprnpmmljmlk_klmmpondm}mjjFlkmrjnjlsninn_thnmopnppfoklmltplxp`Zqytkcnukmn]nniuhnnoionlnmqpowokj}cqhjrspm]lZqermmmqigjsknqnunkoilnpkovlkinnqtnfmnsojmvizrnuovn^qpnlnntwqllkl{tloqsunwfmjo]mnx|jwlnkpv^muavoolzoqylnqomlmsi\pllnimeofnlmmohhfoimblV{rklollxrbklkcvjqk|pgqomme`qqpimnmbntm^kqspinmxtuPopljtlplnpcovslrpzhpu}o`lpkipvupVsjomnlnpwl~myfowpwis{lkopkhmNqilmnopaqsknuloomttqwkipmargvlrnpnjlpynmlqkonnznrkzmqdljontpmjnpXkponnlfjiommnmltlttcnmlipXl}eplpp}YnqyqhmpokfqT{pmxpmwmmtn`ojomslpknjopqykkyn^ioniXirsnizoumioqrfsmtjnwjkweqjfxghstfujjpqkq|rtuhqsygfoamjqkokjgohflnqmhqkottqnpekkmjlmigjoqomkhqnunejqlvv|lmhmpfnhsrkkmm{nlgkpmggofmftqjonmqmnlmpdflsr|nlijpixsznmxixppqkmjozplnhdlnvoghloirchkvnswinkdniksmikptsikjgjrqrqmlqlnskpmptwfmtoqynnkpejruopdjkhnphmnmmupjjnirwq|sijpqoqklrllgjhfnuiqltnnvjqiofpdunsmmhxulsfumjmmrkulfuotlslznnpjypossnknmnulupnujpqmiqpwotijxjyfpsenrnfqeknubnpkqqszknnjtpdhizmeipnummm~gpsjwojkolnfpqejfkjrpugohmjkZ_wtnjkioylrtjpumkmoljyoeqqqqipurqiioUmpugqplrxrqlimeootkytqnjpkgxnlilsdheotrolkohqpqklnpTkppjljqmzm`ommjntkpoouo\kroejuqqonrknynojyslgqprkmwt^pmwn}odnmrogilljljnkoqoin}q^~lkkinnqjqhpdqqnhkjkejhoonmolfkkhcojijnriwdmoipotrranlkjlbtooopmnhqzkjngjlfhhr}kmspnhkrhekuinpl{puinlnlmfdckqlmpnsiplpo^i~trtnpklilkqmnusknqvovlj}noklyignpvjpqmmimwvpsjngofmogml`qpvpmpnsptrmimjwumhukolupofiptoutlrjnlxlksncvtmv~lnlfrl_tysmmomjvlolhopolchxpysmmoounwop}mogszrtqpt^sbdeks[nl`xmknlhlpopnk}pljooddwtloquvtohuopqlemhhehpjpmqffmej`n~kkprqphlgnlqookisvsoorgtokartgmsncyoauhdonemifjiosinyjqkqmpuhuf{ikppqwxrlkml{slqtcnvmgigtpysmznlmeffluigsouqufmo`btlvmsmhsmrso_rgksq^lwbm}toomoghnbqunzwsnmlmtjlj_rqpnsmmenobrugusqcfwjnnl{mlilhqn_ltjpnrTlpomkzduemmpq`n]rpmsmvTnqkhing^vsejuotirrqt]wopqrmnq_uqqfkbiakjelnrur{nxnlemnmcqtqj{jksmuujd^Vrnqnginmdqisn\hqmjhoqsszfnsiljnoioloymmkvgodnkvsknqgpglShjpqrfqkipjtixsgjsoxsnpjvuqtxninr|jkvitolnsoshntumikpkgjtmtnlsjqloptqwp[qvptkxppqhesrxpoufffhmpnhijkoj{kcootpmnqmohmjksnrmkokmilr`rnhvlbobqfxxmqogiiensmkoemcilksonnmnjdqrmlhptuwntpgdup]_mbnqljmwknfi}lelinjplZnrinzelqqqmqnpwnkqsjjnmlqfoglhinooogrnsodoiqemsnuponpnjmocknmpsnnuknmoioxncqofmh^rvcmqntmpo}mn_p`oonplmslkuj_]onc]mnqkpnlqinnsmnognoqrnpqsl{qpqmpmtfoneognnmsqomkpslmyqnoko[o^joeppnhkotmllZonmonpmulpshn`k_telgompnbjnkcinmprpporpnoqppwrpgtkpnmmlhlxnonlnmqzqon|lqnuk`noomdllmojwoom_qcnpjlbusooeqskpqkmpmpjqonjm|qtkomomkmokmj~ohimfo~XpsmkcoSmkntvmymmkpplnm~ojsjjn`wCdnimprmm]ngqjhqpkqkloopkipntrspdmbppkhpconpqyndjm{snil]XpojmxqnrukklynkjimodboltplnlnrnwkqtlwW~orlmrhukjxfpjl_zprzmojosmf[^hxoopqtiqtqyolomoolzmmojydvn}rinoQhtnnvrtqkqqrtmgitoqpuwprougusitpwtwanpktmoyitlksoppomtonqqeorgiwnwogphoojpmqzpkleppifd^avjixunrwkdpmmgpk{|Znpvpnrojcl`paZXjmtph{kukolqkkqklmntr`lleognsqwksohreimlEfelqwsqpjkqf|zWet`srkfvgsnkompfsocenmngyilkknjnq{lahooulquakm]trmhlqh~mXgipsfkmmqqklMoZatSRmdu~ckovnjiqfmonkqlplnodjqmilmpkpmenboetlkffslnrojmrlrtmqmvmmnmutopngxgrwqciqpillbunkrlovnsknpitminmeuzhohtiom^yhjnqlxogbwptqqlhsjmpmujrnmlgpkohlrllkmhtjmnkqimkkrsstqmixppjdkgpnormluhp}jueqsmlfoqgqtylxhotniwrenblmnjkejhlfulmslgslhpjeqhemquqkomnrpepjusijklxs_ostntmolpgevjiooYqocmqjhqb[tmgohhusi]m\[vnhjqlvmmhaonnltoejnrslo^jknqgljpyrjmjhimktufookn_okdgsjkbpmoukqmi}co_khlkeoiqintnrwlldgoj`gisibknoikcivkmnbmspkhqlbqxfshRpompm`vnxhkpplgnxpnrlirshouxnlkqlpnmfmokjtmlqdqkmenjpjqivejgulcgotognmjqexptnkeosqqujopdcfkqq_mjmbkoplkhoumcproBrqlonprknlnnp`nXnjnommpjooWjnkoqpomopprnppnlkrunpijljomkpxoTpelnfoVijqomolmunhnVdmoklupppnioossnrorlhmn|nrhmolcm{qmtkqnMoslmvppnYlkoopllpmsvjq``lppolrqhroemmzmqlymxnmkknfnf\lomnmanmtnkpojlxvm^igikmtko~qjmknqpmlrklp}~qmntroomurmjhnnxklrphlnupmpomrqp{oolbhqjuotljljpelxxkqmjowyonqonlphgohpjtppqltomoppilnhqwvsmqnmveptsluooniRkumionjjmnnplqhqj`kqocpfmmmijp_pqnrqklrtesono]oqkuvqootqjmpokq`lnrqfjpnpyhqopvnln_hglljrxfkghmyorno~hqrnrrimahooksnwrtozojjusjqnfcuoliijknpjpmjsplqrndkqimyhoonomjnpmkopljhqstkoln{tozdroridjcVmcknmlcpmqrmnl~iuiotnogkzspkonrlsnbifozhonorwkrsnsgmqmcokmhpplqqq}e{tjjdtxrimavpopesYrlmqmyojoplsppojqipofqrirmhcqeuoknmqo^vmronnnmlsj`dslomgot^lfqklnpjpppfkwmlnlbqpemkqnmnkomqgvnofnqqnpkqkkeivsnddltpkmepvpsqpmrrtfmkkminlmmiolfkrnmliryznosmc|sv}fofaedisgvqrrpoupkqt}qvskunrkqlolxh}snnqlhrjjlkqnggplrcwnoomwmvqphnotnihqcowxmrrijlpsrfsuqpbe}lquopmmtjmkhpnvhqunusnropst_kqnr}mo{ojlmup{oornylat}qtislflqillmswmlflrmipihnrytncfghnommhmysnznknwhfqolfrjqnsnrntg~quibqnhqzmks|klh|wtklqllotwbhrhrusrirpXmkmlnhqorjmwkriej`}lihnxohqnehgttlhnkorcf[simknno`tfginnwklqljgilsjhmopcxgiwiko{vwjpdphsdhh~mnnsVoenoSsnplnpeuloewrmgtnmmpzhp}q`fewksol`ueqdmjlkriljbfsmnfsowrhopn`lrppdnvohqs{jennndicotWgkmonmksnpjsxs|sqp}gnokicrsrimenp|sqrrkifrstmpenqg|qqnnpiosnukroznkmtqkim{ukmr}lnonnroojnnnl`mhmohq_pr]knnsnppdnoOmmnoknppeqlMmfcqiXustnormr}ln`oppsrqlpqpjrmtjtrprsumoap^gmsppqbnnkqllxinvnummoymp~lqmhsojplpVymoipnndn_rWklymjbugmnspm]kfZtoqq[fknqrotoqrljklplyoqsjlgq\ononsmrjmomsdlshwmskljp{prmqgntlminoqmpnherlornqltmloriqtowgnnXemlnfnloliknq_rm|rlznfhrhvlhqpmtnchnsqvmjpfpofq~ogivjYbtyrnkosjjozs\qnnll\omnkvoo_jruogmxkoirp`nomwlgltnmnmwmztjzjlq`lkukqotpqrmnkWwknsonpioqp]ntmltfnwpljmn{jvugprijhmpdrpnncmfoobgm_oltln{rnnkmmqko`pnpyknlreossowlrmnktjn\oasrqdfmhlmnjqrvqtqmmioqfmpimopqnimskkhoyllkgoltogloojnnnrqpimpknwnrfokjqlkgqolokrnzrpnnYpimXjloukooqismtkuuujkgoplijppjpgmqerunnhjklnopjiwrknqmmtxrkmqrjmhriilpgonjjhntjmfqolllnqsrmchopimpjnkrorko~`mmnspjk_kmqnlqnklltpeq|seimlwonoopqkuirplsmnrvxjmowkqosliqlnanli]fir_|sodchpnestb{g|iiongklhismqcfdnubnorr}hqtnczlhsrpprjroirsxkmp`thro^kiZoqfoqmgimgvumm}psvzmhm^ng_nospmlbmokrg]ndoiijrnhsRkovFnhjn|qtxjormkijrcwXogem^nyh]elpo^iqjpmxkqdsznhYolnmmbeiookphYgrjqpxrxokngmkwr`lyrkooewm`kgormcsvqmukjvqjnq\ptjmooBm[fopnoVknokkpqnrpmpmpololqomvobqlnnlqmjpnkpcnmiojPloMlepntqbfmiqhmqkmopunognpukxe_]ojqomlmtplmzxmolpqmmrnon{nonooplxos|owdmkpVnplklkki_qmmlyljovmspkonnrnpmrlolosqjvn`omim`xfoojpqpspizqnmwYmm^fnmntjgbd]viujpphkjounmmpqlmpkmnfvqrpcormqsnVknplrmovsdmlnjvpjofmqhuelnckrstsoktopmnm{qnzjxtngklopoqokrfrnomlqwjsjkntlbiphqodoghohulonnptokophimisinlwifpjmmksmnzwkoyneokkdnxoqljkomnprmmnovsmnoyopjzlnqnqou\jhxm_gpok{pqqqxhl~llmnmpnjhklmpqojijooisqmqetmopjrwjuzupvmgmkomnijkrmpzjfxlu_p_nvrlkonmujhpplmoustpngmoqvkXllporsqlkkqgeon}vami~yykmklsplg\uhvyoXnonnhjjiqviogqoppl]knjykmkufhrokmmi_ulgolbjosmvpUrjpZf^tsowjq|qkvssY|kxmujxqmii_jsuopmermbmrvj`csookflqkljkcopaqkkz[pmwhqkrkekX{ooosqa|kbhmmmnollaorqgspqikjqmldvgt]oikupshsl|yRqekmerfqsr\upiattpnqo^pnoregtlokwlmprqbmkwklalngrtjolphzrmsklqnknuipnourxpntojnnj`o{bkkkbvvxqolyk|noosrlcolmhxhutfoqnjmgmrnkynnaylbuv\pqrcmtYgjedm_ckmghqxlfgltpaosnnhkrnrtqpwmksgwpiaje|i`o]rjl{rimlfaWrmkjhjofjknso_lwpt\losirnwnpsiunkUspjidipffmqenlxqimaqiqkl{m}lvkfilqpjpnwmiqsozlmpmhlssqlkoigltvonorjrxpnonrlxhllrnispqnsnj~[kejsimkpxujrpk}prjsjgrnvmnoumrmznnnjgsgnpphwovlikmcrslgnehnqnlqnljrvlmbynhnkff|olpgtfpprlhhlrlrjloyvqfljgsqokmogerxofhlrqvrml~hpsmelkmpmtlwjmjownoupmmph{qontthj}mh`kqjpklfqjpcfefllunourjjo`h{hmsojmhpjmkltokmmpoflodjskoildvcuikynseqhglltjknrgmenfioftkliijlslgyubsmficnrrfcglkqmmks`lmcxofpjih`ipjhnoibndrnojhlm]rwrjjlsfmkqkllizjuculhkropn_`mvmrngslnolommdrjqorlnkjmmya`ldpbqznoohlqlqtxnpfmiwiruekppqhhlqejrpqoupcrmnhfsjsgtvtwlgqcn^ppqjmemukrshmsnhkjmhntpaofrrgjimigkjqi_slXijtmrmmjlqotjhkgfqnwsnorqmkmkikwmfnpmdolmpjijjul|hnustm^rgmj{eom{xbupopqlYmeoiwspuirjjgljonnuhnmfklniqppmlmnjqlijlqcruKnmnitlpkkmuokskpqlappmznmt~popolpnvolkjme`lkrpfqsknslbo[nSb_gmqprokjjs^eljketmk]rpwvznxnhvinvgssqlii`nnglkimutlnZhqfskmbrj`kullcm|siqnxtlhldmmpbrosu~npronnrnyiqgdjmpjnqsic|Xn_jjrj]kpkomflovmaulk_mc}sbjblcrmsoqnkbplcnnskirqeoklpsolsxptWcqrjjpo[xsshefognqqdkimlkuctql~lo|jejmxpmrmoipvnombujmoovqzlsm}edynkoiolnehuqmmvilijjmmrsjhimbmifboovi[qjrulpounpfhPumupPgcmunkspZpmcll|srnpjurmilswim|mslxqpjoo{ibnmovvoltkqngtmrwnllnnkkkrn{pwkpqmjlsqqvoqmrsmptsonpnomnnnk`gnkskqnndrjqqq^lklwomyispgtpkprtuijdugzhowkrqnlgfnigowqkpmpr`jnsrmhjmlmmtrptmkoroqmqrlrritwyopmmvdfilluppoooemdrp{memtgrhxpkZvslinvpfnpsnmulppyov{urnmngpsnujpmrnlhqrcblqhonpnlrntjrdjhlwnkkilolnnnmememgtnijhiojhzkrtopekljgirqhnkpolrjuzssebnrtmlnnmtiswqhkkcqnuritrqlghlluitlgquonnmi|epptmpeyn~ilwsrwih`chwgfkhkfoip\nkkgl`nimbjjmlsvmlrnqmmvolmnmithmltoZ\ltlr`piopuqhotmdllinpkqrhvuplkqbrtpj_cvnlsfqgrcfhgst_n~knnhmtkdmtolgfolqnusqlpdlmjn]osX[rnmov\pep_upocskkhnonpdjnnwpnhnmnlkmopnpCjkllopmnolnkmqplxhsrntlbnqlmnpulpkkosmjsfqvmikqlmmhkdqhnjnjrqronpjsvqjsxpp^lrgpuprhqorksnjktokm|mnkqoommkmuskkqjpnrnqmqmmyplmvomxlxf^oojlniedqu`liqpgrmkunmnmjifonenq}kmrnpyovmjpmkmrikooPspurlnjjmw^lnthmomsiqkkhuysjnfcmnpdnnkrmmjqs}gmombmgosc`f_nvju|ilncti}nqiliiqoahf_jxttsjnlbihkkolqiflotorsllrxclseproilnfrlosnoyqhlykqcolqjd~{nfijoh`pqmunmulhgnmhekqoffbarq~gztgni_hrojihWXiojtnawhjeblrqordxkdmg_pqoiplkjgsaflvjpkjkekmyrlmhsjwnrmiiylqqnpvnpctppoqhztomhblkosnjpnlqon+nshmmsmmmpdg|eXkljal{tmknpllkhqslkrmpmqotskenrkptouryilooukmglirYsrmpnmppmopnnoon_qkrkjnjjjrobrqf@jrqlmihqntgkpmnmelwofq}snamndmpdop4lehf#lmko|mepvvmonscf]ntrppmghssknmrjmmgbohmyjuigk^mppm_nemnpsijmvhtlivgu~mZiktEnpjtl]qpmamlulepjmlsohmlnllboepforoenqqklpq~gnmfrjnzk|rpodnjsxpheswvsilljlw_rqin{nsimykpkoeommwqlrmomhqqmtomkmoqnspnnmqgjopskhi{vtdtasnpotmasrqkhspplmotenpnxnmoiptjowlrhonp|zonyilmlonurllnhiigmkunonobolillmneisglpsjxwmijsokqvVe}mprmqpwnhpkkgstlimmnpmqpnnnwnposqtrqmwihmmnnoplhdsilg^smnogxqtofmooiofo}lqmovhnm}ipxpmmlonmlpj_lo_jmprglmsejSmlmuntmofifnpnmmpaonRibxjdk{cphkorlotlorqols{sklnqqohtplVsesqkrpcnlroonhnnpqnkdlsnljjonopjjnnnkgksuhnrnijlpmjro\eqm{e[rlkpjqdro]pspljafnllmpnlgnmewUkjjqrslmprsoonjthoukoniyuqjslmy\ymowtpttam`oZpqpn}vmlqnjporrpm{mpmsqtombsnfllopmfoipl[shsrqupblkmSpolmnokuomninpnmlkhmnemu{gcd^elsonlnkkq~hnfmmwhqygmnmkqZ{hiorpjkqtxnsoptk|nsvmkmomchwngppkgsl}lpordjhjjpyampjmrnsfoktkjnomsv`ipmfmnmlk|rnmxhqkmplqmkg}{{djqdsqakomqonstlrqrdljmuermlnwgong}hssmk\qsxvqfjkvjcqjpji{lsnjovntjgtrprovhgfmkkqlsivnsesimhwejllsjosofnknjhmpnfnirlouqcnolfjj_okmnmpjjlcqjozqkklpgvnhtkdvsbotkmlfpykrjftmuojmmmkqomtgjnhjnmmoqnqpmugluorinsnfrjrfZbumhpmtoqnouljmqsm_fpwkmgyrmnmppjjqt_nrerqjduygsiviitlimonqkmyjrrpkwlkuomrwqoeqcqksssimxlgwjnjjkmmmggtokwgfmpjloeMploikmmoknvmffmlsnqlpfmlxjkekmyl~k[moinYmZromolkwqocirssWrdsogksnknxaurdhooeqnlzjomo|`rlokm\konoqwvmmukouhobvsmfrgulklkrlomjlkoagvfqdprjmftwukn[fmUuhtlxolqkknqy^y_oqnlukrUomvtslty{ovbrik}eoitvlklmnYvordllkxpqwpoqssrntjeoonqj|nllgoOclqomorxpoluumwn`hooYZqyoqnrosppmopkhiojsm|mx^lzoNoqm[qnoipnpoppmwopukkqkdjo|moomkkndppgkooolOukprksmNitimgpmjlqlno|lotlnqnklllpdavtlpynsorsmomninspollQoqkpnp|yimjhkoof|Tn]pnppzdpkjnnslvlmqqqnuogkWtpnjtlporqoppdmjpnmomroonve}xpnopnnSg^onsrujnhl_wyonjlivshneontlrnpjgmqhigqlftqhlsrpphtpmvrunqrdjkdheg|mkglnnmhrmwswprtvlphdeosckiokkirojgstjflhnq_mrnnZjijkjnlsqhjolujkhmxoeljsjmroohnnnsusknnmmrmnumnequkolhlhennrrpidqcjl[ojpmotkkqnlhpqns^spnje|okhlqolgmslrozl{mpfnssoylpskioiduiqlxrqpqqqkxyxljjqopnjutjlhkosnrzlxo_pnqoipqeqnliognobukapjmomqqpopf^kppmrkofrjqkqVnqmfmn`okjiomyn}Ziqipu{ZemnlrkplcnpqRlrpukhnqsrqkos]npopfynpramlnmmiokqkpolmlhrpmlmhoKmn}qroqmriomqsekkorpr^o]n`immn}uijxinor}qpoaqksltuootkikonokxssiomqslmmmcoqlpqnqtjnlzYZuqkqkpmdbglllmYl{o{nVtrlnlhqrrhnohwpjmjrwoxinngqXlgiopqagmnkzmwqm`npuoV[mgnnfp}lmiuqromgon^mmtpgse]khhqmlrolgxt}gQipofleirjlrloYvkwoRpirmtmqqionldncioqqqli{gpnijrnmmjjomthqfojohqmpinvoiy\ohnYnxoltmtmrolemclrqnkqhouOlnrohq{yndzjvtlspp|rsppllypolkooa`bpmhpelrz`|prtisin_k}pupkmmRfqpk_romnmmnkpmjp~}pngoonnpornmqpmp|omooozklWgqxmxmtn`nimmslbqroqol]nzikvglm\qrsupkmlqsinmfgmojpynkvqgqmrpshkknfqowlb~lqppnZqldpkog~knfmSrcnkpplknmrnkjoOrpllono{kfnslnwq\oqr[mmphkosemopn{znotpmvm[flwutplgnmoqlppnjmopqmbomo{rnuktn{kr[aUjmplb_mnpynznlop{hnkklpooalmngmommnkpni^nYlkprnpjqnp{lnhkm|uoVpshlfppnrnkmmdorplllmp\pskm[jmsvklpnjlt{ojmxtrlkj{rtoplmm{vskqwnhvoqlniqmlopoaqnsmpmb_Rrmzmtl~nqlornvonqnps[~nokpkpisnaql`nmrlpiokmrkoqYplpmspnonfqktM]nxqkpkmmkqsomqmqjqqmnkdppnvm`mppg\nrzmidphrlnwrpknholrq]mmqSmoohhlnmurmnVzlvnpnnrlolmkcOozqksoubofkoprnrkepmsojpmookmZom_kwfqgo|wrmolqmjVjprhpmpnghmloononctrk_plnlmpnq}pjr}pXlrvtkndxoqnkoylzlkrokmhjpnslo}{nfsljmas|ndlkdlijhv_nmooi\ppymoolg[nmprltsno^Zr`~o]poxlmzognsknqlmwqnpQr[srmkslmpertqnoluljlxmjlinqorycpmgjiutmn_sdXhnnllptpokisllzln~jtqlkWlbop^krtlmkjnWrmlqcuqmthkifkgtjipkplgkmscjcjulgmlmuuqofgh|hd{ikhklsxperdpgqsukoknir\yrloqmrpuinropktmijgohijolcmmdq}fnkqqloellfshejjqpfmlmtboouemmqrjlhktqjnlnflUheojiqhxktdppsl]mebomhulvksopoqoqilnpnommdfsknsrnqrlquqpijoqokqokofonm^tjloinmoqpomllbphrfspuwtiakbu\lmmsnblmtloklmkTiqolkfgmxkmrnjhllhnmnvmrpqjqlpzhisZugqqmrm\pmolfljnltllolsgrmwnqkqos]nmnsosglohuujmqqnrhy{r|wl}lxfolonokkzpirkklltvmpqnqq{t\cnxll_moonljprnjmloonhplnQ~qplplZkrWdgisk`Seoqqoujiirqmkjkoqwrssztlnwpwzdmr\llpoj~lwgqWcphnqvpkjtemsroovihiolqu{enil[iqrqqqdumhrkfmrropnevjphqqpwfxkszhmrk{XXqmtmpjjorktnorxltixhrpnZskcfqtpnqqnmliqgbpfsqkmhskolmmnpfe^{ssoqeqekqmsnkfjgspnsnnqtgmlnpeipsfZormsnslylpklbglp\ednmq`n]mpmiiljoskgmykrtonqeiyrqmpmfpfqphe`mkmwgodnWlkmqzknvaukqzmixokffommqeldnrXsiqidspmknjhltmonpgpknfekkpkjrqopmmsopvhqswlvomjypiudqjj|f]fppodcsmgs`jrkhnoq\oqnihnsklmmlvmpsmrqhkdergubrntqkkiqbhvknsingmWmktpp[ihoekmhrqfcofqnvherpRqn\lpqrqvltnjkhmy{_imoiojspk]nioonmrukfymlatpupk~lmo~prjkp[pmpokpplbjklckplot_nmenqxqlnposqnpjkgo`tientSw_gjrQlsp`rpxqdpmlnlnppqjd{s~{gjnolqlmkpovskplovrtntqmpxermmekn_noyr_fnqnqoampmqklizpmgptpfkmojlkqtknqmra}lrmsno^wgnbxnPq{fplsmqleymq\oonpiapnwiloqxi\reFrj|gptikcolnmolnloolnf]istkopnxvkkslafpyltunnsspligyjqqqlp`snvrpupkolnsqknuhx|jtorzfmjugvkopotozpnolmosprmngqopqmqnvkokrwkzgrrkljfrnswztvcholmntivhqdmwhorrvhnqlkpyqqmknkmesnunqqktppjqomztirzvnkst_rfgrzikqithim_mqojqnvllkjknknqjvlnniursulmoflg{toj|qoojjxmwlUv}qfslriNprsgipkdtelpkgvupnmvipspthmpqYoknkoqoqlintkgormhoprls`mm{ingmkklpqpkmpk|moopxqkov]mtoqnkqkmllenoorplknygosXmurfqmnkrimkdspjqkkmqg^ktnooqjdfqrpsmo~mqgr]oknikolpoernrbpaomzsmnsnoylqnqmgjunopbptnjqjpdokjnqmyp`rwomnpgrlgejplokor~niemfp^unvlioiuroyronorqrpnwlmnskzppoqmpw]hoqmsngszldncgntntjplk}pooonmtmmuoxvlnqlmoiplmnokmntsnemlWllqssVmrmhnnlpnntkplnokmmvluroc{kmwz\mklrnolklbnwmnmkpeplnlolmvbljoZonmopoqsgnrnZmbootpplfUhlmol|n\npimpppplhplnumlomllolhmlqipnt]wlwlllgnjke[hppqmtmotpolpmjsi\jjrsnprijtnfnrmsmootrll`tqnvmtmosnToqtm}]ohrmtklmppdnkneuqpwvllatqllinln^qkloqnsoljooromsoqm|nanjtsnpsimiojzo~qpiljnnpwr{lk_rkjpX_oTjpmmjrbnulmposjswpoonjogsmrsmr}qsqtumpspemspqhlmg_Rxrmojlunqslokpsigpnmd{lklompizpn~gjrolc^lynmngruhxxtqpnmonsxqmkpijhn`tmmmorjksvrpgompqugpmomm`tjoogpoheoktirrgropokmniqtmnononojivtpvurbpjqpmqpusmtluspbfpfkspquxthojrsinmioqmmmplnkrljhpntqjljplpssrptrgqtvjqkulotlqoqhpnkhpnhkjinumepiarzrfkpqmwoqmnglnvinjgoplhofronnmylbmpkpldqgrninYxjnpprmsrnmslhltnmrljmnlkttlrtsnbmj_kkvkrmynststjkkqdeonohlmmlmldmjkokormxmhplmpmpklkrnTmsqnn]knpnilmomjmmmkjnoghoo_kjinnnnnhkonnojqpo[nk{m]Vj|jposqtfnguvnsllpmqp`xpVli_ojqnkmlomnivoacrquojkmootsqfelpqxjslnkcodojk_lmnnknonyfpokmrmcsp`phomhr{lhpu^njpmlq{oobwr^n[|cqejnqljep[mmiok`kqcpljlslajdkttjlwjqkkvnumrqpoompqdzfpshmrop|vcotnmsqqcinrpf_\jnmqpopzqdl^dioircwqrr}oklffsoqT|`copgsprjvortldpokwlrvmgnllqepnytqpnu]nqlpppnpmrfurjq|poijjsyaoXpkmie~isn`pnioshhkpqkldTpljmhrhYblnmhoopoqj|frj\ykjaltsjob{nkvaqsr;kq`npurpzlfnpdkqnurgmveokmrwn^Uoltuko|qsq\eyMxmjvgunhkjriOmtqqnmmv|tkiuoifjozlpmpfelo}prjh|uelrdq`ppj|niqgipqrijpivmfjnqjrzrpqd|tknbelncukitrksnwolthremqkjlintprnojifTmn|gewfks|zerwnsilpqlnklilrufvjqqzqinouxhrnlfkixhrtebupetpmhnXtsjoljohq{jcojfrlnlellgnifmljrsonpregerinmwkfiolsmhlllmlnqvpjolrdr{chwuiyjlrmkkwjkqmmsgjmcqinzqlomg`kwkmpscrfone^mtbviplhimqjfopnmogllreptsxb`nwqjmiuhzopjlpkftwsprjo\ptdnfvnkvlmcyqgoqhwmugyoiiexnhylYkvih^ksaikj{nmwni`acompsepomqhmmkpohoov[phloqmrpomojzrc_vjuepoikmqss}rhpptrlmqutunmgtnmdhkaoxqjiuppmgm_mzllivnrjrhlniYmvxpokdokyj`pzbhvkpcejlkdwyuji`rpludhJseZmmnkisopmxjnkZoqnpurpmnqmomnunplkntppohgfoonkSn]_okdopaouq]qmvqprmnlqprmynmqpobnltpunpmnkamaq}rnpjoSpkmlnnndltlscostknkpoelonmmfrmqojr_kbonymvqftiqlomvplppqnxamlmlmq||zoqkpoYdmqiomoikelublloopmmrjqlpnmlfobKre_mnsmpsqipqpnnmk^komqmtnqpokn}nkltnlpvqiwpXojonvbpnnrkolvjloprqsn^moouinclqonnslpmmvlToodvgpdlonpinqnmwnfigmmmkprvmghm]ckuioofnpnmg}phlyqnplojplnjhnnpvvol?rm}mojpbdkrp]nwqr{lmlqyqowmpohnvdlmoonnmnkljnnommlmmyp[ylamhofksllonnpkbbppngonqwqpsp]rkmwcrlhnpjkjrplmtpilopnplpVcsncorqk`ieilvrNrgsmkpnnmunpmkotongpkornxlmoo`sanlmjmtmknpis\jlkvt}jalbsrmkg}kpdnmpmlhlnhnnkhVgi~hhonormmryqMpilomm^sojmipqhrjnrqomSrjpnjdpsqqnhmonokinpiokvmymoopehnletpmvhsdnrnqrqf^eqgkl`ovoYn^lmqm~l|xspqmqmmmmjqqliyox^fkyrpegkfobnhnmmmojmmjri^oipwml|q|hmnptnrovrn]rlnq~untn\ooo{nllhnolnyjpnonsvlqnjoomnmkxqk_jjbj{znjiftzqrlzqn~qepqljnkco_\o{bknt[grqnnpqibk{p[|pmwuhlponlpoyqqvnjqjipknl}eknmin[nnnokqcl}kollfnosnsomnhfpqhlpvnoklojon}bnykrSlmimn{jokh`am^zwmlp`hlqNonumbwckvj~pvjrvpnnk{munmmkkqjntWoisklhooqgeprrumpplldjirpsnqbopmvnlnwhloholmntjlomlonomnionmnn{jvlnorvjp[kznknkoonuprkmolpllns{rpsitlWimlpjnll^lml[tnorq^fkkqjsmo]nmlo]tlpnkgjpqngndnlbllhmkvmmimhjvpnymjkmkojkkn__nnqlpmnhrnSkkgpYnq{lpkigvppiqpnikmngpjrnqmitkrjplmmfmqmmjnoposvo_llmtogypdoojoh^koimvxptrrguqqnnrqpjmlrjnjoqmllpqotfpngnlprrqolpomnCqkoltqvkjfpxngliqmbs[lmmqmnvoVng[sdnpbo]qlrmnjqtquxlqhswklpmnlnvdslksqsnllospnqn{pZqlmqhjqkm_mkpforelmmoooonhpvVpnrrjofyplllhn_zvq_mmnnfnlhfhkol{vlosionpiVq`ligmpnjkskfmflmhonymnojhfyoqkglpgzSmtpons]knreoqjnsjnno^qkn}sgkqknkinlns|m\promnlkvpps[rmpi|pfzrnjnzlnmso{qnupynqnmoqmnrvn\qpfjgxnporupmjvktdmolmyinjlpnmjdspqipVlqlp`\nio\o`rrWqqlyvVmmipnjkmqvmmmovlnomltnljrjrmlznsdmpoqujlemmqjvglihmlnk^_klrlmun{pmfehdblmxlpxkknslqnmodnko[qYqngmiolzjoknisbonimyklxwmnsspcskxorlriaruibwgloklrfoxclgqirqsojijeikfppsmktpsjkojrgimmolflitsnjxkhiqhsllcluopmnuqamoilsdmvohgr|kjrfkqnxkmldfzklxpoiammootmilpgoppnjlodmeloslqninhhqogq_fjdvjmhjirpwngprnhkrpmntmhkuqqfoonfikq|grlqlmrmgqjqldhklnojnqo{nxxgjhknjriqssjqlqgilollpqnlksrpliyrml{vommslonvnlqalqonehflpoki{aokscsxjqorrel`skvowochqppcilqpoukntqvfkvqvS{qnumkmpoulssZrjosxfyrtkgomsbggtqveimrfp{}mriopronolsnnznhojmknmvrorlmrhnpkjmljnprdkknlhkqsunpgnmplk`uxmgX`rrlncnsckl}qjfnnu`rj|lmsktdmepismpxtatlmgdwklowsmqswnomiztmeqoopgnhxnpsmklqlugnolnoijvnooyiromolpnmsmnmrpknrmuphqqmrlnrmmojqoofjjjpjmrjnsorqisqsknimrtjmwnpjqmqlqpoqnlpsipkirkjporrvjsqnmrniroololmjmlrktnmmotnlnpskrmfnum|rntomnjnpkkrnlhnsjmrijnkkmronkmmooqnonnqsmgmfknjoio}pmrrommonoolmqjinmjmollqjnsknqmnosvlnkmmnonmpgyrjmj|okhmhnlnsrkqSqulnoxonvcqpoqrjomqnlum^pofuj{o|ull_mqmumnnudnnroontpjnroqufSoploqknYmTyx|oqescmnpolqknrnmi|mjilpvlloqolloesjSnjobc_jlrkunioidknmpootkktfYomjksicxpnesqcmgcimYjormkhnllmnmmmqmogtnsopk\nwl~comqjlpmxlqllknknpslujppmgnrqmotmomvrcatilbqernnmjjqlm^kmmeosorpnknzllonnmunllmljiklnripnhnknrjumkntnkinbo_mqmkqocmvjkfvhi\yhnglsqonvo]ok]onnm|joolpjmkbvoo[ps^pmjnqxnmpwpkpo]pmohmjonymuorqjclnnlqrrjmkTmlnpsnl\Wlomlon|gklukolk[iksyyllnlxnnwpitipjppcuigmnvjkhkwopqmologjiorvfsmolionaqfmlnuvrsnlwsngmlsnibnqnnckjvummrn[wimsqlnjmymg{nopsrjrklrftodpnmnqoinrkpkrlbmej^nlfhtlfutlwgonqrnytgppkfndmnsmrooorlhiihiqhfivl^frlmnttchfrqyikf{vomnxrlulmjcpfjqlbsfpmrtihjnfc_rimonisdfkiohqohnvjqjsllkjnykoqqlmcnkqigtrnl|mujzujilsmjnmilxlwtqikkirlnksrvsmeulprmejfinhlkikjojjhxnlqoplmprl\ltipnmllkpqkiglqlhdjsigipkqibrokrmjnlfvvmmvimqoaiq|ktjgnffvslyzahapuikkxixsskejilnilhsgwlmfmrlpoibeqlujhsmq^npfljn|haiodmoojtijo_pxlhagelomoisrjjtqouwjoplvgjdqqnf_ipkkrkilpsrknqonzmjsvrlldgxtx\uv|njnclqnmqtummgZrjpivuoslm`fmtrfojnnmlqltsnjmkekitlklaolmo}nllmmmfoyk]igmrql|msjnnlljpkklgmaukvegkpqxnonmtmkuhgphrohjozqmlqfn`usoph{grouosilwhUeofsophiinnqnqntkqxsfofnegn}kwlqnmmonksojyphonmqconpviokdomsllhjnkioleilkjqimz`jofoirk]rkpnlgitaxoorrluismiio|emoihwlnenfnjtnnophsommkwmmwnqqfsimuloqmlpnolajihgVgjfmpjnpplprnpmpkrlohgefrmlglorkpklnqlsmlklknkloemc~nmSiimomqtrsuphoohmhkpkmewspqjoqpocnnksnsjmlhkkkmrloalmsjkgnirukiratlrglrrpihoknclnpvkjmgnhhqokqjmlqplrnmkoomoqrlquhptpmlojiopmgompmrjkchidofmsitrom^reikplkm{hodrrsnriodkknnnkhieiuqkiplilppplmlkmkswqrnphop`slincjpnicoqnjqnlnmonlirl_njupZopo[kyo]mokcjnfoqpknpmlvpeomzcqyxmhjkqnocl[mmsnlrrqglmljlmwiojtcquoiuqqwmlqqn|imhnlm{t|uoolqpPlkkpjnpptspoqvjplprqosvhoatsnpdlXjegplpjfhlklkopp_lrqqjuogkl}ghhqjiooqhmppipnqii{nmmybmnrkn`lp]\ennjp_rodpXlXnppoyqnnvnmkgoonkrlplinlokmlslmnomniknnqfkvoovij^niqkqrhnumfknirwmqlonlntYiiqlkvykqynhpkmbowoomnogr}uqrkqlmjynlklmlojjsvolol`otmmbrljoomWmcqYljfqlltnvwilph`lmmojmjpunojmfpuyzo~qorjnglqnlpmrVjrmpmunwllumrlm^ipplqriioippmnrmtlndhjprcn]mokvWlnohTlrqoqmcs{ipujawnoohrjfxknikzvnkqnetzlkkjjmrhqrpnmkhjcglpmfihlmhdjlhlrnosfpoeYnhquflohg\hvliamtjunrkfklp`khgiujhqdqpjlpqtsojhtsqlhgk\npmmhrohoquwnlolohnpm_gsxfkkwopikmrnnksunhkmpfivjl^kjshjol~theomdgdbqpkmtwukjhekjfltprq}rdoopciuhn}ph}mggl~olmfdkcolmyplgpymgu{huupunioqlesuilfpjupktvlonofoglnlrh`ejuroglnzppavgfokopsqwlmjrymfpspgmunpjvlproqsghjkohqwvm{vk|piaypymhtojmxmpgqolhqkkiuymikkslnjqjhpgurilzksqjncnsksalymngnklkpnglcjhjuhlmlounfqpppwdsrpiek}cffoikoqljkniislwoumlpq{uqkfhhmwqomjhrwkgqp_ndmnckgulxfpupkljgpf}gfxljln`qncuxovkcjipsilmqqphmepkipulqhpurotojrkm_{exrrhlaw]mepyxonuiuknkok_msXfop{cadurmmkoqozno]tehsvrkronlspvqeilmhq^wl{m^lvowklmjpwkjlhnotmpmomhmlkqgm]ojjqvipqkqrysvkuslkpoom[fckbvkjoossscjjrnbqlj_poos~hpgozrfwosbjnnq]mhlplmmoxknmvr^rmpaspbooektppphoolujnpmmwtnkmsulppqknbnqkrrmmogj`lqomrkfonlknnqnn`qiLhdomdosm`gdroxqrsmlnn\oxmyvjcozpmnornkMlqktvrowwarkpnumnevfrqrooopngrytptnqm_npqwkopzoo`nfpemqckpminqknjlc{nnjmjr_mrckdligppionpdsylslpqkkgelkgmmrpblntpHhmpnqoim{opqqllqjupkloqlkn|ntln^ldlptneop]lPlhvkklopse`nuonjq]eigiaxivnplskpymssipospiitmua{e{mmoorphcnkfoclwknqmllfusjgptmsqlnsslutomimqwbs{gihuruipvctkoojkjgqofopvmjqlqlmstrhopxj{krdotjsfqinqsynqcdkcjbjxordia|wppmnrnlnirsdpblqap|pklsmomollmbhkpqnswqtqtylofWilkkqpemkcr|ogtmkryghqkouinrillrjorepzf_rl^smzlteilsbgnlohodomkoljmirotluhlk^vggjwrdjjrkljmfjogpfmjrju\mjom`qqgpmjglq`wp^hhpjerchsiciqsserqksZvjfuehhphsggfsYlih\lqomhnaqekiqqijejsuqfrfnsjrvqo]qoomq}psjorkxsqupuohnqhtmhkq_maljtrnu{pmmulqqlnbopzcjpqmkugzimsfenoemtskplTtsamjmngenypfrrjwqfknprjpeobrrjjnzsimqmmozpml^inmtwsiosemcmmonlonkmj^pmdrnkswprtfmvovnnogoowqtnnnqpolotjpPrp[psrvjmrpnrtr}lofnnpngigmlijmmpntl|niFjl~mlgkkmhn]lmtnnnujrondmaoUmoxksmltmpqmnamknklop\ho\gpphqboclnmqkjoepomqltnq}jkik|hieihmrwnlusouqymvmsrjn`kqn}|mnjrnamqyuimmssvuollsfrsolnlammmgplp_npoqgjmnYvnoeekklorgkjhknpokoinpenzjnhsn`l^nlkrgnwrckmpmpnoolrehsu{lhhmgrmlypolqqnsoyjljnmwm_qojmnocQgjtoonponmzekslkm[u^lnqoulgureolmqiyolpobijqprmkmislVxsio~lfs_oqmikrsgfmmnw`mp[ohrnslwq^mpkblkpmolmynlopoxmqkmmmptrkyqjlnoumpjqm[pqp[ng{hqqqmkokjdguwllth_ggjlkmpllvncgjs{pqprojchfxYpbmkmmjimcpaklkdhmufnihkhnqfmknkukmfgZn`i|ktl]hqengzfcbhYSmpftifqamhmco_kRnlrlkmkb~mveupqhekiyojlbhp}fdboumdwymniijphlknjhktljnjmfnms\eiotjoecjhnkWtoqpqigokk`olf~ytpoptvhjqjmozttdkknrmsilmoromhlklndiZjWlfjPriirwrwlqsdqkpn_ollioonjnqilf`kdqkbfumnojkVerZps[lunqjkkgpnrknmmoklklonknjmapgmeksjnmhpnomgmohxkifxfxrqpcomjqqjrlumgujmh`pommrmlfjnnlpknlltahaflslnnotkqpprnlilpsxjhnkbm{crndkvjnkkzphtlfue{rrpijongimomommgsloihxnjprnpenpupnjuljjgmnmkufpkajkhomhllousp~ojw}jjkd|kfrrmpxxmp{jzolnkmhmrlirgtyw}onpiviiypfnmcjhlpjppn|nspnmknnojjbnrvtofoxrkpjton~dqqmnvxcqnow|wlcuptqmnnqcznjmtkylppktjspooqksmujrpoqlrlnqnnl{nilhsttmknspmjkdoirpnpjnnokposkmspmlfintolfonnqonfoljannopmjkrsoropqopqo{orns~kwuknonlhpqokwlvpklilstmuulriurojlgqkgidjhfipipugohovtnshigifkjkbtekpmfh]qpmhlnmtnrj^Znknforqlsntikugmscjorkungapqirnrksimcnhnmrghouprmnlcokrhbinstalnouigipplokklkinemogytmxmfoqw~mejplqgmsulf_qamw`rslwninfkphlkjnyy`djmnhix{nkgslxurosk^nqkrmpnfmpmpqqnpnojjqnrup~mjikrwsgkntz|olgralfnxqonmrmlpkrkkpqlnvjpmjqosltgbpithmk|mkptoqkrmnmlfiutnpqnamxrjloujlmkhriombimskkms{o[jjolqkpmqqmytqlzbn\ghpppqcnpekmkrjktkxqkkjlziktbkiomllpjnfv^liellor]j]pvjkkmiZfmwlkyolrp\jonponmoXlqrlqnrtnonggltqc|jqlpnomyswhehlmhklxlrjorkinqjchocprqnmuognuqplphlnnlqkonmytqrnpifkmmtorn{|nksllxmcqfrijo^VklcmtkqfprjjponikpXnqimsiqnhpZqqisknfxpeoocnnmk}mhifptkhnnoklmfamntr`\ktfqinYpbjrkgtsroggmrhqdilggqmgkqlihjhsWZjfjocnbonojonlljjc}jknpalfoiksnilslnkrkompwiuwnlkbconn\qlwmrqjwmqnmZ^qqreolp`rikm_koVnrvoopilrri`rolqpxmarhrglqnondkjm`shssrrk{riunoknwn^nnkljpkglqflnrrs{ocljrpkrmnoqinsrnmimpiksihlkqjpooqlloollx}oohptyrknobiiknrrkmkfmndhvokmo[pls_jlpewmlnpllkpmqlvnlrqrprwmqomrzbpngkmfhsjnmnlkimlniwkmowmljjprnrgj`nlsnlmoj`qnfmlnirspelpxcowhlroftkhkqwojjokmopjlplkknnpltoenygxkrtlqmorhX[uosjmpcloujmomcqgtkgXjwWovklzonlz\rrlkbpimogqkrvjpq~sbikleirmjveppnljvurmf}oddmruyqnqrbsyhrc}jpoorrldoztvlptqlonslo}ljpqsmqnabghlpn[gjlypovdqoirnnljefcnnopl`lgciouupgnddlmhdnpqxgqeqrl`\n_lvuomokvejeqityomcjvrsrmnmqoXkktgyglxfyifnkvnnoijrnnnpi`qlWgk^ukroiZmtsdjgqnmmnlspxw^jgmvumiqttljsfgrosnnqucljorrulhjpqkmzuumpttn_mlnmrbtsvojohoj\qgnopytcymjphpsmdprfinjtotrklqulimqoimolqjvwmtiesojhjdineoolxqghknnklopwmwjnhn^jilrpjollcmlqsoudn_micqqpondrijzutkexvjomtlwqtlmsnwpmoinpkprwgjmosqehsoaqnprnq[nppjpnpnmpnoprtoramnmndmlolmrppoquvliiqr\Yqy[mdpXldjnrnlwnolokmjmgtis^l}eXomgnoprmnoBjovpqjrpskppnljxrhm~oipnlrk~kmpvkvnommhlvvdqmrkqntokeklnoqonnemr|mjipnnjn~lyqjTmn`upomnpir}lpVlpsqhrnpdllqo_ltjrqmfYpnwllfsenqonmoptnlnwyysqumjpM`gnokrbqoep\mrjjjqloealk`lkpnmpmflUgokhrhmpnrlqlXsmjihlrnpigljrsfnkqonpnmdnmnllhlnlznkknfnlpnihplofnmijmmryoigdniillmibmeuc{rmjdmklqhohbjljjqnoqogonplmtqwnpjqkpx_nj`mp_qjoipnlkiqrzgluqljqmgopjpoojnjjjkmomnlfltonoydlokp}rmonrkqerd{tknkidahpndqrmplsrjkmrolghrtqoopqmbndmndmlooHupnlxoqntlonimmlporomimjvnnpoolpmonDynrorxkl\orem|pvmloorn`qxknonlopldOodelzhSdlinlnpnSnaohanpkrlmplomlhjropvmbllmmonflommtmnslomff`kllplrhpoqoklsmhrlkms^nlqlqmjvkm|gnankizkqonsofloq{qnpnulnnclplmossg~hjnhrnqlkkolmoopqlrepmnl}yuoonlp[ijllrrpjzn`poxpdkptrokrykjoognnhqunhojowgsqknqknmcjnfinl}ifnjjlhmliwzwnipp`ohfdxiohkmdm{pkqogmrfhnmgbophlgsanonlywnolda~xprcopgrtdlpasuqkrjkjmnihsp^mqmhtnnflmorsondomkwfllpoqtrnxkinoenjognnmkhnmtpllkn~ksrgkmmjiperoxqmivsmrjommeiiwfnrnqnw]kootuntlnjtanjkkarrmorrnaqusqkrndznnrqsonusnnroonqemqprrmqlkqkmpoqmpsSpfkf\mnRqeopzvVmijtnnypjonnrnoell~kuxr^qPrnlrpjmbryn{pjrqqNqvomlmozubpsqoHmnepqslpk\nnnmanknt{Uulqk\pvonbnnktrsqhkos}nkoqkppyqqefnemziymimqxtemouinompmrlppnbqowrrkenknnjn~nklkotkotsjknTirlp|lnkmTxijlh`xoomsomrpnQplqmwkmmvnnokkrnp[ynnxoqbqmlkmqqooqnliarnslgwrznvpsnrmcmmlfmntknppmqjji_plVl_pcmlmporlblcrknlohphnolln]yuoptkm[iobotuqonsmlmkunpmjyrpjoro_oq`oplgrrtirlxrrulmhr`celdrnnk~enoxonpsu{lsycnutgwouqjopomhjrm^jreqpslniojnhomims{lnn}hukn`nrpmjnlpn{brvl^soqienuilxnnyqlxjeqmscjoofmnmpcmdoskuk|mnmpvetoholitquhnphmprq|jthukhpzlppnpnotp}umhttnimkpulTsquqrkpooptxltlrfkoxqlxrodvjjplkkfnrlgmngoqrinknmqmqisrepqdqnljqqohprrklnkgkotqllkkpkwnggggomokhqqtvommmonfvenvomnpdlki|upxkptsoolkklpnxvfgmfbkonrptmtkelisrepphcnklnkxhuotowqiuiwn^fyblolpipkmjtjnloybmcepiykikjooolllatnrjmqqmtqfoupqkllmtpumjqpmo`unmxpgijtoruoaqmllkdqr}lfps|tuhrmvnpjwknn|qspa{qfhorsoflpmq`mturfkn]knmthhmtgiyxcrnmrjqimnipnoiikpnoojnirmfyqjtjtqhgemktlqrnaqehjrtiqkhdrnkilp_kylxpjkmotlmjotfbmlmhjnbihkqjhquknorqfcvp]tuqokDosjcyokxm^`neovxqjcps\o|gniopWobbrzkgpan`kptnuoptelspdcgjo`inpkbiWfsqUonjjnehsjmhhdH{bwpirokmjgkqsklbYpnoomqk|efdirbmmovroxdpsckgguiZhphmfblvvdqmpndmzmmptmhgo^mpoimehWwgntUnqg\zlqonmntqnkmr}wonmfpppxnqsstpiulqomsvpk^lhaonjenPmwmuokpkoljhzjorkntsqpqpqcrnmlooospjuiu}ujll`sugpmmpioscmfrpouookoipiglinflkgkctkkqllpqpp~okhbjom{ggmxhunpisqbbrkppoqboqomlmlwknqiiqdnghlolokindptunqr`tqgbqbr\lmspknnrjjawntiljl^kipmjakqjljonrpoqbo}rmnlhliXso_noqloxstiimloupmywqkj`mqdsqflrjnusgtvnohnsopnsmfnpn^mqmksmiold`smvmkmgwikmonmkkmpmnqxchwcnjqkmnpnvgijnoTuohmiodngonojimymkeqohrhhqfktrvhphhujnjmmwkhhngdjn_fjtgiwrjgiopnrmeqzrtkzhoillpnsighnlomosjypnfumduupmsonlniqqohuimgrngkdmnmmtwnvjxbkmloogrylpmoswyqchhZhmlvlteyobeyptmrfincqkmtbilqkijkksljpfmtnmmkmjvpwqjfjorlekkl`nlhhqnqgt~glmhnhnpopjsg]quhkpmmhov`qlpkijdjlrtnqfojnsipokt]ojskjooqokrpjhuohgftoqpsmbknoeeojm]h~xlrpmflqjlllhmirkghtppqamrtjpjrpipowlqrusjnZocomllfcpnqxt{~cgejmkqommvgpmyplhkqhntpjflsksmurflionhprhkmjmep]tznroogkkql_qpemionhnhqhehmtrhlllrsmq_pkjnlqqieqpmdinnion_nnmloqnnz`lxnjlqmnlkoozekjlhfkpfoqsoyo}qopaonrmsnlklpotlYqqldpnpe|orjojpmotqlilpskanrnlnkogckpl`lsZopcpz{oqocntkowolk_kunlwnaj{no~ommkqioqnntljqkvpmboqmgmhol^eiotlsoxukn]slpqjZlmvnjcmwjkjKploiooqnioqplmmonigopmejrpn|jvmopfomjih\sn|khlrklrkidpjm}pmnzmmndolorckom]`kmlmmlnsrmlnsmpnkdoifopnXj{opppqopxkklronmmmkihmuir}\ijglosmoemlsppnim{jrrmrppqyrnlwnshokZsxgmmnbl|lnynkrMrjl]msqkqkqqnpsslqlnkm]lornmpvjhpijnpoxu`nnloopenquSnkniylllmtnpgnnvmnUrfpknuompkvnhlnppn]pnlgwYntkjwnmTpnoppmEqpynkpan`qooeemomumnJh`p`n{ssrfcvpzkrduqWZpnodmmgrblnekxdmfvncpfnblQsmqrbmccunsompjpnhkolkknsWlncnogkyprw`qqpgXyrqcqRonnoraohkjjnhqqr`ruqePrloenq|rsw~oiPujosnmhklon{jqvgkklqkp`mrrrkepjqabmhdsoh^kqmmpgnohO_mwmqlojujnbiPujsm^i~tyqsxeTfmqqnuklofimopdpoutlpdi{o_lmlqkmeliudgeuorfnlpmgokj_rbxvrux_hnzoqitqxpfqn|lnsmbwnlhi~jpwqrewkpgjnpqsopYppmnkjthwv}nsoyqlnldpunmvjjmjinlmsudpmhlqeilt_`qkpxmkpfqlnrnpnbmnrVsokquabosyivhipdnhqmmkmmo`lslqk`jjijlkfmqsi\nromlmikkjnrkqlnoyqta]lrrqlqnslojekomiqqmbopjqjhjsitolhoplnhmckpjqglfmlmd`exudvrqxk_psmqpqsmijgkx|zsoisjqflsomsokojlfpkwnrplgjmnnwzygnegjjrnjurmlkdwjlqjwdx\vqbgjkzplmqrfjodagrqtwqoggmgfojoltnontunuzk_ignosuilejqhbohqkgfjlpfpgrmuYdrhxpgmmilrtmmomidjbhmxpprhmltekiouofpkevqqk^pwsjneo|mninilosonjrjomlmrr`mnkkmgwsmq^tn^ojllrujnodolmmljmqlqllcinmohhhoijrokkxmlqlk^ng~eyotm{mernoqncnnrhnmlnqnllwaixu{t|[yiolmqldpkseqnqnleqqqoqvowtkkrhmmfronmjokotnplmkjjnj\yllxmroZmowminpsnmnhqlonknmghnhmokbrmlpusnaslqnlnoopnnnlamq}qlblxpoijpinqrqmlkookjrmloxsnqchhmuqn]oofePjqqltsnkqrpnwqjknrqelixiotsemoujoomjuo}mlrosumnuhoqolpzkkfzgpmnmxhorqmpikdstovstitrspqntkkppsoylotqocpimbhxo`kmnfgksucsrqkpsutouqpjrrpnrqrnpdrkgnixokmnrmqmmrxtssklmtyftokqtylqioznnmnersmylpppjiwjmzZow{qqnornsnsrypl_hvthqbommy_gpk`oemokf{timlzqpqvhqqourqgooqmqstrpunhyjpuoq|llX{hmntmkdryrhhqqpptmqbnqi{otniiqlaniolraotsjqeml`nymuneqiqpikfteftmlocjpmZps{reyowmuuconfere{mgirgmoivsofitqolsqijpoj\qgsvrlmoslqmtoq^mrzldmmn|inqpjlqoxklnrtqngupbimjigpskorjmlyrkgoonuu|jisu\pnvmj{muhzxykxfjxtoxpjgi}lijghjsmgibkfezqknhl}mslormjmtkhelpcwmjvnqpsshopmpokntrsskk]xkjowkqrqhpmjkhmppwkmjlinlcrthsqrhpognqgprsszmmjmYmpfle~mvhsnlooyookqrmkjlnqjqglplgroqlnlploknnWkoryjrmqqnjtpmljeptglgkqkt|nhkiolskoporvnvpjcqkkmkppiijrpnjtqgmplrychwhprvojnnuomfhokorqjbmgtjngdpmn}mpplqjpripjermnnmpofngrf`sgnllknpkpsrgpkqifjgprldlmnnxli{m2qnhoogofepnpkonbklegjlmqsnogjknijlll_rootnctnrfrmftkpaicqnnujmcuupum[rzklonbxpyookjrkjjkpspikakl_npioiln|lkl`rtroquoqrrakpxcslZvpnolejoposvocsqlgrknsjhpjtriss[[qjbjmdqpjrlxlrgaoMkcglqulgk`ieenoVnnnnsnLnnohmlnitbnqq^vlsho_}ounqnnqYlnpvwotlpvjmilcnjmnqkgimnoo~smlotqp[mkp~nppWknaomoojponcow^ktOrmuxpptomtinnkUr\qrmtoOwsohonnosmtkPrwuml]nfnqrlqwomvrlka`frnejsqXnlfmomrnmupjqv]mllmnpx}o|foqmgxrudoolkl[isrrnojslmofrmqpisek_hlmprhknujhojmkojmjrmmunfhu^k^nmhnuinptkuosotpmlklnTkhpnnpqr`vmonnqnppfnnt_l}korpnpkpoooyokrnnRjx`fdrvmritmpqcnnomlqxnbghgbniff|vflqplrzkr~wnlilkqmpnilltxtjsqrd\oogomYotoknnvmkrgpmQalnnp_parmvqrnjpovljqbdhjmkmlsnvopprlz}ryklsod|pukpoonhpmllllqmlpwoqzhkjfonknrptnhooknoapmni^ltroeppqbqksunbppop|nknllojemjntonl_mtkionmqnsnosllmoqjnmnspnltunjqnmreoptgqejqnqkdrofm|jmnlnmtngrmxigknuwnqoopnirmem|nnokljlpknpmmgrsomkpqjlmppklmorqnnkogomolnimncpjq~lksknlkotqpoq]wnnloolkkqoojlclltynnmmnptmjmwioonikmommoolkjxmdspqgjoonmqrdolnplknroomZiholgmfoop{{nlpqomlnkuhnjkupollsmonaosnqepkoonoplnpmnlpmkorhuhmbqntkemuimkkmmkqmpkoqq_jtrhnrkonmjmmolmmtonpjbqojimohrnlhnomrdnmhfsvmttllhnrinrnnqopmmfiocljonprjfnnrooomskvjqpjokpgoltppnmokospjmmmlmtk^llprrknhqojkrnlthljopnllocmphopsrnpkngogjqriosmtnkpprfmphrtrnnqulmjsrrkrmmitsmorjstqgurnpwjlqrmmnpkpuntdqomlmnnqpkjkomnlogorrlkkyrri`nrsgmhlsnorqqnopqoienhjpmepkqjxrpjinogliTmykmsksimnmsoplipsigmopmkdlxsmpobkwonpmluipmtokjbnynpbpootpoppml^eomsoomopqppptsn~ifuqpqnvpindtlmnrtonqliqlplrivpkngsmonlrleokjopjmnmnpslmslzkpponhnqqpnapnimmknq`_nrqtjuorfnlkgtqpPLqomoovonq{sphkssmkmindqupkipviom_p^kkmlvroohnkjnppnolqjkormlmnl\izm_ojkhnqokmc|itklsOphxplnxusolilknlqkdtpimufnemqloommqrlYlnkqshmnoxngnojuq`rqplvnmolmmq|rpoenikbrplqplfnqmqvosoglwmnorlnkplllnp|qorpnarkjolssjknrfgkrojnaip^qplimjpliklqobloquklnkuoplilplimhhkjnjnskhnkqlqarklpkfkojjgnuwnforoipnqnwmonlrnnimiqmmnnqlvopnqpjsnnmvseoqnlmnpljqjjgbmnjqpkrrhsmnmonomrqokollmksmoptknpopnfiikrnmmclgo}ofrhjenu|sitmpmqfnrrqpaiqmqdqmlnotkxropnuujmcsqhtimnkkimlpqoomjlojhpmknvloofqlinikllkljnnjkqjiljnsjgjjltijhltmuulkqoebnaomhpnrnvoavjty{nrllinplnilgooppninioinupnlsnivqqlmkmqiltpmxorlramostsqndiqrimj{nijlwqZufrhplhtqoihrqllkngkfsmjnkrntgonipmvmhidbqorefioilutrklifmxhdmqkkmikmcikqlgqgonmvklnijeohoalnmslppjdq`mrqoqmrnhlnikppmjlkvqksodnmoipimmiiemlhqelvnnnnsjnsrosrmoppgnmonpmmopflnypjqnomoonponkpcmspnoskjotinjp}nrikjoijlnnnmnlvmlnrllio~qmqeoonoodowjarkkulnkpoplqoymoiomnpjpn{k`fpkquornnpnppvjhmnblgpnmmlpnnnnsokk~}oomprnjionwiqpo\prixqmkn_jjkXioppkopjinlkhl|dl~slvqpkomlpgolmnlnmpnno}cdiomogppwnpmmnrjmlmjtlktsrsnlrinmuirlrmppsmuqmjjldqirrokqpspenmerjknujnprrjmplvnnmgrkommpnmmwqmlsnqplooknorqqkqlpkpqkhpjmklmlvmqompjmsrloummbjpirtllpkslrolmlpqjogimkynntrwmmmpwp{kjomkpnonnntkoqqnptinoysukrpsjkprnijormlomoujjwomnvphznslpmqwsplqpgsniosjmoskrjonqnqqntqrstprjunilkhhnoontlnnpulmiWipklknrqsqknjdqiomnonnlinmloionkqog_kxzlfonnnkapnetmomqhmmrotnnhqklnohqgnoonrbqglfpmnoplmoqqmknvnilkfmrrkmtmhjmmqsommmppllqpxuolmrpgoqskooosomnnmmomnqupq|sknymqbonmwlnlnlqvekohumoo|rmomkknmjqnqxmkqulnfnrfldomlnskkionmjmcsnfkklnunblmrhxonqluokmmnmnemnpipmngpunglokopxpniopYonnkqnprms{gmpplvivrqqznioonloqpp_jmknpqonumwvnqmovnomnwkkoolql]qnqkopogqsjnojnsnrprknismmepjtmnmrnmmmpknnrpinnvmmmrrmermorqnjmjqinomoplhklqrplkprkskgmnlss]iuhunrowhoouootorpmn`trlrmmlnpojfnkoooormmlnqqnnmsmelnilansnlorosrosqggeqnmllgksimqloppmiljplnnkmplogkgopnpklopjrolrkkignmjnvtnolpmmotsqokolofpjoppotoluolqoleornpmirmorrlpcsnlhnptrnhpoiknmqimoookcmcoomohrniqppmlkomsqtpmqliijljpjnlopqeuhnojnklminqmoqplmpkoomopnqjhoqnwkjpbpmnrqmjrnnfrjjkrptjnppinnmoiswpnnsmprskkonzlnssplpxqoqqiarffopdorikitmlpk~mnmokmboftmflqsutkpwpqrorolologmbilnoouqeno}snqonitismdtmpxommmrnh}pqvrvcjpmprresmqqj}nhoullktukhmtplmhpOeinokilmwhkqmnonrrjwoqrg{rtlcjbtiophmohppniomoo}knlrpkm_nqsnruskolrlnsoshXhjmh{hprcpoikpmrprqpmowjmipjrslloocmmnwpotkqeqovqnp{nmjkknmkrmnrhloljmmjomotqkhlnhiqrnonokosgnoqsihqptoossl`jnnumllqoonomnmmlnomoj|olqlfxopmkpkonmhp_mvjjlrjjkkolntnrmkmjimoflouqpfnnknopokgomqlolnnporjpnoxmpopnklkloumknnnmmfppoyjpqqupltppmronfciykprlovnqlopsofextpwssnonurqmljoeommmmpspluqnlgrliprpkopopmhspqlnrkljindonisqonlunpomkklqmurptqnonlllqjonlmxrprqmklhqojtjnr|qnmmhnissoppsnnulnlmmrnkdprpsigooiqlrmqrlljmrnsmmnhohhkqqfoqbmnpmndnmqnlmprpmkqjhrtoqnsoslpkojnljivlllnqqisgkocpdn|invoojhlkqlppksgjnuhqqmznnhomukoiblp_ynkinnllglspjmkulmhoijpanhkknjnplwtmlpowmiqqmpljkllkq~lophdippmiopepbptkmlljlkjn^{cnhilpwkoldfinrkkjhmntlojrnlnkpmluvogpjmrloomsksnnkngkoombphlhkm`rsjqmq^mlinoktq[qgaannqljmfskominknmopmpnnZoenliplkqngnnkmvmmocpmspllpikojmrphkonilmfniqmnqijnkqlsmhthjrgugmonrmmo^efqsmplmnilanrfjummellspsjeoqnhnklnisnnkomXlrlmnnrivgjiomrl{mimncjlkdslpqikpooqkkonjhnqtkkolseomnnlcnhpmglqknosiqnivptnvlsikpnpiomgplqnklqghqsrojrlkqqoohipliolonomo^jiqqqlpgnkojjcnhmpdljhnmtokpjqqolokjhjjmumhnlkoymllmqlppspyofrooppnonjoltmrplqhklonmqhpjovjpnfkrmljmnlltrnpodtmnnqpiosmjnljmhmqomplnlpmrolmcnmmmjnlprkilgknnflmpnmnnqjslnlquihimnpjhqntqmqunooxhm`nhnlooonsojlmjcjnb_kovrknmqplljjkpmllqqqnrlmoptokkqinbmmjorhmqopqyknqolnsnooomfk`mlennnkknrmom\mlpokpmtnmqnmimbphmooomneqnkjimpnqolmlmoknsoijlskmjlommpmouojqomnnvnjnyryoppldkpomhmmookvnpnhhimnkpgqspljknlumnmqojlotmmmmirknrlnornlkmwzljqlnorinqiokpdmlmrrmtnllnqkmoumykpkhkeoUhqmpoolocpjoiomllogomnrgqpeqnjpjogkonkoljoqmrogklsommicaplnktlxmoslmnlnskpnpncltorrllhqnrllsmnmopqmnjiwropknsmfwmoropjnqrie_jrooootmsvmunlolookwomnfuhtoxqdlmdqvqosppmlnnktoovonppshsimnsjgmwpndnbqnmppppsioognjnnnluo{pncsq}mjwmqgtmelohmsmtjmpkknjmf`gnpmmqtsnjpoimnmlpujohpqnpppnethn^evhnpioslnlpoppjnukqmrlojihrnloqnslmnkfnkWobpmmnknjkqjn}_hokqknrnqmmionhnnrrdo}ooqssslqkllqpmonmpkpnpimqrksspmqslmejnpr{hpvpquropsqosdaimmrimlmplkomkpoirnolklprpirmotokplljlppqltnohlksnfijosjpmqrkiqlooojommplkninvsnnlojoolqmqrnmpklsnknpmmntjohqplpiprjpuunhprnsomhommpnfolllllrqromqomrmmsttmvpnjmnrlrmmkkrkliiprloqmjmroolkmprloompkmpplpjoqooiookpqlspinmlzqotfemnnipplmhhnonklronilrlrilsmohlpppllntllqprinngtjmrugjpoflkjqzhnppnkijkpjlf^ojmkomprsvnpjpvhotnqskloipxopplsnorgrvjolqmoehomrrlijsnoprsomulntbtmokjomlloivnrumxokkmkklfbmgkvuoelcjpqomqkninrwmfgrwpkg\nlilgljinkhoojklxljsnoqnilaromwtipldnnjolssw^vozpjpnnqqnpk`vvtorqukfprlibopfokjmrlopkprlnnspovnqrlnlmnmtimopdonm]onlqqmlnnmjmvfobnknppjsnolellmrnqnmlnqrqlounmnrmnolmolmmknqldtphmkoq^lmopoplmkpjodimonqsmpomqllvtmnmomklnqorjnpmjnoqpslmmenphonpjkamploknmplrsnlehmooporsilmionwojpxlxrmmoonnkcpnmnploqtmmnnpnwoodhmkonrpntqrnnmommommkntwprnpojmmvpqmlmlnqmkoplnmjoqnqrmooxknotkjpzmkinjnnnmnleojmkskklsnoojlkipvjjdomvqmlsnolurqmppprplpkqmnnnnqmokponmqanjkbjjholoohopsmrjkmphpqiouppnklpnalojlrmmlpqsspkljlrnmrhnktpwmmklyfuumrjooklolnmotlnqis}psnkkmljnnjlvkonnhnsnwqouuonqkjpdmjqmqljkuomfofjlmnlmliponqwoportcnopmhmsnmgj}{meoteululpoojrlwkufnmlnloinlnpjjogjolrilp{ipttpxrg|prlnmtnlqqcrxnpuomnuonkiodqqcpjugepnchlqrqkhmkepplgadm{{mkliklqjnnstnlkrplrqznmnotdmfeopjjupvjmoyl~j}rgfkmooopkfpkjkqtisgqdgsqolplnimlpnnjgmrhompqrsonqkjnmnj~gqlpiorkbmmhpslnwqlqhlmngnkkolkjllmjonokmom|bqnom`msyopgqkujjktrrksklojpmlnpqjvpnhqnhsnomglomntrpnlmmqjnnnuiknpnktmttoorjjsrrqnoqpxpqklfinoqoynhooqpjwmmpsfkvrukuqnpnpgnsnvrlgvkkvjospolkswqkksjrj~mbrjlrgtqumsolllmolguhlkwponnrqkuokqfskpokjmid{ih}nhhtfplksvxtojwl|qlojwlqmuqmkirmjrsoqkprmnkjklnqtrokilwtpkkikrgiosoogpnqjjpmsngrlklphqwvnrmnrijrjkmkilmkmljmmmkrnptljklriqitiosooqslmmromqmo}mgqmplqsp}jnshjognulnm[lonopfmphnoqriopoiimtnnoqpnnooinnggormlkflhwmpmgkpnmnqqnierpfmpmlcmqpnoponmiqslcjijhfnnpnqsloppnrlnlvpqnnsmvosijnojqognmmolqtnmrjkqootklnorllriolotmqlnqhnrvlmkmumlmutipyxnppmokksnhlonhphlllphzoofmmownpmfom[hnlnpolljnr`llnln`uyorrmomnvkrqdsmntnojnltkooqksqw{lpnmndsdjnirnodimnrklunqnoummmroksonmhqmsmonXspnmooofmao_kjwnsjaogqmnpoajl^ppqncllnmknolmmfjinqntkqpnpkn]ocnlokknnpkifmqlqnommkoqmlpqkrnljnkkmolntloilqmpptoopilpsopjlnjjpqmmmnpjimnpilizjkoqhoslrlirmnqkhlmkqrnmqlkoipujmnqndfrumpmqmnmop~p\woomlhllnojookloukiosrmmmmrhnlrppjkpokniwfvnnrkknirpuknonpnqqkn`ulmpososqin~fnoonqlooonrsosnl{inqmiknpmnrlohqenslpnklillovpnnmpmrmnhnmliklmqjnnppmjuormnwpmdmkrpfukopjimmpmmsgnppgnslrklnoqmitminmomippmglnkgoiikilksgpspmqmmoomdprqjtntqnmmovomlnpjkskspqlpenkmvlrkunwmhlqhkpkntgfoorpqkoknmdmhoqmiogmlsnplnkmppnnoimprujsqhoiltkkmqljpplqmqnlmfrmmkgmovpnqngokkjqgmlmmjmsnljnlosmlkosekpklmrommrtrmmqnnijsqjsnposgobppnpmhojspqjcnhpniunigjoeblrie[opnjopmqpreqi\lleoiotgjxmnspoipikkcqplknhoopomontnskinihprgnlopapulsomnrkknnoikhtfpbzgprlrphvnmoqkgqspsqatlfpgnoqTdnriymorogjkxhngqkqdneitjlnrq{llmmocknkgrypufosmwjrqmomfvhtqqqlmhmwmrysumpjgsgpildmupognkllgoomkqjqkpltrqtitmk^mqnn_oVjbgmnoncglkmqjoqoommnnomkmnnnwmnknpllnmplpovnmdnonmjZunYmip}nrnennmplnpnspnxkriopskrmh`mlnnnkmsnmo{tmnnlrolmoqomuoopooqmoooxkpjlplamsimmmmm}hyonmnukxonomookqmprnmsoioorniospeoomocrjltomjnljooysplmtcomkjopqpnichcrlqllqnnmmsnnmopnolomolnnnoknplnnibonsjonnsnirkvlpqholspjhheeqfpnnqspoolmpoglmtomlqllnwlprkliinqpsrjnlnomouorotoinlsjlohnlnsomirmlmkkkgmqfnnomqvpgnkniqkknvmnqopmkronppognslepkmoglphoujskpoitmmoqgontpnlkiovhlsrsorijhkoqlprjqrlkzoqmehmjpmiqjnmmjumtninsqupljnlqllnutimshmzlsfnioorpqoofkliqslqnlshpqnonmhmqqv`}npkiypiouolrmroohehopmopmtmtpiqdurmptntlqespnqZqidnmkmm[hjrnqilomhhgqpiufjppklmmlmqjVjyjcntrpnjywsorlspqspmojsllmmpsropopqwkepimgeipofmponqkdepghvjo]jphhmuqqmmsvnlpmhrmq{rrmmnemjlibphrlsgoxoppjwrkkwmq_jpkvpeomonskmmpqhmr|mnnhnlutovtkrkplrona{konjlpekip`votkoinbfuljpmpn{njpophnwnlomorpnvvtpdoqpo\swuljolliotqonmqfnjkoujijmqishulpvkplsjkkktbmypqivhkvmjpjslklnlqrolshfkljolkwjdmckmljslklsootmlnopjnnmnimtkcnap{m{qnjsicesmnokonwmjmpm\kzm}hljknrqqtivnkwg\mroohomigoomgltrkmgtmjlmrloloqniloqplsopolmqotqmnkbltqfmpltioomvlmllkvnsknnjjloipnkryohiqnzittjooqotivoppjnmchlptnrqkumtiolmpommhlqjmrk}jplpsklijnwxmolqnikqskigxjpppojrojeumupsmhpnppjhqowkommrronnmlppaptqrkomhpgiltworpskfihlpkknmqkorqnnjknkgnmkknvlynjunnnjuirnklkmptkmeopokooopyrlpkgnspomloliprmqlolmlskpoomjknhkorumgoioqiptjckcnsjgirrstmflvgnogueljrkkqsol{ebfomakfskijknopcnp~ihrtgffelpmjlrgiijqlp~morolepdcnymtjuimnt^pgntkrtnonlqlpliojvuopncloifqdpoqmppoknqobpemimrjggnkqrdu}tfjljrkqefvplrlmeoamqjrllprrnlqtkkrfnfmiqjlgi_kipzrwqkqjpjrsnnqpjoqqnkxipqnkqjfpekqkjsoaqfokujlxopkqxifrklqknnlonjmjnspgtmpmmoiumolhiknpnqlvqqrloepinkjfqmwliolnornenimmuommkmmnjngjoopppqfqlorqrriqmjsotlnkvmjq_oizmkqmmjqmunhsnmsqoqqovojmsolpolnjonpsikneklpshmmjopjknhmahgnmqnonlllqdnkkkjpmncrppmqo{otwnqskponmikfnoklnlkqrkl`pimnkkjnnnmsmmhljolqmyqtrrapqkgwiopqltm{uhnm{simqolnflidllmjulnjkinmvlrjokqowqrgskynrnphrvmqlejjrmhovonppvlhjhlmnnntokhknkogmnpjglisvokmgouplyjodhlnljmsmpllsxskmvonqqm{nmkoolpgnvmqnqmplnmmkmoojppknoomjmwnkhtkmujnpon_opmqjgnnnpomsnpmmojpotgtnmukymijmpntlnmnsnmoqkmlllmmqqnjmuouthnngrowkljhmqklmsrnpprerropnponkpelypnknoinrqrksjxbujlqkvosrmgmlolvnnnjukspmjplqrjflkhpklwlornuodaqxswcisooopglhoolkqmkihthmokpjegmnupjlrjomorokqijooolhnnjpkgntlohnqjkhqntmnivyilbvjqjdnrklcrqhrojokon_nqjoj{iyorozptomprkqto}sstqpnenmgejlnisktmwunmlommknlrkknrlnormmfgmmrkpgommeqorolonehnkmkmnoomhnshrmnqpqmjgbnrqnmnnompipminnormqmsmtormpsmpkplnhmlolkkefgpmnjponhnvurqnnonqhoilknnqmpnlgponthlpiimghnmkuollmorklpjnilpmfomjkoijmjtjhzopmnkrprlkmqrprrkklmpmojkqsjnrkmzknofpinmjhsomlioqkmmoqmxnsrojfiqfhmnimllgkkojkmwpognlloocojmcooneopliooophlnmxqpcmnmppnnkonTjphqklomqnpmljqnptmnmnmojmnoknqwmrrplsmrkjkjunlnppkmmjlokqqkgpomopkmurpluqpp`mmmmqoplnwoslnpmnlxnqom~kmomnqolnpmploqmqsrnnnookwtumoonyonl`pommohllnqeloonhloiwnolnjiekrpmlvononoqoqomnlnknlnnoXrqrnkmlknueqmrjllnrlokpbplpfqjfqqvhhooqumqvpujqglgoflmvgoukneqkmpskrpyorjjrgnkrdiknjktq`lmmininnmjqjerenoumkndljklo|hqgqltqrjtli|kjmvkrjrkkohjvosomhffpqlmlklipelnoglqptmgsmquqrqrsiiprthvhdafnpoxhfsmhgdlulzlpymfboigtijophkkknujmdnqpqqelwmhrnpcnrdllmqkirpmmkovqwmruotultqqkmqqmpnlmnqljplyloncjlovnqrnvpqlpoolopinnjyhwsplpnpvorqmmlhillnqnpojohmnijkqomtnnoohorqupqnnlokkejinfxwhofuRjlirshbmthknjdrmmsklmlpqu\skplllpornknplnkoqmipwljpnfmmooqkkjqrjmfjmkmnnwonrjuumnniipiwpppl]jononrlpioronmpqlnnkoshqntknuslmnqmkktrplfnkqpqlmmotminoltmjr|pkypomlktmmoeomrnlmspmkkmhloosmpiqptrsnmiuojlllpnjsrnpompppopkhnmjmqprmknkokolpjflkqnjlnmjojlnmrqnljpjmmjoiesrrnnolpjnnohkmmpmhlnloopnlortomknlnnnmsslolpknomgmujpkxompnomjolkumllkmhllmumlijnnooqmqmmrkfojoiqrknoqpnnzoqnpmlmtqjotnilnlonnpqunqormjpnrjkkgnrmjkrsnolsqpojolqomklwsllmrkmnwmkuolmqnloqnjnlkhojiokqtqlm^nhmrltqlifikmonomfoobnhpijkvdnmplooorlk{onjpoxopmshmpmtqkj^shprlomimmnorojlmsjnnfoslmnnrornoqnnnuhstnkom}nomopoviqmkjpyptlfpmlpmqfvmdjmmondmmmmnmnkgogbrVmljposnkqmonjokwimmnoqltromqoulnsfuolrnoqncmdlhlnok~pnuolqniqjoltjlfiuolnfqlkoknnhjqrnhaojnpmuqaktoekikonoinfndoqmmmmlinojnmsbglghoqpmlnkmozoglqknpsskkrppqexnmdqmjjnmoskhmynyjomohlnjsikpniimmkrmzklnjkukhhruhoonqsnumnlpiuoqmmn`koqmkqpkukllltgjnitjqpkgo|llnjrmhkpkmmpinoyqnjkkkmizwnrqgomiwnsolhcoomtjj~okqeqqonoqpqjsqoooqsnmjnmnfnpnmlnjrhmptistkjrbhoubnlgqtpoomgqqefomnlmmtprhlqcu~npgirugnqnloprjpljrmjmjkmgrtplrmlgnlqpmwquqhnclrmkokhnxojmnomtophtlnjntmykkinqdeyhkkfquijqpsmmklouprtonloprspfrlhkjoilspqfukpnps\pwiqnnnmqmsnhmlqnrgqtrmupkrnmqxpqislopomqqoqjrosnlnlnkojiotookipojomm`lnmllquosokjmpllmsnlqfm}jliplihpljmhqgknfjjkompokopkmpqurgqlmllqrnlkqkvp]koifqkpplskvlrejpjdkbinmjoqvmsnpnoijgorlbekumnmkljnjtllokgq^omlnjolmrslndnn`qpklqzsimoovlopzlxcmrnkqoklmrqnljqynwokimoolmproovkkilgqonotnloioqqnstmskonfjirrlykmfoo]fnlmxhmmnloopqnprkjlmhbnxmpmonrlmnlqxmkpomqrsmsckrn[oqp`ponolppmmpoqosjlokmfjmtrnmojmnilymolnotn]pnlnmooZknrnhnmrmupln{mnljlrjopnmligspnvqwljlosnsmopmrqmib]msonlmtsgllhqrofobscsmoqtimlqnnporjollnpmqlkdssrosiqmmpohndoomoommrlpnnpqtojnlno^mjomurpkolmfssnlokrsqmmjotqlompinonjqnmnpoqmqnomllojlnnvqjkljifgmoqpklpnlmhkmukloppqimmojopkpshmplkmngpkrorprnnoqhobptooplntqlkkxmmltknjmlqtlhkkspjpmluomvmmkmjqmlmjlnmlinhlnirnlpmogsigkflrkmnwlmqpnolnvlmdiokjj}njqnmkkqmolntsmwjnnmniormolojplipomltqnlopjmlnpkknpprgeqpoomnqnqxpokoflmppkpkilmopphlnmsphnnnqnotnolncjmrnzjrjqjimylinnntlnuliplmlpnqprdnsnlqv]glprqnkpeoqq_mojqsmojltmlpqeoopxjtlnoepvjnmqhqkimmmnktfpqonnkk[qmpoqmlonpmjmsdlkonop^nfpjlokowtloukmmlxhnqjtnnlnsnmmmmnlmojpp~spqpolokrliosnmommrjnmxjeqljprpmkkjolkpyfqyqtnetnmnujslpmqqouqpowmnmm}tomokpdomjmlsihmtdtjnoicnqwobjmljtlqlsukfiqnonmomfmqlonnlqlrhrlpqnmjypfUnnnqmdlqqpjtnltoqp^okeqkkokhmqmnlcjpplnljqdrnoikntqmohpnslrbqlnjpqpluqslxgnmn_ospiofnopmoenmsjprqrdmodpjlpnruwmtqjrrlkrqvloodnivonkpppefjrmipmllqjonlonrmnfljssnmldkqnicphphniilomkowrkngqqropoponpknnvhkpqlxpm`lnsknjpnholonnqjlojprl_nwelokhncrsounmkmhnlnj]qnkklykloojtmwnrjoloi}kpxlgtmmnnl_nkhlnphuwkmll_pjmssmnnooqpnlq\upmnpnnrifpvroopgrwtblnrjp~qofpnnpqqnmsmqnqakppvmoohkjtopnrqnmnoqopdmmnyxrsnsnwloghbmlpngiojoroskomquinjmonlnbmpnkqnmptjonkfkclrplmnonolumnislumnkrsrpdnmmpnllnbpmomqlnqemriojljsuyxnonpqnpnijsznommmtlrnrlkmvrojwmokpknlmjkllnrngmkklmlgkhonulsnxnnsmpnppoopnqewmmnrmmktnkopaqnnunpjoqqqjmnZwnomqumnqmnpnkq`dlsmxknilnjnlmkpnokmtnpnnxjrkojdmovheqoumjjlhnlglpokoanmlrdnllbnmmimpnpmnmo]zjtoomilnpmnmj`nqvmrpoolg|nnjjnqjdnnrlmlnnmmjanraktjimnztmpqkqokbnupmplnpowkhlrmqlffpjr_noonnopmupkvuocimpllnlvqonnpynsknrmnnnkotlkptvnomrokkptpemqkmjphr`lnookdmmwsnpoh`mooolmmkmebvjvpcpntlkprfnloorlponoo\qgnlmmoloogvqqpmhokklrnotevnnqqdxmfyippmlkbnegnkomtmnpohimijhwlfpipufdjhmquoqmmokpkjqqlonproomigkogmplpxloloilpmwitmjksgmqjtjlkrltkhjhnoomjelhnoolpos{vjprhkmmmopivnlkmn_jlkknnkjlinulnsulhnuulonjnjmgnqjtohompohktlkcpjvomrqnlnlcoofrinopekoqoqkkrqmmmpxmfloqokqqfolpiqjmnnkimntngqiimohoqoroimwiinqmqljqlimimloeqjpmsmnlnnjomuhokpmuntysqjmgmdnlk|pmepmnoqllptmw]nt{lij]mkunjmlfjifqujlsopnormqnn|josbnlrmnlldqonkhmnlkjlnosrjqmqpokrjocqlmoptipkltujonnondrtpyppyn~onpjqnhp{nirzmqpmqsmkupqulyoakpwlqblqomlmjpmnmllmnnokm[woqmok`no`fnlqkfdfmpmqpnpl|puigjkooilpohnirpbnonknmogpsrmtmiqsqknonnknv}on|kitohnqkjnmnlopnnjktnpookgosulnpokpqz]omlrmyooos]rimnonbmnsppkfpmkuilqqmnpekljljennnlokmooopqpmksmhon]rgorpwjlkpjchlrjppgptrmnnqkoqlqkmnlssmkmlorohijrrlprlmqokykomqllongmsopknpolmkpnqsnmmlnpuqtnomoqmhnukejpvlijngsfnmklhflkxsmvmnondp`qkvnimrrhpknomniku|nklbonpojnsmsmmulmgpkpkfqjinhqtpkrotqjshriolkzpmulZgunocawmjsnmuehqpqhtnpmintghmqcnkoqikjldpnjkwsgfjtvnlrgqzevqnlhngmjqnnnmoxfnkhtnlmp|klihonqq|iqspthfeopicjjnpoqlnjmmhhqdmklmlkqmrronwuqlhgionkqnzejkqg\orhntjhnnbsnjornqnimjlglpoophmolrptplmpnppqoirkrisjdkoasfqltqcnnpgloulolpomokqoowklvkswnonxokmmnmn~qoojprhroppplrnwiknthomlnktmeknloroekomooqjwypodswklkojmnolpmnojng~mnnonlntiofpmamyn{qkumnmivjpfmkptkmnolkpmjrijkgVrnrlntlojosmjpqpkosomqnbhjirnsprot|omomdcpqnntqmeipoki~npmddptlnpojpmhnrnmlnnlqsqp{monpproseptloialpiolpnpokkmjpojtopmrsmlqoqnjlnpptknlfsokgkrlqkqmrokhqmxmpooowjpomkqoimonlbtfmnqrpkujmsmonklomkrtlompcnddpsmilpwmqgnkmkmnqupnommmjmojtrktlhkmkrponokjrasnwipnllqlpp|lpmjnoznqqoyjpopmiqkmljkslnrmmlolnnunjrixlnnmhjnjjlmomklmpooknmsjlnuhnfnlnqmpmkkljommrmumklqcpnkmnnqpnprenmoromhmsippcjquhrplknlmkfomonrllonbmnonnnolgpnnlomrolplcnnknkmmnkimpqeqflnwnqntpn{kmopmfnlpoqcmrpntkvgzmrmpmpptjn{mmrrmrok`sllolyopuomppenxhoropqokyppsojnpmmxnlzmqmrsnppmnponybhpqoqmkoslfmhmplommrnmwpmp{qlmnppomqrjntqlpnmolnlonlwrnmtp_mkmjngmspsnomnqmmfrlopqnmlnuspjxpptx^tmnnqmnorojyqjnnmklqopolopepmrbmnyrpmmpdnjrfnhomtopme`hnomlurjpqjppntnmpmlkwvmmorolorknmqompckqpsjlhiljki^kojsqqorrkomnjnnmflpminonllqnnmlnpkomookq_linzltnpvrcpnppvfnjnkqtlkpqugnomhrplxomnhmrnnhljndplpllmmoklknrsrlnkipmjlnpjnkojmlrkrmzmonlnnnquptkrmiijpZhqgmopnntnimlkooomlopkqmmmfnloorqpompnkqnomqjopponmrmm_rqlmovkqnospnmlqjnrolioipnonoowlpwknnoloemrinpgsvksoqmonkmmqrlorqovtltdomrnnoqmqoooqnmolnknnmjlftnlnlpnkhropoonumrjqkoguopriqzdkrepfonoootqpmlhnrolpmhkpnmtioskqplnvqknompsnkrlnmqmomhhimrnrnpzsoemumujqvkslnvqroohodsmlllorlhsnoqopplsifqmkpmjohjlXsloltonknoskhopnqqoomrolsp^jlglqoqwpnqqi{kmoqsnwvomlehleokuonoqliksiojnooihtqnzonjooulorxntrjilzplsqrnlpseomhrrnpunrrkmftomlljpqhlsrknmoniljkrpomnnlpk`kgjoo[nmnmoomkloqoklnkunkhmj|p]^oyounomrinimrnoqknmurftnelmiqkrmonnompxjxhbiqmhqmoljjjtmohsjoujjfnrap{hmsnerkimntpksugooqnqp`qmcmnomhvzokmxcqpnqnkxuopdxkdnalgtmmnqkmfke~hnplkenjirkimohajhqpl{nlqomopuonnrsolmprmrulrpjnqlopqlqpmmsnpelnonptVqnllloot\nnglgq]l{nnlqlknjopdlrmfqibniqrxmrqpohnlpqellopr_lkhonqonoljlhkconkoouq^liiljsumjwnpjjkerdmdmpmysokgdqnnovhlmmjkXkpqo`lmhiiprlgqtqljkmemndoblckro{moathlt`tmrUmlqmutqnzlllfilnrpompgnlpopnbidnqprjoolstViyZrkvlmsjslmmn_prsrrmpqkklpmmmfnopnbl|l_phfjqujmykll_lpgwmproqknklnngrmioolgulnkmmjrnooohqvphfrrppmlkilrxprqnvorlqromsleimiqipkornhoxjrmgoltakmsinpgmknljpqpplmgmonmp_jrkphlmskighfmmprnshlhpgfpqmlmktjkijnknllooqmknqtinnhpgqptprhsknprropmnnkqjwmonooqimpjmhtpnooplrqnoljnhloivnmlommnqqkqmomonjgmonymvuphiscqumapjk`ehmlof{olsmumzovunpuposrzth`kwgqppgvlmqkkkjl}kknnljgrfcqktguoltmrlromljzqvkjnnl`spspceo\ezuiflloomlonhilmopqworlrhmkm^npojlmlslsnhzomimtqgotfsip|nllkgonsppirotononjorgsqhnihqonmqpvgdimfnluqojojkuhwvlmtmn]lixkjrsuiujsnpqkiegqpotbrrtjrhIqaalksmlqokntjnm^nqkqsnlnotmnsznpopkoolminrchonon_pabqm`ovljonlhooqommnooomuppnlirncoirlqpmlnofnfh}tkkklWrqoomqmimsmpenqsjkqmplonnkplkspolqhicnntnsmjoojpmokroslrqwgpnqplntuuoxnln[ijpgonnhnijqlnmqntkoplpopmqljqhVol_qnropopjnimnmioenpmrnulonlsnnwvrnltponopkqpfgmmnrdmipsmnnumnlpppmjcnknpklcqmmnrpmmmrrk]nrhqhxvggmlnonrpppnkhjknpnnoqnjlmgdmrm~monmqnmiwlon{qlmrkjokosojnmtonvSkpwmmhmiklmocopjkosnmozrpoyonmmppokmolnnpnkpq~jmooposloo`uklpgngnmnnqqlongpnqollnqqoqqmdumnoippmklknnomkmopjonomnmnxbgqnjoppngisnntn]skjoroiijolvnqlkwmnn|njlyjopquoinjdqdnqhmmsklnomxmesnkrtzmgjimrnnmtnnbunjmpljohnolocmguhvhrnqoqpmqm_rtunnkmeoqnqimplriqsrlogpmjmicmnpnnejnlnlkooltmnmtkmnphkmlirnmiimvjkoouulcgiolkkmqoo_njknplt{ltpnqopqzpokmmonmirstenjpjncmpkplnlnmpmjimonrhj{omsslpzmxmnpqomnorvnhnsomvqqkq`pnulknlokmkuhonsqonnqklpololnrqmdpmgmwvsnpgmvnng{qnriglpolpljledludlqqdhoronponnmuo^snlqkomrmnjumrmpjtgoiolmopwdlmmkmbnlpmmphcyknlpjlttoolknklprsnmsmnmlnnnmtno}mrUpplqnwlmko`diismrnehmmcnnnmdtbjolsivrprrorlyolojriq}nlnk`pmrlonknohmpnsompnmnfmopomnmjrnkominwmonkjoilnmmn}kn{nmmlpqqflpusimrqymjjkuhkomlnmnsnnnoksonhpognnqrnrgpjblplmnpnobkko[norqjfklkmpnmqeoop{kgmppmrjomqmknhnjeqklmksonimjlrkj|lnlkmsqqmkhhmmksupnlrocjlho]ivotooplkxoitklnlqlqtpkjmsllrmtkplpokmklplonmpmsmnmmnpnkyqiqmlopginnimvtlunslomoooktnlnknnoqollolonnnhmmkwmwqropmkomoto[mkplwqt~nw~pljumjsoqneqcknnmolumczohanojpjocmlqnojokrmpkmhntklnrhrmsmtkotjnzomjkuoloqqodnlnployilodpnknmoeomnpmmtmnoqconlrlmwmuqjknimfmnihnnnljiljoopnqwwopwoqnmrl]jctomgmmmomtphpgopfliuoooioomjqmjmoorcosoo{olbjjmlmoopnnookeqnkyomllmrpjrionuwlionomkoqmmqqdqnpnqijvlkupuksnpnponlkrrnolpovpqloelljliwqplpsoo}pgqikmlqrspnlnnkmigskm~no^oneqhanqpbocinapqmvmcqniptmknrvlmommptqkluspnnqpqjnvmrhjslmpfikmlvmqpjndpmpnaemmymkpntridijxpljowjntpqolnpolmklmndmetnhmkpounnpmnohrojpummksiomolhukrqslxprrjkummgpoiprogjqmqnmyogokmjmkrnqsbrkpqoofmjmjmnqlpkmvmklnmminlrnqofrptkrkpsgmpfiknshwjmqbiloonmlrqhlmvlpnvpkfhpskylsqnsoojomjokkmpoqlolhqnrpmlkijjfojpioiimnmlqqnskmfqenojlmqrkplnksjmrnmprnmjnligsilysnjnomspnkppqvlsskmmmonokoqjelijoplmptlglsnlqixsrotlokjsponqnppnlnmogkllpomotplltgkpsqlloobliontjpnjklrmnmrmnpponlmrmlmmsevqklqkonolvqkmenkkunhmppjhhmojjqmpqlknphouvonotqnmnrnnpossmnlkmmknqnorpvimmmnmmklqqrokuujl|lmvnujfnstomhomnjjinloojpnnjqonljqopnrjooomqphnfnknqkrmlpmonbpplupupponsonmkyuqkvqpmlsnmtmollrulfrummkmosnukmnzmlmllkiqoploopppookprjoqlmlnmlnmjhlnorplnokmrwnjprojljojjlmqqllpqtkrutpsmlmmrqompnlmmnsvononnlmqmmlmllmnpjtmorqmmnnrmlknnpmqnolmntnoknmqiomnjmonkmognuomllmmqlmjmoqppsoqonoqmnppjswiqrqokmotmmmmrnqpolookkpnqjprmqprmoooyomoqiiosnumukpnkmglokhnmrunnm]kkplkpknhjpwrqqmnqnlmkuzofmllpjumulnymdnomtmnklbmloknpwmmxkmqkikchwlopnncl`qttmkmmfjmjnpnmnnllllhkjlsmhtjjmkohpl]mmohhdkmnoxnbjklmmolnlsqlmq^nmnopiashnhrmgkkghi`lnlloiosppkooqrnpcmlqhvteotm|nknuomoosmpllkmllqplvlqpjhmmoompkroupkiokhdnmnponajonmaloponpipmlintlooolqjpmnmlinjnntnk|onnowvpqlnjhltilknekgknokmnimtfoinildrmqlnopplnlfpbinolnvimlrfnmteqmidnnbnnomlqnqlsnmnofonmiollnonqnlmpeolnonnqjml]kmpoqnmhdno}orlozjonrinonfmlqptjkolsmounkrmnojjlxqnknmtnoknqqonoqnlkmnltyhsmmnklmjkdpqqqvoqoltnpelemvmelerolhfvqnlvkxqlnjnqpnllvlprnshogrlqnmoqknwikrsprjsljpsnlposnjqimojtpqpjcnmlljnlnxjnisfqlnmmersqnigdwopoqhqojpmjiqlpmrYmqknsmnqqsklluoonmnokmhijnjpilwopmokumjbsnkrnlptjmqqpknpohlokvqqroktpknfkcjmpnmlookmwoonimlmloo{lpfkmjpmlpkmksonompeppaqnmmqpngjdpjookjujjwskpsliilrkj`hilrmopktqpnqjmmnvjhnnfhlghrrptvoimnjnmjlnkgfmkjokukmpjniklppsjktfmoinlpppmmmjignhsykjlhjnjmjopllmlrprpxpmqjlmpnkqsfjmmilpktooesjnsnlmkkprqokpqqhqlkqnlasnshkomtnihlvjiofqmoksoonzpigprlrlplhwqkfspqljmakmpnkproml^klihrplmkklksmnvosollkskienkoitmkmVoojjoqpdysjoinpoukydnmpduolhwqoqanopnjmlgbqehlogmbnnioinfiimuhoqglnnplqkhmkgrkvrqllpxm`djmvbgmsurhopoplxj`klkimXhmSsipnhialllonlordklzpi_p^oWjtmpsxpmjomkrmrrikwn]qroclnmgmmrmqgjqfpklq{fmqrjpjstnpnrnnjp\gksorapoqpoqa_cqhooxltkon|rokoqnn{odlrsfelnjnrimgrNtninmololhounjntnkmjhielnnmrfljjkpporskholqmninpnnmulXjmjmlnjrppqnohjrqrojegxjtosiqtr`lpmoqjknnipojlwlnvlrqmpnoqoojpolqkmknrseopgipwhksotl{omjqiskklhlkkljllohrpnmmnsrqqokmnhpminlegomnipenlqkcrgevkpmnobmejnpmgmbnkopnpmfnikjkpkjgkrltpqkpnqmmmwlkkm|nnjqurqropiohppmnjiqoinklpnolqloknjlqldomnjcoqodptqinlqhmnkonmljpnlrorqnsesozwonmjpnngnbnmpjkmmtljnonooqjmmrnpt|okunk{ljqlounjjnopprxmopmtsanmnolonsnylkosoomnqopppjniunhnondphonmolihlnlllpngnolmmrkhghs|fnnoinvmnjrkopmskjpsnnnxblmmilhnqgedpopojppcl[nfonqnpvppmxoopknonllhkmglloillwqkmonooknoqqlmkmtmqbmmpnomgoqkfdnokrmqmnnl~prbljplpnxooynjnmpkosqzmkhlkwmlolmnllrnnkomm}nljoqonqkgoqmqjopktrwkn^ngmamojnlnqmtvnhojhnommokmnlmqlnjo}n{pxsokmkljnjnpmnbnmvlnnlxikqgnloalpmknqlknjpnjmpjmknfelpogneonascppmi`pqrkrqhjtjlqmlbqnwwqplqjmrmYmtolngpmpqrknkkjqnnsiknhikjrrmkirnmpkjgsmqknmlqicjjnnjpphpflpimtmrfpplmjrfhjhk{fnzjkrnirsmtmnpllcmnsvlhj~knqmejnljqhsqolqjiusxsournymvgkgppirommqfskrhpcimijhkrimfsmbnkoigrkmsjioirkiujnkmnonolmnncbsqapsmlyqnoriqk~skojkskognqnonqro^pmipp`sniuemnuqgqoprynsoqtroojlipnkpkiflhqmfrqwkl`ohrehloppvmjkxopfywninrlrjmlirvnoihgnokmqrpwypskenvspropthoummfulmloml`nmkpkjmgmjolnoqrumfpmtodpgsqllcmpoyfkfrqipamlnlpthpkmqsocnlsgvopoiqfn}iimijksooklmilmoynwrlpqqqkhlqmp{rtjmhqsnikrifkhlelnpnvikqilnsfmjxhksmmlpbrjouvksokoeqnnnsnjqin`rqknnkmjhjunnhkvlkiqkqwmqrlgqhnjroznlkjloolpkknmfmpn|igjrpkrikqsuo~n]ogjmplktnqmpojlglomorgrrwjinofupolqkuoktptmpmnsvghkljonlmqgixlgsmntmtqjfnomxmnlkhjlgcvmknnsqp\pnloeporfmqlhxnshjcsoskndqnopcldpmhjltqoplmr^oin`soepffkqmsqkrllpgqknnrrqomsqoqqqmlhnmkoxnlnromhnnlpnmllnpeqolnj_sc[nilmjmhnfiermrm~mpqjnmipp}nvlgltpwohponpl\orjtspnpnjnnoslolkpgjkunlypnorqnmlpsoconnnnmovqmofmlljmlekmormuirnpc|ommqnnnymohnhonotkilnnfrtjmujmqnicnlqnopkjqorlYjolonmnrtpqolpnuhlonnpgewkjvoonplqiomsnlhncmZlrznhmonmgjlncykomqgsufqnnknglkrjtnkfhqppllpuninmtojgpqojrllmkqrmi_dqljlnzqppmsnrvrhprjplplljrqpgpqioqkjseehhvmmjok^lrnnqrsjipm\motpsjjgrosrmulpqpnnmjmounnjiggpdmplpmlglvnmmqokkljwmlqbpiilq{mjphejnpmfpfuormsiqoonqli\klnloopoglrsmnqpkjsdlpnisopjorjokoqhmxmjlykgvqnsqnhkkeqippp_nliromlqprjjenopfqrkhoonpiogrjopjphouqmnommnqvoolmochsnogsruznkgklppwtnrumnlnitmsmriitk|ekkkhj_ijmnmnmjmmoqeprltkoindjonlmmjnmmsmlglmbmhpqtrjnojgntrspojonlnmfqjen_qlimjzpmujoiooosgkujjkpnlpmonljlifkjumk~mikmarrhqkmmfifkolioumjkhpokkqnmdprlklzyqglvnpowplmhjqnpsnknwhmdorlqorommresolrrroqmlrsmplunqmgnmnlvnmommpqmrin`unbrqmqjoppmppu{ooilpmigmoponmoirposxnlYmmwnjfmpmfnhollkonpptqnhlfpcrmrjookqntmnmhpklnpqoodjobhmojocmfjmjljkskllsqqqmqxmlfnukmgogkoqjnmmnrqtmkopplkemmovpnopsocppunpmsptqonmqmjljdlljninmogvemrlnlqkkdrmnejqknkrllilmoivolikpontoqjrpjqdopnojmligolmkmqsmj~omggtq{rnmqhkpmqmqpokmtrrnjnqotpgrohdtjfgpjnoorokkxmtmnnmllgyemmflqmfominimwlupmnmijilmsnlsesm^slmptllrfpoomnnvjsmolptemkjrnqkpmlscgkmdmlminlqqmknmisowsjnkvnrnupllnwjprrlpjcmmn_nnwrmrfqkfsnkuq{flnqplhpnknonlovnqoiljsnpjslkikhmfiviqntnvqqlronolqglninmnlqmjfhp{gmkmtlhkmqmpnpfhnln_upiihnpgsrmmh]upnfpiqlmnqjtkkkegpljnhlpkoqplkikroskpoplnospljnojujoijhnemgnpfkqgmmnonlvqpgkahjlnlnptosotoinpbqesnpxoknumjhpoenumvqokmocmhmhtkiviskjpnlfmhqumhqlojgn_tiourskiposs}omnsmloqnlsnhlkknqqmkhgkqxckewnc}egrkksnhmrknnomhihluhnkqjmofhjjguknmocdgtljiqcnxtixnqfqoplktwrnmwunhnomzpqunlqnnmskgmipknlushvowumjpzoujnquslikhyclrkdmZmsshnrnwlywqognletdhkrrke~pninhrpmgnkgjogmititlmmoinsiqsqlvlvojihlqplktklkhjwpzsuofqlookpjknwppomnoj|nnnmmjnirgvlqnohn}nqsummohmtuloullppnrnnlobmmsorkqpqlgunsqqorqjomhmlrbjwloqvlnoqjxmupkooquonrkgrmnnotnnppovrpomerlpsrkpntpnnnwjgiqxzopnwspysmjlsljlplnnlhs{noneqilnnsonklpqkpuopommnnktmkkmsooknmkmmqfiknqnirjkrpmuptthxqlooqmoruspkjmhlntspimtoktrnhtkokmymimimekhpsrmkqrtpoloonoplhhrmfpqmijtmrnsjeokrkgfmkpgnpmmhmpmrollmgprmpfnwienkpjrmionkrmmplqt]nojmlhohmsomnqltplqqsphomromlplnnnfknkmunrjkngp}oeiooolhqunhiqcprekqtppjsdlogfpjlmshsrgnlpjtpjpmlnplhnffllnrqrkmeiopnmkmpqknokrutwommnjntqlmmqpurpshoolhrprlxpnshohonjnlprmmopospjjpmlwrkkzplimpsgoiilqelpfnnnqnppmlislnmnjovvklohklfkronokimokoohhgwwplvkmuhfgnqrlopudptmrgnnsmnmcmkjnsrlmgoushinklmpokgglonioiihplnqlmjnitqquunqvuikrjigjljfnnwkmlqtuoqlmjhlvprwnksfkppqlljjnpikrlroqqpcilkbojrqpnilpppflmokpxnkoglp^zkmnqdrkoufrjktosornnsxlwk{pomiqpng`kqpsmwqrmlloimkogpurmgq`mjslkoqfieqesoeokjmnmoeolgWm`gvpmgrknirkhsyopoknmsiwidlwelsnlonkllklrgmgigsoqpkohjcpenn`ipcoflpnpnksgnrckoqmlhmsmrlonollmkfnhqmqrrhykhqigjjkqoallkpqvrsnalklshitmm`rqprlir^mkionohqrpocnqnsqlpincolkjmnolekjhwgnolqlsqqqlqmpnnjtjplojikooonnglirliqhyrmjoosmpuoqpnkonnnpgphnjmnpopjollomfzlntlpr{qfrmlemsjlgogmoikmzfupkrvmqnkqsoqpnjkmunllmmoplrmpomnnjrofliu}holripkj|ktpmmijegpiomng~ovgmotosfrmokomtjipnrmXqlocvoljnipkpinnjnkplqnloollnrliuloqnpqilkmmmnlvmxmwerjlmqqlnijhvqktmcvlsnljhqhung`hlkeulpts{mc^gvjqvrqgrfkhociyopkjrkrndoklhrrpnepszswodk|ipq|qrsqo{fmqrrcvosimoqskoo}mplprniqunjsnmeumkmokihonhlijmmlp`pknwjpioghnkvpiqnmlppjkmslulnojvkinntlurcllookoKqjeurqnoootjgoupxgomtoooeldoprwoqdpsujrinuexkkkkwmwkypqznnmopnelofonpxkqvdwpnlknnspmdulwruzhjmqplrfqslqrpsjrjlsksvmlloqsknqgoepoionqpmllumnplndksshpypenjtvrkjmm]vjvoj|q}hnkriinqjojmnopmopjmoktmmmmvnkluvoriqfomjltuflitmtjonpkmmoonqtjofmnknjppmnsltwhnnmumVqnljjtoqjnhtngooskgwnoshrnpqvhlnnuoptqhoopomikkpqohmsoatrmookbqmnimkprnlnkqnkloeqnq}njnoomonlmmksqmrsprp`dotXoinbnfpisnzjsmpnoomoonskr`kof`wlmpkmplloWkrpkkkm}ormqrlngvnji{rkvoplkiunklmmtnokjopmhirnsmrnunlknloompnukmstpnmoknlnvmypnanknoqmknpgpskn_rqooimnofhqpqeooivnoldrninnmojnonkrmoonlqqxpoooynp_jmqpkohrpjncnmwpcqiqgtnndthkkoqnhl`pkltlroqrsqqurcjopynojtokqmnopmhoknipkvpxoptknpkslnmophpplpmnmlnjpriomsimmisphuipqpnninrnlr\mukllrqqkpnnphqomortrjoqnjommpnnthlrolknlnlrupkhiplqlonllmpjlphholnjqoqlnqohmpglnmosqkoqtopqpmplljjqwlomlomkkknoxoqqpppnlknkoikppjmmnpmlxmspohnnqlXwnmmwksrknsnqnpkppsnnrlnomooroqokooPmluqpvmkZlyiovnkompnqniktooolnnnmk]liiotl_hmjplnon]mgogmnpikxnnonnpmqlnqpuqggmploolnppwnspoqnmqhkmlnkqhnilnnonmlnlsmklofmnpommnmonrlpomelqqpponqfoloxonlnwmomenkpmomoiwkljirlnqlppininlplljnnnpxvolnn|mlfllonqoonuncnjwuolvprsqplllrmfnntbdqlnqomjqvxpnooqmrljlrgqlkrkjolkjpnbwnmlmbnocuhjnlolgmnulpnaqmonjjvieqsqmrcgmnjkqymnnxbsmgdonsuofumjglsnmwqnmqnmleekmmjnmhhmrnrmprboofahjnmkqoounhlkdppsipqognnoommrpmombsinklmnmtkxkqljuqzmljmkasoqmvobqmsobkrmpnmrqlpthnhijmoqnottrgpmlkoqpgysnnogoompnorqonnjlmnrpqnppolnkqonqjcpjnldptdpksnrpelkkppm}okolpumoimktmsummhobooonmmiincl|ulhnqZprqnqklkqipl}ooZnpdmqronrbnnikgplqxyZmmlodkolnipkolrjjimnkrnlptnpktookgoioumpo}mnjrrdloumpmns|mlrlppnfsuopckhglokppzofonnphlmolim`ilspupmnnhmnmokeyrmqpquknlm^pnmpymoqsnnrlmmnnftnotolhmomolksoomqmlfrpuojwqumnqknprannijlmonnpm|npnoocoq\q_qdnllpoplglmplnqoppmknlkngqqoprlqgosgmpmmnoqpojqsmmmskvppkqrpgmnhonmmoqrnnpkmqomningfemfooplzhntprmknrwmptgrmpjrnpoooookhkpniqphnklnoolbpkmmolprnnnolpqnentnnhutqqooumqslcrohodovnqfllovjmjkmonhoopoxpnoloqjktrfpfmqrismlyihonenhnkfsqqvqtpotqolqicqlqonlnqhqqkqutljrqmnfugkplkilrhlsojoiftkmolspjmpirrikhmnqnpiunkrhlljmprnkqjmonlp|pnmfuhrqkklostpnqklmamprklippjpjpkmpjrkbpnhmpvnqxqmsmllgjthdoxsnpssotpmfppnmojtkmejonppnqnjufmmsmlonkpkvxqgqkpsqrgpsojliojqroerrnmvemmpnmlolglojhkkpemjnmvrixoploosowlommplqtolkkppqnnjlmjslqemylegfrxrjpqmtmdlieommqmmltomskksqtnnr|qpoqpgm|hoiqlilnhnsulpoknngouspphlllkqskirmnplkknrmkmmlmkuhmvefkqlvvmqklbtihmmhtpsomiphnmsjhriqpmlpjkniseknksjnmkfmlmplgkjsnqpgvgmen\osllhsosfvlssjncprnjpjmjmqmohohjijmninsonmgnesthhkiplekohkepokojrjgakqjmkjqr[hspnjowfzpgretlitkltljhlsxfrolmgttfkndpboeomgelvomgpqhdihnsqlknmtiospmfnqjljdomqknthttpjskolhmqinnlmjjnktnlomiinlhmimhoipviktgojhglmlqqjikijlmmlqqtnnimjnlmyoqnektli`mrnmp}oeorsmh\ronhgjtlgprjjnoghhklprpnpdpt_qvopprmgpthlqkqnqygnimmslpqcsonmtkqnlenjthsrlqqxmonnmojl[lxrqjloqipuyrotohrmquljljurqopnskoptfnshr`omikkiknrnriplrngidemftblssxkgiwpbg~vntjglsoloqpblpmolpmmoqnnwxlomojliamlnrkoonmqujlbjlsslnjrljopnekocskmonuiiluoa{mlotqoipiojrdojqoyin^slqiiqnoibfllpmoqnpgmoqitnjnsksilvmjjorfoidrsvqoooinrrplmqtjknlnrospqornoormwqnmmqlmnkqn^glmohdiqjjkoqroiilropgojpsrnqmcnlrpmosmromjojsogommnapnoqldrlkntuusioopinmjoirqqpomntjlopnsjhrmpoyqmslokhjgokmujjlwpjqtolkkkgmlorkllglkfkhogmjpprppqkihoppopmjvlllbtomdtfnhinmnf_rhjqpkovnstqkoslrmlmjkl{erqqgrmkjmeiomoobonqjjnlZnjojpnmrjjmjjpfotmgnjrmhmfookgjniumq[thnlmnvjmovitncprmouormljknmqlmksononlkklmqgigpslimnppsjrvpdjoiqinyqlphqnqkmqkqmflkopjpjsroqeotjpnlimimmpjqmrqkrdnkknqmemkpjilmgomplhmvlofoplipllhklninppdknnmkljpzojlikmolqrnmsfnuoonkhonsnmpjnjpmkjsipnjkvkpnnkfjmvmnnonmnltodnpnkplsmwnqnnlnlijzsplmlrmdknkprtoiglqifnkbpojmqqnonknknpqmnodnnpmnnjjsonymoonnimpqrljlnonojiqmollqimfmflupnsloroplslrojalotlmloshklrcpmsnkzlknopnolptnpnlmmcnpmiqowoopopnonjcpmunmpskqolqmnrnvknmunomiknoqlhmnffnyommrpoqollklnnlommffqo}pantnppoioislpmqpooonommmprlufnmnlpnoqnnksxmmleptlonkmlpjoppmzqtkrnentiornjmqmqnnmn}^qjndqmojnlpoknrqjslonp]mkqqmnrmlokjotnuqiolmmppfjlvaumrjmsoqnonlolixjr`pmooounmmnposlpmnkbplpgvdpnijsnndlrqnpkWpjwinrvzmmrodlum|mpcpmnksasimqlkknozplmjmkpmwsuljkghxpmvog~kjnmmuoomnrjplmdlcppofkrovmnkpposqZhqmqeosmrlvs}huqcttsomytpmkg~qrnpoxaogtgnojloqnqopoinxppqkrxllphp]duponblkgfyjnoslJsoikrprfogcmjfphfrmnomnjk}rUhldlpjtkohmjRqdifkm]qnkrqpfqrrkqzommmvlgpquxmlpmnnwkfrkolopmpxhnnhhogvnqnlnljoknpmvmluqm{xgvm`npmpqqlmpoeonooqoomnpjmmlnplmlnknnmpnmoimmmnikmfjmtrmlojijpmqpwlpjmkqlmowhnjmmmljrmpnZgllntnlkljmqnnnqlooojpllkppmikjostmonnkotlmqrppsnokolokolfnnl{mpnolooonrvhurqolnulpkqpzjglompqntnkfmoknkoqjokqknpnmlnoqolntlymjncpogmkuigoshim|q|mmo~inmqploqtimmrqkyrtcmjmipoknpqnhlmdgslxprkjlnp]ljsmgshqlnrokqpjpsmfjlpflcrmwkhninotlkqnmhshllpljsppfjommmjqqklrgrjomsqmifnmmkmkmndplmmopnmnmoqlwppmnnjnjpghqmmfnpnlonjinlerrpmrplpnmlhmskqcsomipioooqtqokfmnnntknkopkmnnpjmmkqookijjpovnimkvpforomnqlkuempspmilrmlrjkhopimpiomnmqldkopoqoommskxnpnokolpmnjkorjlhppnpnljthnwsprpohqmomnooknhqcmmmkkfqtoqqnpjsipscnnkpopmmmnppqlunnmkpnqdqnopmqmemqqmnpppklpkrnommqsnjfhlomktknunnqhwoknplnkwqmoohlnoxlnlnposlk{qnolkmqmqnslolmonnrrpmdjkklrlbmnpp_npnlnsomlpokilapltollpmjppspkimkdkrjkozpivquppfompojqqptulvcrqwmrjrnqnpeljpknslooomrrpmqoikcnjzropofzomkkfrvkdmlshmmjmjhoqkiohwnsnqgmoqmkfvsollmkrpnookpprprolmqppnotmrzdmfkvkoouqdoomnsijrprkotrujkqpn\kv{jostmjlunlxkimoksnrkllqlprqkjojoqoeqolmnqllrppmipqkwqnnooirrlgoppsmhjpmmgomilkhipk_qrqdqrneshuieglglirpokyighlmiheogjkmfoibqqnqnhlimoikinompkmnmkknpk{nlslitxmglurrqxkmmiqknmof{srnipzrjlnn~lutmirmyhrmpjmoqmnrlp`qulYrowvjhlkfjrkzlrnmpppenmlhqsqolnooqjqirsvjfomil|m[qq^litmonkko\kclljocjiyploqtjqxhwhmqljqlkseunlrpkqyt|shmogpkkimfnfk{xqpkzlloktkvovmsknzywmqoqlqkqa{oinkdnshljpmlrjxkpptrnmqgooopkqtonmsr}omutsrtgohqmhsxlinmwr{kmnjppXkylmnnoqsopznionhlohylmmmgomsponr}hovpppjlutkgmkmjiopkolnumnnmkqoimgpm|mmsllrq|oolppvjjstloskkknphslwmqottrsqllpolptoqgoilrjnpnssmkjpnokmjujmjqktmolq^njknkqrmrkhqdkomqnhkvthmoqorrmqgikqhlmmmmjhmqmnsnnqimymjnjrkokhlnuhbspkxltrmyploqqtjwpfilqpmrpkhmljnmkhnijjqrlgtpjromhnnnkmolnlpnfovonvmmnddprpoimqngnnlnrpmtoolktoknmloqlmrmnnfpnmmovmhncllknpmpojoomgmqmonvonotnllozmrjmkkonppkmiimplurlnmqkjmlkjptqqsmpmofpmproookZoqpppnqpnqjmukjhmlllohkmnnpynumkmnotodpinwoosdgpejoonmmmmcnwcn|_qosrlmonjomkmlesirpmin\nonpoooknmmnYotgmqflynnqroprgrsplnumhroinpkankemnplplvmlqoflponmoyrwo~kopnhfsnkrmrhjfinspopnronmmqqoollgonlqinnllppojpomlqknopmqpnennajhkonktqnqnpqkoowrhmmon\mlpnnmsoljpmonkqojhposcm}olmpomnknjuykzmjkrxajqkljnhnpmsknxpfkmoimnonb`jgfjnklzolpmlotvnkyonkpfnionmiilhunmjlqj`lprlobnmpgqqnjmlnql`ijohphijnjvnnonml{kklj_kknrmmkkto|omomzl{qvkmmtejotmnkmfroqppnmkologjpmplomspomosmonpmikiopo|ihksqnhqprhomotmguoomvkrqlnptiriojmlmikommnpooglonkhpnnklmjpkqpmqmmkmrnpnospanlpulooinnmlymnmpmoumjnktmnonjsmpmqpnjrlrmsunnmnmomnmkpmjpommhppdnkumnoloqnppqopoooknlomhpjpppnmqmhjnlnlmnyonlilqjonppmoemjqvpmmnknuokjrfkqmmplnkopjnprrkkqqphrnjnngptnpoomnmkoonbggjqhllmnnntojnmpmnmkliojjmmnpoqhpnmnlqrimpcinprqmknqsninoqqxmlgjspnvqsihoiondknllnqoblmpojrnnsmfjmrmrnqmhtlpnshkpqjsqmpuokqjsojoodtgjplisogmksonololtgniohgkhkjmrpwnsineqpsrohnfklnjonmmppltkqqmljgmsqnlmslsmojjqknpqmkppmkopwjhsimhtoryknnjkfonprhopnphljismorqslkmopqphoqorsnlknrjolmlsnmoumqnxmqqlqomppooplmmmlmsnoqmqpmonkooopvprgltoph[mlslnkvuponopmoonohikmlnopnlnmsjpomhnhrolqvsonfmoitnnkllpnmtlfnlmlkkntkpushksojomipfonrnmpejvmphkipclljqoqakolnnjkoqmmmtmopxvqnpromirkllnnjnplmnnnnrllqprhspqkmlorlrkpmnrpplmngqjmkgmkjvnpmojolkqqqhonngpklskpnskxzpobrnsmskokrinqonqolqmsnsusmjphipmjmnmhqnUrctnlsqo|oxnrupnjvhnmipnpntmmopporqjpnmknlp^rhlmmkpsfdfrlmenlphqoomqqqorosmmmpohqnimjjqlnnohpjidisstnnsaohphqfntuhrqomjpnopspqupjpuinnumfmp`jopnqnqkfpkausnxssslmrslnmmmzifemoovtquktosngmjnnnmsknkmknoppnq}kkoqljlmoxnrlkirmjptqnipnpmwkmjkjdgjfoysgjggqklnlzoe{kjmlnlmwmghglmidmorrlokorrlmorikmljlmkemnrkqokcmjljmkiqkpimjprnlptmgmnp|sjmgnhkripjjqrmgmnloolksrmhnkozkrqrliktpriooqkkprloopigtqtqmvjkoqpilpromhompjsmninclflflxionokmoomfiwkpnmrnqtoliimomkiqlklolqmmntnumynknksqnamnovonrhpihpomplrnihmejimhmmmprmkgopjrnilmmmopjwkvpliooqmsrkhkqswllmkwpmunqmvnimdhpjkmmfpkmuggqtlofnonjsmaqkpifmnpznsqiprmpjfrlwntlsomrkqkkmppfqrjivmfmo|ofomnmmwnitjippkoplngklpmt`mnknrphljglgrkonlemdrikjrrmpnkneminnjnkklkntnlqnlmnfjnoknkmklokojnlmpnonmprppnkmsikjqlkomznojpqnopsqqomvnnolqkpipnmhnip|morknndgrlrppnq{mjprtlpnwsjqkmqppmhrlljnlmqksprjnnokhnqptksmhonulcholosntooqpnmwnkonjqmmipvmokpkpnnmmpynqnmmsfnklrqpqpkoqhrsmlpfnnmboosrivmoionllmiumnttmpnmgnqnqtmnpmmpoonlnvnknjklenqjkqkmnmlgonmpmvqvpvqjulnpsnsjkqspluwosjmnhnloqnjpnqklkjnqnlhriipjlqemmulknjsoooluologjnhlktjqotqpnqymjmlniiqlfmilm}nqplmgqopgznnqskoekpmsrohimsponkshqrgjmmniomrvnljnnmjqykapnnrnpoqo|knrpnnudkiupqoonioqlnplimnkoonoqsqmktivponopqnpgqjqppnlmpmmspkioppsvknlpoqmqnpqolioqongsnlnqnpomloroppcknonkorpppnokinlpnnmmljnnonklklokmphooxojponnmimmmqlolrnpkomppsrppqq{hnjmoqoqdnhotqppmoimonmopprnpmkkooqjjlnpnlpoonpjonnlmtuqonnmrlmnlmkmoqqnlooqiulppoqlqqhoympfornkpskonruaonenlslzmmqolllmlpnouvorvoomonjmgmrnmomnkpppjngnnslqmojmoomrkoonlnvrouknlhlonqompmnnklonhorponnonnhmoprqpomlkugmqlqllsivosmompnoqqpneqnmmptpnknrmnsnopproprlmopmmniqepmnqrspiolnlqnmknlmtoeooonlolpmloqqkooqspooknkrrrurmoponrmqrnqmhoqnpenkfjhnkpmlprhvkqnllvmjnmbpnjktroptmoqnrmoncoqosrpnnqlmgklponpognmnpnlomplmmnqsholkomsqlsrmpngslpnstjnrqilmprmurnnmrpmonpnprowpqlnlnojslsnrpqqfpmnoqnmoxoyoookposqsiljprsqqomnqpommmgonmqzdmotrdshjsnlonispjjmimplmsqjnlomiimnmkmjskrpogpknlillmnmiqqmokmiqogqnljlinmrqrqmnoipnrnimjnnloklsljmmrqkofmsrmhqmoosompqvomomrqwopjmnpomnkopallngqknopjnmokoqqtqjqwriqlszxjlpniprpkmnywuknkhhloooglto~qxolnlsp}srekxTlqdregppnnulpsnoqqfjumqkrtjkitomrtlqvjppnnglrkseytqprhqkojlqnsrsnrpounqplfflposgkorpprsplnoomcnrlqjttsiglhlilllrtspoqopnrmlgqesjjqiiktjksmssqrkoonpnjgvonclynkpikoronqkmokrmnnoprhqonpkspoqirrnmsoipqjponqjwkjlonoqmrlmloigoqmolopjbklnnknpnpllokmnlnmupnlponolmjmnonumlptxnjpkomqoopmmhxmnsjaxpnllnomkrkmjhjwllomljpmpmrpokmnjmkjcqouotjnnoqmqpiijkskrihlrlqhnolqoopunojgpnwnkmtvikomllropoo}xntmmnnomipq{kmomlslrhnmpoikwmppnptmlvlqkonokqokqqkpmomimjmpolmpoqrqoslrnoqromlqgnolpoiqsprirponmlirocpnnuprnpnnophoonkjrpxoqlmkqnisqmornmrppngukkopqmmjnohomplelktgqqkjifooplptnmololnorifngilrlilkdpprlkiqpmmpstnqgjqcojlnonoesnhlppnkntpoqomprmrmnoejhoxnnrqzromfopiumopqpkmppixmnnoolhlnflohnrmmklpljnnooooqpplrnofimgokmknngskknnrlijoskjjvn_npggvnsrilgbfpsetdotoqoshhksmjoqoqtqutkhkmpmqnnrlmpprolnlkrphsikpejjljnirmsr{kokomkopcogpnownnmpbmqkjntoishoqjrnkipptkhkltatlqpljjjrolkm^ontjopjllrsmgqtkmtupmlrimjgmnlpom{llgrmclgmnpprsohloeplprpepqenpqospjnqlglqjkpppnokwmvotqlqoiolljjplnkjholmngprjphpjtupgmgqkmqjnoonmnkojqklklmngnoronilkoortmpkhlnrqmoovqoikqnnlilkplkjmipponmqlnotonopanmollnsomplsnmonnpujjhopkpmlqjnoihkopnnijmnjprkonpokpnonnplnojsjlnptoiiknulplomhnrlnqnornnkenoknmmljpmsokmqikqmmjgcpzinxmprrmrkpqojmnphnojlhnnklmnrhppkrnqolphnplmnnnqllnmoknjmlpollkpplnnoooqosoklnnqjnqnkmopllnnorpkemnlrngjqhmpmmnmntrmhlplnnmkouojlmkgpnhnopqnmmnonqqqtqlnqkpjomnnopkmnispkrrlrlmmgopnpnqhmkokn{rnqnlnlnglsimopollomsmwfnnnmonnskninpgmjmmnnqnooinopmjmnrslmprosmlmmmssyrpiknomnmopnoopopotqomsltlnnmpnplpgmnqmkskmjkmmnpnpirpolfnlmqlnoolmtopnmninnimimommmponrumjiopjl^oppokommmkusmvphklnjmkmorjpnlqlpggtnlmsntkljnjnomlmkliponqlqsomljokqnmhpmomopvnhomunlphkmlmopmmqmsppnmmprjqnoklnnlqoplqppmmjmlriyqpnooqtsrovlmmhjrnozpmiknnhmbhnnnkpmonrpsmgnllmqvonnkugmorlrlmnpsjnkp{nkhqulnoenlmroilsqjkkjhnqnulsrsmmzsokorjmkpopnenqpkspnopyinrmomhlqnokovjstpnfkrlpfommsnsouksopnnkmmpnoolmogttmmisnrjromrpunmygrqklomilojqjlrpmlwlopnsokljnntopmipimkmljmlnliooviqnvkmpnolsnknnqophdrptqkpulqotnrkpkmtrpnkomqlnnorrhnjnnqnojmmosrpkqnnopqpsjopmpnmnqgsnqkeikkpnxklnuhqonollotllmnnnpqqpimjnttlnoyjtqqirkspnovnlllnnklporojlnpmklknvglmlkktuklknpjlmmlrqkkonhpoqxpltmmpmmiomnnrqqvnenopvspkjkojpnrrqknokmvloirsinkmmntmpnqlqrwujpholnpjnpjlrmmrllkjolntmninnrkoqoiomqgmjkpqglnulqmnpjljmlgmmhmomomfmplnipoqmkkmqqoimmqrvooxeplkmdppukpnomoohjtjqnnljhmospjvmykuoimjntulkiopjloflmlpmijnolkqgmknjmmnlkmhjrlphlumjqxmoiustpmimqjuosniemjkopmoprmlqvnkllo^nrpnnumfmssgmqsqqmlrlfmspmmovjjkmkjqioipkronpmp{lnmmjppimgqmqrpsrkvolnqlgrnbrqjinmjlnpljivrrqopqoptpmkkrqknojgophonmnmmnmolmsoppooimoozinonfmllbkopprpmommjnskkfqlnnoklmonhnioomnmpfonvnrpklojminrrnqmminopmjtlmonoqgmpqoomnloogrcmomoqtpoolonnpqnmnujnirmqnolmpoilnmmqommdquilrmnnhmnhpnmomplsmpfmlqpnpstkmnkplpmjprjspoklonnqgopplpmmnmrljnonnqobmononmmlnmkmknnqnqrklmryrlpmnsjmrqnnonmftposqlklqkomnqhkklinhwonkqhxmorlmlmerohnqmliknnnlqrmmmjnrlovkpnmmpkkqokuqikqkkomlrntnkksmmqrnmnmlmkgqmspnmosijlnlmooompdrqmlunorossqmkqlolqmunnprooplnnmkonmonnumoqsoolmkkokkplonmsohlnjtmskrmflmjkmjjotnoonnqnholnknoolpirkqhmmmnqoqjprmklpqmokmolrkpmlipvlmorklqmmoqpnqmpnqpqpnupnkmnlmmqlcnmomkmljotpnmokumluomrrkmrqpbnhgxqgmpot`ooksqmpnmooniilopksumwqpijomikdrtinkppgugmpljhrimlrilgomohotitolijkswjnonogoimoopljtlqoionjobidmfkkoiqmmosqknkmtmknljlpimlkrqpmloonlmrjojiooopqomzgjmijnofqmjsqvonkolorgklmkmgpnnmnooelsljiokoknoljwqorjmmopukkoqdpknlgqonmlnrkvpkknnhpmmjkgosimfror~qsrnnmnoprfoktknnossrnnopjopkskkngsnmmqkinovsurjstjnpinfuomhpmmqkokhioqnngnmnlpuipgnpprn`ljorntsnoknqwkrmcmsplilqlrjllplknsllnqnrnolulqlnnmkodkmomnppqiqjpvkjqnhhrpnmnpqioinmjoxnomorlmpopmrmsjru{nlokkqpsoprnZmspkrmjommhlpnopkpsvskjnnnkklolpjpunmhmkqimppmmqupkmlspnqljmmnmoqnodlmnompjnhprklopkinomtunqpmooohsnmmmrnmoronspprnoopmklrliommolljomppmmdmrqqmmqnpoonhplpjpplmkpinkopksknnpoqklsnqplptonkrnrommmnqriqqkmkpokmrqkjnlknlkopnqrirmrqnnottqxoqnvmqnnpolmpqnmjlnrtmiqnolonpvgmspnnnprnklvooolrnsnllonpmompigkonkpoixqrdomlonmmnknfpknpnklolksbnnkslhkwpupmlooqrljpqnjqkpmmnpqloilkmr~lsimsklnmplmloukprpjoporjnomonpnolomlppoqppk^doqnpjniofpkjnsolhjnnnonsufllmjorpilmpjlkrloimkllskopklqnjpcpiomnlnjqpmhnjprqmnllknoipnmnqooljlqpljoskomnnnnornmnhonvpvomngjnmnlnrmnpknphmmtmmkmjoonnmoptmrjkimnqtomojnpnorlpnkmhfounkoqnnkqovjkwponkookqoqmlqhroqnnpwppllshmlqoolmnokqmononmoolonnmmkqmmonpmmkdummnlpnmpmnqhhroirkpomnmoomlqykprpmnnqimormglpimiqmgmnrmnrpsmlnnnoqkpnplnjooknmlmglsnnlorkqgmjoltmijmlkshoptqjvojpfilnpqlllqoqpfnkrkttkgposkusllmshnrqnskonjnonlmoktmimolonrmnuomjnmorllnlpspnxlrkknwpqjrtppoqmntotjnnpklmljojupgmitnjlolqonlmprklupkjfonlglkppiikvmmrllnnmmklnnglkklokojpimtlnqspsimlflowlntmpprqmjmkwiqknrmttlnnpqfinluomxnrnokmnilpnpknmpjmoow`rnolopqn\tjooillojmrlnqplppqquslellupkltorucpqphejpqjmrlnkmqposokoqnpmomgipknmlmpklnqqkpslkttkoqkmmncijpmnktlljsplmvlnjkonpksimrcpjraiptrhmonlmimqjnhmilljdjsojmsr~tpnpokiokmptlphtrnkcokrloipkjmionoinuonutkskrfscmlrnksnmgjhsnhirplnfnfkmopfhplpkjmplpjo^jahummninjsmomoqrplnmpmpoopnnvrognoliqkplonrnpiipmpiimkcmkmvnomplomvkklknnonnphomjtopljlonnpmlqponnvonqipnljpoompilsmnnompqsklkooofklnkmlllumvpnppqmvplnnqoklkourqqompmonlwlnompsonmrjovlnjolkksorolmneoliilopkrqnljqrnmoplmmklmomqompmnmnlmrkmlllpnplippnmoppslhqmnkpqlsl~molqdlpgopnkuprmmlljjgnliljtolmrqjsfikohnwcqmkililnlrnnp}kkmojnomrooqqrgtqmnolmehohknkkrrnjmljllrmiiolqpklggrlmrsouqnrlojnpfrmkoqihimnnoinskjqnrvpplerjqkntqogtgmnqvoojqupluqmnionlimonmnlmiqlovllloiniknijmoonsnlipmjntjnpspoqmrjhqnprtnrqtooomnptkooxlm[innnjhplrvpnlmopksiknlnmpipkolmkkljopsknknikqpnpfnpqktnniqnsnplpmmhhnqpnlkopmqloioollrtmlpnmmplqmhhlqsfjumnllpplbooiipmrplomrmmvkooonroonionlonkpemprmqonplrknnmomhonqnrpvmknjlqnpqnm{lommohlkhjkllogsqirnmrkrlrspnkoolqmlmtogpnskispnlilrlphmnllhoknonprlpkip_rooonm_ijtkqmkqqovperlolnoqmqnplotqmtnkqvhomyngkimpnmsvnomqktmnuosllckuoqoplrslnrolhrllglmpnuhljtjjimqcoocqomnnjkzpjqpllpkkmklonlvhlfqpksklllqjknmqooooplppplrilmpkkbymlpipnjlqnoqdjsmtmolunwkoolqniqqftwon{qlkksrmjhtnompwmnnjjpxnsompmttpnptksmprflplohkmpmunkgmnnnpkpktoppjpmipkwnrklmjonljpkmsmhqponnepiqsjpqrlutjurlosrjnnpoonksnnlppgkmojonmqpljmunrslqsonlipkohfpmmgponsowdimjoqmqqkjnmoplwmmrhnhmnnklpnnmlmmmroosmomnsrqnnlqksnlnoknqhojowzospukmnijpkkkpnlllkjmoonmlolmkkmnmpnomqppvolnoolvppniokgnkilmqjooolhgmnloloknwpmlpgqmpuhjbugjrnohqqrllnmflknmnjfljnpqjooemqpijylqvmisoplponqpolnnmskjnqlnkllokwmnqkonmknkjpeqqp\jqkwmnmqhikottjolhlljmhmnmkmnlshptkrllmlolqpsqkmjmkonnjknktnsmojinfrrmnropknnrlpklmrokcpodrmhknmqlipmmipropsqokgnpqosromlinplnpimmmpgjiokojnlttaxlnqmotoopgllmlnkknlpqmspneooppkmnqrnnqmmunpmimkvsmiojmttnljpljsxoljmnlpfrnrmnokrorojlmqnslpskpsolmlipkpmimqklqqqlqrolopoolonnsorgsorljnnluoonnhuhmqmjssmqqropoorponpmrobplinknqpklntpmgjnfmhmioktlkvpnqnhnpnmnqok]lmrlroorhopjqnnponqqkmsnnpnnponmiqmrpomjlomqplnpplpokrnmvjpnmlkkppqpjoppgqmmmkqjoloniiqqvolenmhnjjnojooupnrvlmlpkqnm`pgnpmomnjpkpokpoqnqrnglkjpoodkinwnowhontmptohmlmptkmhqinpnpsllnlllpllqjinmmpljilokpniknqkrpmtolmgmoofprnhfpnipplnxmnjmmolsno|njjpqmouspoppjfntknopjllonqrjlplpmgnnrnpmtqmnlnprnmqmlpsmookrpplkfnnotjnglpqioiklonhjspotjsnjqronmmpjmjnsrokgmolnprkpwrhrillgnpuonompncpooonmnsolgknhmniknhtqotmnpnroglqqquosmpmkqoimonknvnlropnoqfomnqplnnlmqkspnkmnjlltrrphnqwlpkprkllltnoourlnoqoimmjrhncemokklullinrntjpmtmqmojvnynpoktopdprporpvoosonllnrmojslknsqpyqqmmmoqkulnogosjdnvpspnr|fhimlonlttuoqpogkftqjilmmremhjppmixirkojonpptlintupqogojpnrmqrmjnkmpuqnsjjjnt[mljrnfptosammmehnvjrmqlmlqnknjzpgnnkeftltvgikkqqfimmkqomulroqqsnqnngjolhmqrlfkponmwntoppgsslhonqptkonqoijmnunumrklltrsrqljpqghpjowmokqriootlmkvmllrlqnqjrsolinmnomtjjpkinplljqhrkslmhqnknonlmqnoolhpmmjjkgpnn^gpoonermslnppklponjphnjmlglnimlsoqhonsmongolrqjinnjsjqomonnomnkmsjononqprrmqkmonjtmommokrnnnmkr{snpmqolqpoopolnpkpmlpspoohomimnlnonpnklsmiqqmniojonkninopgnomunopikloopsontnmqollponmnokqqmpnmfnomolkmkmopwmonjotprmokjn{qocnhejl}kmhmsqomkhsmmmjhiepwqkopkjnonikssksvsrkcpurpxknlgonqqjmllfqiqmnkkilnlmlnoqpgmfllotrfjnkrvlunotnokpsmofllpliipoqlmijhspmqikjlqorskiiulollppkonplopkfhnqipmegplmmqeotgpilmoomklqmrkomkkylpqplqiprrpqslrljgqoglrnnqqnfopsqspoqrkhllmotnjtklsjxmqlljqombntcpmmlnknonklpolmnjqmmtnoqllgmompsuroinmoplgsrnilopomqnnpmnjmroptlnoosmmmmjpmpqokkklgnnmpkposqnqppojllmrmornoillmpopmllrjjmrommnmnhmptnoljqopnqnqoqsnllpjmkorltnjnplnomnmolrpnmqgoljqnmlqnmlrkjkmsllqpnkoepnmnlnrlsnkqoomnrkoronmmmmmomnrnnkpomnpinorqnnillkuikqjwwokolmiospnoonrlntpommimlmopptlgnwpmlmsnrmhwronmlmhmntmlojlhnhsmplkgmmppnkkptmpnlmqlklkmlnoiotlnqknnpcpqlppspqospmnomqnnokokjrnouklgkqmolljjrsqprtppnlmnmmgounekqmhprqnopookunmijimnohkltmpmsqtnrsnloipsjlmnrrntjlmninnqoqmmltrompponpsonnommorkomimppnnnnkppmupooompvlgtlqonmonpoupniolrkmqkimnnmsjnlpmkhjookmkqommhnjmop{pnohiklknlnolpfokprginkolkmspjro}mooqkpqsokpmnjmwvoqodrngqnjnjrnqmonntnokkp^nrommnpqppokpmmhppoonjjrltpmlo|irohlq|msnmmrgppsjuosoomirggnpmpopgllciplokimpuklpnloplnpmqmolofppopqnqnpjhqnlomhvrmoinlkimowiltlopqonnqorktlomoomkqnonqmmronophknmkmmpshkipiokmlnlruonitqnknhkqjmnlmpspuhfjoqoqmnnlmuoprplhltnqotqonqoonmonlwlrmqonnsopptlpkmnmokomnmqmkjnlsnlorkrlknsminnlllsonolqlt}oopmnmholkkotpklnnoprkodomtmmwoqxpkpgonenljmmnqnkmoojllpszjpqlkpnpmjqknjlhhlqothoriojjhqskmxnmhuojmxormkkljmlrorllsutwolmjnslpoqhkpksckki}ppmknlhiueqnponillrqhpjnmbqhplmglilydhlmkoloonqrnrtmvompoqnkjmunokjlnikmoqljmqsmojkopppgynjojmrrkhjiodlliuleiknimnpmbimvwoqqsjmhpmllsqkuvkgnlwnnsmoimqnovgppkoqopnsnkophorltmppvjqqkompsrolqmsppppsunsnssplqjmeiomlojnpnhnjgojpommlpummmmnnlpnlrmofjkplpjpooooojmknonnjjelopknolqigppokhvtoopsqolnmlspfonnmmumkpqmjlqhnnpdmgipoqjnulnomrpjnhnlnjomgkonmnqlqnqpmolrhqnkojlnptvm}jlmjkpknqurnnjorklmqungnmkrpnnfjnmfkksoywjglmjooooqdnvmgpqlkqomklrmonmlmmwoktoupfljoonoklnolhinmktmoprorpkprmmhmmmgcmynnllnrsonmoymnjprniuutgnrm_npkbtnqpmlmnompomlnokrjolosrinmllpmpmiooopoiaqlkmtpnjmrqjqsmvnqolmrmrlsnmlpjinnihqomtproqomvnmniooornmi^knnmklvriljmorohsflcpnkpqbpnipmooqpnnknojmjnlqwtvmnkmiomnqjomnmpnkqmmokdsslenllqlikqnrlknmhoilvmcknprnkqkoosmlpngqmogqjpnmnonnpnmpqlqopkuojoolmhksmonlmonnjgiotollolrjmiljnniqkhonmkimlslsnnttgrnltoflmmunookqokltmmvnkqolmnongoljrlpknskokmrkoninmslompplpqmmlxnqlpnmpmpnolstkonrspnnkelzslfnjrojpkolkrnopopltmnlzpmrnjjmmnmmkmmqksnmmislmlnklnkklilllsogjpkkoqqnnqqjolgrqooomnrmnlpollmkomlpnmsmkoonkoenkjkqlllomtnslilmntpnvplnnmionnoobptimmrgiknrronnhpjohrpkopsooouwjnojnosnmopononuimmnrmlmlkkmnpjqsnonnnfqmrnqnkorlmlrjpmnmoomfmiocnmimnupnomonpslokppmsmijolhnogplktpjzqmrlnppkmqmmoplonpumpmqmjpmnoollsmilqqrtjmsqtoopbjnsdqrkpqlorlrplmhomrpplsmnkmjmpoqohnnkppmiqpksoskkmpmromqtpnnikmknqqrqmmonnkoullnqmkrnomqornhkmpoljpjjpllnpmmslhpqemponlqnnmmnjomslqjnulpopnspsokkopnsnnipmnjfonphpolrnnlkclklgnsomqvxfkrskkmqoinnknmgmsjkimsknplmlpnqsildnjkooopppijmnnmmkonimlmmkmlloksnplpnolojnpkgnirjlmnmqmpmntpneqntnoomqmoknqttpmhkrmmdnmllonkmomprnjlmllkkpmnmuhntpmmhpohrmjkmmtrtjiomlhnjnjkssomhqoopqnhroosjhwmponngoohkmlkvrnnmlilmlmrmmnqknqmpmenqpnrllpjmmrokqomromdoolglvporqoqlppoprolurdsqiuiopkolnmmrommjomopnjqmnvlplnrlpknhnhnqpohlkmnpqttkporloomlljnmjoorojwnomlmjimfonolqnooolnmnkonjkjjrpmnhprmopnnmjmkomomkphooknimopp{jonoqqnnyourrpninrqmqjrnnmirpnlponhnuonooplnpnkniniqlgodkmsknlrpopmqmkmssookeplqmpjqopmfprbnnksojkooqqpqognrqknynosplukmr_qpukpyolenmjmjopomookolqnlqmoqtpqmnqmjlqrmjlpgpnkormnomoomqdmmojojnhpoolqomnavonnnmllnnoljkhmlmqonjgnkzmjjpmnpolntnmklopjoiorjknnnnpmmnmplpnigqqkhinosivmpnomkjrmnlpisopoopmorokmpmmomnknofxqlmknslppmmmonklpnlomokmmlkmpjmmo\kphnnllpiqnjuijklxnnllmkmqpknglnhonnklniqlpporrnnpnolmnkompdikmmqonmofjrnonolqlnqmjruniqgkomsnpnjpkprikslqnlmlkkjmmqmminkynmollrhljipkvp^sphmnlsosnluqmmomlknqhgrqshlqgvnmnpyphqlitiopoooqlnjpqfntnmuuqmnfkjmmimnsnlrnjmnsnihlmjojojhrnmjoomgoko|mjoppfjfvuplkpgphkoonmspsnvpnomkkomhnmujngtohhngpstkonjrqgkpnmno}lgslnmlpkpqssskknmndomuhklnlnonoqkosqovjmjoomnlrlnlpmpmpnjlnqungpnlqqrlkopwklhonpilhnpkpmmomoptinokpompkmmwnsgmrqnnmgjrvonrpioljtwnknjlsojloqnnkskrofjlppmlphspsljnqloljnlilrknqlnnomjqnmlmmqjjqqr|lqjnnjfqonuppsoqntplpnjpnxfkvppomprnnmsoomnjpqmqllfqltmllmpnnqmnmtnpnmgomvmrnrnqtiqktmqjkopppmoi_hronjsjnqhjlrsoliolrlnnqmmlqnjnmkosrklnkqtnnrkqninoipkopnmofnvinqpoogsnmmkommmknnpmompjkjnorgpnlmjsqtjmkmomqkmlnqmmiopllosqglmklnmjoslhnqnpooiosolpmmolmjngrllinsnkklqnlpomrqmlrpkrlljonjunrkponoplnognsmoxpooorxnnnoopmljorqnjlrlknohukljroqqltoqioplqstmnlmqj_monnhllptkljtvppoldjmkqnrposmjnrnjlxoimllpoqrlmqdnmeqkinonpgnmommpmvlsmnnoomlspnjroolptkmjngbiilkrsolorjpgoqqmemkjonrmktnlkklsqiuongmlmlogmomnhgpnlorntokljmenroomknpornlmpxlomutmllnoqngqpnolkjqqipnijrorvlmsrmrlrpromknniqljmkkoirmimrkrnpnnosrniomsmlpknmnplkpmiroknjoqonmhoiolposjkohknloqmjmpmqnkitqinlhkt_phuiqokmonnnnxllpposonmoh|qlmhrxiprtnnpomjprrprnlwornpnpomlxlmquljshnlrllqmmupmjrlolnmiytmmjnpohrphkloormjqpohwllpnmroqllmqncn|jopkvmkrmrikhlmnmlgnomipjmrhhoo_niwnommqpmtojonqkqtjklnbnpsonmnnmssoomjejpxomsmlWeqmmqykntgbntjqnmnzommonfmrpohltqrsrmlrlrltoplopannjlgmoopp_nkxopsofkrqounlrnhriolpmqihnqloqpqinlgwqnmqqnholqnqpmiotmulnqoonhklkoqpitjnqnlmmlpsjrnjjmowmolgqlsmqqlmjmlkoplmjhqlooxklnixnoiqmuohrplpowslqjpnkrpopsnprslpljrmopnlntoionromjolqopnuololnmhmxlinltrnpolkmimpnnjkkopjlpsomiomukniohmpknoknmqnmqonihoxnqckooknokz|okolommmqninunmpfmprhnrkomfohksnmjsnpmrjllqomomplnmjqrmtpomlhnmpmonlplimlmgpljorpnoqmptpmnonipmolmoonommmoqsmjnojnppmnsnmpumtlsunmpnmonpusmqpkntopgnpmmmknmnljnllornpsonlmnhnqlmtnoshrkmqojmpnlmnqqnmntkoqmuonqrlnmnnopnosonnojnnllnnqomrsrkphoplnmtjfmposnoilsnohsomlqmjgmnmmoormojesomkmokmlhkktolkjooololinrkqlmdkltlkoqngolohonlquqkrofqjmonnnqllmnmlpqiklmmrjmnpponurlmqnqlokltmuknookimngkkprmloorolmnnhkkhpnqtomtopmopoipoloqrqmmulqpqrpqmmnlilqnnylnplmmsfmpqimnmomqmmmljplmoknkkpnjkippimpnponnnvomklhrklnqrkonpmlpnjpmrmmnkmnlqkmnpolnolnhllfnolnkqrqknnooqmrpjnnoqolqmhqmnojmrsnrmnlknmlmmqlopggponnlspskkpnomioooqppnsksmkmnprrmpjommfjjjvpooqqqkqltorlkoprkpounrntkmgjlsrnlpiqqjngnoqkpqmmmunjmmhkporssrhqonqolknppoomqohlyolknvojlliprptoolmkqsesndmsnslslhplmryqkfqufkxpounqoho|klunnrrjmqrpnrosphmqjkympqkqqpgqnnkokcwlselnhmprojsxqjodnppmnnklronmopsgooqpkkpoonkpulwnppllhmnnkqmlssvlondlrmlhtmhgikoqktpondnilsoprimowpk|klqtrioozjpo{msmlqixnhmqonmqoljlntppoqpyppnstomnmmom|jmpmllnpoknroojkomlmoskpnnnmmihnqomsopnonjoosqnlljmocdrolxopppoooqojompnmlqlqmgihmqloomqosnsztsndnolkiqnomplpmmjqmnsqopnnilthmmnmojoopnmnuvglnnopsioqhkkolmnplkrthmropjr~{nmhpljnjolqjkotjodlkpjokmgkooqmknlpkfnlhnoumkmnmmopqqonjlmmnonnqorkpmnpmqmlrgmousoiiknork]otnnnopklonsmmmhlllkoonomhlnmqmlnqkmgimljmuomomdgsmnkhknlnjnneslrllipoljxjmjqistmkhponofjdlqhokjponmphnnntplriiohohqjlurpighmnmqjnfjkfmonnonolnpknomolpsofktnlnlnknntmogmnsesiooqnpmnqqpqkrnrmlmnkjhkmkmpltnssirofpoknmmsn{mirlnqnmpjnnslpqmqoklporjokmmnykkkqkljglpmhmorktoloriljotonnhnolnmjjmmklkjvppvppqpqprqnelstnlmoknrpkolremnlkmpljpnmkqjslmnbssokxinipjsomhpnrhoninlfvhjomssojplmoqrlsoeollqpmipnooqjlnmrrsommtqkjqjhmhsqvnipqklrvopnrknutmowtjpkomnoqqpovqkmkrmkrlnxpinsmosoltoninplkqixqknpqpmolnkpkkrlmqorkkkkpukoxnluplqplooolokontpummjottjklrrchmospxspmmjmgopn}pthoioolmnollllnjqyqkmrsepmifhpnlhoerrnsqcpykollpokllemomqmsnncnmmlqkogpjshnppstnovqnmignnjmxnnonpwlnnmpsktsrmirfsvnmkonoslmtiknkinrnkonjolhqgjpnkhfmnpoupkpqnonjpfkimqknekjqpjqlsognmtgvqnmohpovrllikrkefclobqononnonosmgmnnqompmqnqniupqnnkplnmonsjopiksioohlnfmulnmlnlpnqqnknlmmqkqnlkjhpmnnposnnomsqqhlqpmnlnbppmpohlfjnomipomoohmplmmlnppmrpllkplkpmpmjlpolmonnmlmnnpm{flkokmjpnnonlqsnkjppnrloorfmjpopmnmsmrrmoiooploojqkekmmmnnmplnnljmrlnoppjkrppmmpnipmmlpomrtromwlqomoogkrorqnnijopolspnnmmmmijiphlnnolmnoskohqprlkyojinmowmqookonfllmolnpmonoqklskkrioklqhnjtlooulnqqnqqeqpmmotqjjseonhmomkkjomslpsqiqqpmnqmlnppsnmlmqjpkkppmnolk{nrknppmlsmkmpjn]pokponkohymnlopprlipspkpphlokqsjmmfrmqllonoowqornokqmnnjnlrommppipsnmlhasroopwkmmnn{nnplmnoqnimoqrnlrqoonnfmennpnkmsqookplnnpsqnxpikooskonnoolrnqpmljppmquqosoklogsqopmlllphnnropnpdljmrnmouthopqilbprllkgqtjlojlmsnnnklmsoroopgjpppnoglmlkolvjotlmnpkolmqkpfnmndlklormpqkllmpqropnqerkmppooqvmsnnqkgmlnkomnppolsppoopngmnljjlpuoskrpmphoommnopnlo{trqogqmnqlinniqnppkonpqlronoqpkjmmnhlppnpullhkoxkjlmoonvmovqmlnkpnlqngijnjumnemqomlnopkjjnnkmpmnpnoomqpmpjlnolrlvknopmjmlomnjolnmnnjpqqnmmnpmlsponnpprrskktmnolnmnmpknulmdnpkorslnkrkjpsqkklnkmmmklmnnjcmnqqjnqnsmmpnktomoninosmkpufrppilnmppsjqooikqpmlissokpmnmonmsnkouomllmpmkipon{kpvmmmoqmrhnjwrpqnrstpzqoepvngmpqvqnommpmojmlllltjvujnlllnnrlmjpkooh^qqojpinmptnnkmgmoryqgtmlprlmmtmkmjlmhmgkotrqmpkiktmnqllmikllnnnctnmlqrmnkpmbqnmoiuuqqjotinwpovpnpojrmpjmlkoqukqpikmjpmiomprjnmlqorkjoopssskolnlmmmkjlnpnqpkomnlqllnntqknmprrqojlphnomjrmpmptpurnkmmlktnrpdkimplnrshqznmmwlilnomhmhkmmljnmokqmqfqikslmgqjlnnnolknknnmxujmnnonnrmrkpwnmuroplrmklqtphmlmnlnurlqmlqnmsmtmonofpomllmnmmqmpnlpmpomlpgniqpiknnjsjklpeonoqtsmopnnnjpkgpfjpkhgminlrpmnmommklrnloqnnolqnppmskekoqnvmgggqnnnlnnjkokmjpnopmlpjpqsnskonxtogonpopnrqnoojmnkoqlinmmnlonnnprqinmnkjnmpmnpnqtnljlrgfttmonsojvqilhsmlrotrnonnnpqoopnymngqqjpkgnknppnlogkopumfnnlplmkoqtnlnllrlppktxoromntiotopnojnqopjlimoowmiocmnmrfjmomnnnmrrpnpmkkhnmooonmoomnppnnnqnpmoelnkmknollllnoofrmjmqnlsslnqkmlnluhpkpmpphnhummlnlrlnmhoeknrhompkmokclrolnpksonopnmnjnnjulmohjisnnhnnonnpkkpoinonnqprronmofpsolmmpksomonmkijfnonpmjmqprooqlpqsskpkkmnmmtrnkimrnsrjnkmujpplolnmkjinempmnsnlfljo|tnnimfojrrpmnmklnqostmkjpmjslnilmkstmsmkmpqnvqoopkukommkpsllrkokolpojmgnrlnnotopjonnpenvoogqorhnnnphktrnmmovpmmksirlpqnnniqinnppqmkkomnebqmkllknknnlmoloftslsrpnelpovjrjrmnjlqrpppjlrwkmpmrllfkommuroojmmpgjomrmjppsnnllrqnslnjndlhqoskjkmqqjiosnkmmmpkmunkppvpporklnhjnosqhppilqkpoclhlqskxsjlloophlqnlpqpnlmmljrmpsmmooounhrroqrmnqpminoijpsqbsononjpmoknnpljknljoloopkrqlholrkmnkoskekonmloplqooklnnqkgirqlmmkokxqllvoullolqloopmttlpqkkldlnntrnqmtmluuwrormiqopjlrpnmsttktmpoprforqposquunlqdljkrnpiskqkjkhmumnjplominqslsnilmomokqinrmkmoxsijkipufruqnqnmkmsmnmmloikolorknnhmnmqosrlqlvnhmplkmlnosmnpqmunltpoqmmplloilmxmqoomzjoqnnlmolgmnkssppijwnqnotrmnodnvmqqnspnmlpjllmnnvrmonplinqloonmmeogookpklqlqnkpmrknropokollnrnmhoknrwrholhlonpjellnnplmpntnnohkoppnmmmlnprmoiiolmptgosijnjmnjnnlpnunmonlsmpxonkjsufqrvnntollqoojsnpnolnpomnnkjnnphmmormrqmplkgjnkposiplmmijoplpopomnomlommqnlmmnlnrmjnoopshmmwlorqojntxroxprnpornkrnkkklnnkolpmlnnnrkmfwkpjnoroommfogooolqqomnolqmrjoprcnojnnqnmnnonmnnpmhmomiqkhnnnomkllpmlnoomnkrohinoqmppjlposnrpmmromqlnqojmqoqqnqrqrnminlkmonjlqmlokknmmnkoqmnommmjmlnopsjpomnnmpimkoppmqokmlnknvmrokoktnlksfmnnknqntumkpnjmnrlpksnpjonfqilpprtfpiZpqknlnnlomulnznmkjimqrqimorntlllnqkmouotkgmiqkqig|lpkkm|osomprmnonkvmmtpoooiopngnmdqqpopkqkomplpkovslrnlmcvnjosmnplvmnmolqgonqqjsnmnjkppnijqmpnollsulerjqqpplmnvrmqskmmfnoulmmnpomqlnsjnunmjqosopommjmpnlnpwnronphnkpvpsipjlooldjmlogilmhjnnimimlohohnfpnololouzkjtpoolllulnphmljlvnnqrhsiiogglhsjlmkoqiloowrgjnlqoonmlfkpnglmlfrlinlkhnpmqwkqmlgonmlqkkjmjlkqwkohronpnlpojtqolpnqmocokoqivjmjlquwpqurplhjmpmmoonpopqnejqqpkjkpowooprlnnjnfmmmntqvppnfmogknlmnlpilnlmfrpknrnppOkpkngfrnj|ikjlmnnqjjpltmpnwqpyly{npxoirmpmntmdmpcnl`mgngooqhlmolnojmnolpjpkopylmonpkonjnqmbkgnnnjolthoqpxhfjoojkokmrgqnupkqwgompckljcnmpmlolqq\ljsmlqmpojmktjoomcgnqgpqpnjp_mlsnnnomqfpnlnnnqhzkrtpmhrjpmnemprlnroomqvrokjmhnrzomqmnlrusiolnqnlmmmfmnqmmgrrlmxlkk}tppnpokjRmknmilippriklkninnlslkogopmppmpnohmrqlpxjqljloksllunm`kkjqkqsmqpjnlonrnqqijljrkhlvrpjxqqkkmqomqhlrimnnnikimrqqmfnmmmukpolikpoYmmlhmqkhonmjkojnmovogndpojysmqlnnoloqmknnloplplmoirloeqnmktqhgojjunnpjkrkrekgjlmnpmuqmkolnmkkqtmnoskkmmlolkloqinikvommpmvplknuqqonllmfnoiomkpmljlnnjnllkoqnnpsmjpjlojjqoipqnknqmkomoqrmlmmmkqlqqoohnpqvuqlqnqlohshnolniiolpnopnmniqmlpososrnpnrqoqnqntonillpyrlompmmmcnkrmlmmoospnsommoknmjnpnoeqoknjndmlmnnqninmomppomknqihmlnjnkqzmmkqpmjoinpomplrlmlmomnohjsmjmhnpmkoooppcpkiqfqinmrnnspqoqojokpooqnqjkmlnolnmqojnloplqnkuompmpmorhnlprksoomjlknrktllllmnsoncjilipmllkvonpmqqknmqqlmmmvmtnkrlplroqornn{qpplsnmookomsqlknmnspplgkklajphmpmlmvrplomjmnmokqikqnjopknquursqonmmkohvkojmrdlnklmonvmnlksoigrntmmmmmmonnjoolnomjipqlfninmpjhnooodrrmkmmlgqnmnmojokqgoqosmmjjnijnhmholnnljnntkhnhgoqmgipmqjqhnunnxqlmokpppomlmsqlunpjonndptkmrmfnqmlkojfokjqjcnlldijilomqohrrmimnrmimlikoolmmpmmjpwipnolkxjpoqmnnsllpmlgxoljmoknoonmhojoslijplmnorklmnmpgikplopotjjpmkookerllnmiponprmboqnpmpmnqjkkiqonjmodriuhononrmhmmiojhnngnoiorrcjsmntnpwtlron`lspnemnqjmkniqqrsnjmoozckpjnkonomrsokwplpmtoprmmjrtnkmpmomqnopqrmtvhmlsojpomomniqltsnokypmlnnlonlomoplpkpmnoohqohomooolwplojrxmkjsqnmdnonqppnnqnmsijpmrojdonjkmjpnhileqplplttlnkkmpspjpmrkkzntjpypnsmloolhlmonnoohmnlounhmiplllpmqpsqlkonhmknwlntmqlhrnmm}moolniioollnjonqrnlriokmolgllfueonnmklxtmmmhfopooqqfqokjlsqvhsmojorpoppmzsmjhlojtkunmknkknjrummooutjpdrmmvlnnnnoollipjlmlrtjsookoqndpkhnpqxljmmqnoqmmoilmomihliizmqlptokgomijltmleomlfxpjinpndnlmkpmsqiniponklvmomotvklkqiomaoefpnpsornomtonmkoponvkrmoptlqnjopirrrmnglmqrqlpnqommmirklnromn[ufpjooomkknnmshnoojonniojwlqmhoskrmmtnlpp_klnpmrqmrdoghtokotrjkjsqnxlolnqmnplrqmkpopmnkwupnjknrksnilpljmqmprjlhnqkhkohvlqvkmlohmrlmnpojtqnntjpomnhnmnrptlnlkonipmppoelonllnnmlnnprkookhpsnnmsnokmmmlpksiqgkeqotopmhomnnlrjsmnppnlqgmmkmmloimkhnppllimjolomyi}jojcl{vllolmvlenohnlnomrqlmltrlplijoloqmnmnhknoilijrespokjlttpqplppsonkproluqllooqingnkrkwtouplolismonlnnhliqellpxjsmsoeokippndnlmmvrokmkootlnplqiplnnmokqnjkjgrlqlilnnoonokjosomhoqrqmrrrmqklliqqtlorplprkroqmpkwfnojhm{mqjpgntgopdlollonokqlojtqoknnsnotqrojhmmnsjprqpjnnmqqomgtjmmlfkksnlnmrnbfmpkknnqsomkdywnnoinxqjmoioinkomvqqlpjmmijloomrpnpklmksmlmjbmpqkhpojjommirllpmxononmsqkomnmlmrnmgpgijfnlmntojimoompppmamikonpmoqkllngtmmonqloyphqkmoopomtlihlpknkmpnnnjmpjklgoptplonvqpmoqllnkopniontpoonnpkmenrnlkrmllngnnqrrllsnmpflmoxmpolwoqlinnnkmmmnosoknojtnrpmpkjpkxutgnmmlijgpoonnmpopnqntmm`pinnmjmlkmoololinofoqmomllmkptnnjoionnmmngkolommppfnnklmuphoonlrnpohvnmimonpksnnlolomujnkklnompklpqonpmjnmknnlooossokllnhmoootmmomvrpkoikrnklknmmpolkkpjjjmoonlnhxknmlnilkononnnokurjlloprmktmtojmnoppohmrmmnommmmhjnmqvnqllslpmnjmlopqpqmporllnmrnqoopgnsnldnkhrnpnoonrlqnqolmppljpmtnooktqoklpknmnokmkmremjkllmolmlgmpmmqkokoonpppkqpvomopqnnmjmnnpqjmoounllnnpkmiqpntmnlrorolnnmrnhjmkmlmnjopmnteptnhmnumlqpokmpprfnpoiojilqrokiminprniqphrjpn^plnjukulnnbnqkkhnnqhoenpigmnlhsnjnpmnhrmnkimdopnemtnppkkqnjhsrmgipfrqrnmkqykmrqihppoilqoipqiohmmernkmpmnrqornlnmqkfmljrsjqokxpproklkohgoslorppljgjjnsnipknlmnhvljrmo}oip~oktsnkmpgonmklnepmptlnoooloprlgnplizpmmhjiqlnqqe|inmomjnjxdttmmnnjovfpjfnpnkklgnhpomdogoklklowujllf{lsmonfnlnnlollm{llhpmjiyojriopikgoonmlvirntfp`auyomieiurnookdqqhrnmmnolfoonlpkrlklpgmnonnixkkqqlopnqgludqxsmtmmpunlnnmm|lmmeimmknvtlqdrjnhoqolqokmojmrjqnpsnihsplpipmmmsoplljqqlsprmllknhpnrjluqlqlnqnynhkmkipgmnfnmomopmgomqmlorojonlmlmpmhjlrnpsomjilqqnmpkjnrpxsinniqlj~oshkgpqhoolqnollqmrmppmplpknltmnrmomhnjrijosooomnelrtolljsmjlrkjhkmpnqosqwcmmqroorqpqrkmoslnppsmqkllkiqnpmmoknijrtnrnrplnuoopokmoplomnovnmvkkpompmhmjmmmkqnmklikspkroikjpnrkpopomtpnlqkmnnspqpoupnpromloojhropkqqpqpkpomuojrmnohioinooqnmmonmpmsotkpoklmmonqnornoklqrnlsioqlonknmlpolmmsjsfnulonngkppolnqptiiojnonppnplnkrlokpnntmkrniqrplokjkpukkmlwovmrnmjpoiloolppmtjlnpmokmsjonpomioqrhtppjgoummosnipmqmqpknsnjomfogkpnrljjqmkmpmmfnzjtlnkkklo}gnkjntnnmphmcpoljlpqpsimioimqpvlqqpmolprpnrnlnkltomnspkjqlnqq`nnolkrnnlmink`omqiikrpnlrmooilqnmnnqmkofjjppfkmnestlenrppoqmpqkqmjinspmplrlmolnkiflkqnqlsljnmlvrnnomngoqnhrijhmlkjeqomkpgqlglorpnmjolpohhlvnohnmnpkhoosmnsopmuprjwnuornlqmtporpunfmpkwlnolnuorzokmkrqopmopqeqkrvnlkqgookrnmoljmro|qmmooknmspmkioglimlonplirmnnnmnnosmkmmrooonotmnorklnmvolpnqsmqnmroqinnmoqmlolnontljllronuiojoljojmppnpqnqomlqqlqrnojqrqnlopltpomnpplqinkroonkrmllonmrolmmpkhsqnookcpkknkmmooqmmlrrjmlmsollthotnnpmmkmpnowoolnoopljnnlloosoolpmproqommmmorojiqkljolqjjogfkpjqnzhuspkkjiolqmsojnimtoztpio_cxfsklojqmktmmsrplmwo}qm`jumojkqrmkmplqdmpnlrlirxrjftmjTnmzqpdopsmpstlrrpqlmprnlrjqnjkooynngoojollptipppmlpgmkm}hongmoqmosnholfkkptsmhokvk}priilnhfhomujsljqxgkomnlkhgqllrmtoloktokkkrpkpopppkpjwlkrpinpsmmuqhrslsmvdnpmqtdfqtpjmmmrlcrmprnpmmmjmmlborhmgllooqsikqunmdoljroikljjjpvmpojslgsiiligsqqnlwqrqlnollpxngqnnsslpprkotinjnmludiqurulrlpfqqookresgkskqqpliwqimffqprqononmpklukeonjlumlmkpnlqpokzrmliuqkuoljndpmoqrnyq`xomonnlmhqigpqorurqmrollsnuoqsomminlolvppl_nllgpolxkrpuvrlfjpnhppimpomqqhegnupmnolxrkjquprnkmhqogqqvunvqupfpsxnpoqnzomhjqlnhhlnnpoinrjqqqpduinrmgnipinoilvgpiesm\nnskmvpokonsenooomhnsoknrofqpjnpmjlmqunspjoikhmqmmmvrinsrinwnklrjkxjllrnnthm}rnqoikdqhoplntp_wpoqrmnrtokmsipnpiqpmpkoflrnlolokqlkllmjpqhoksqtjlkmskhtropppgnrojhkmwjjmoomujrhnoftpnoonqmoltnjltrmiprmngvp^nikjlknpqowmpommsonjqmrkmelkhfsqmnmloomlmnepoorrkolqolpmpojiwjkqpplmknmqrompmlqopprkonmpnlloqlolpnronpomlprmkosmplqvosqofmokymokoulnmnkfipnigkjsjmmjnkkmjnsokfppolnonlnqlmnoooooonvmnmlmmnojpsookoflnjppqrollomplwqrmhogpoomomqullqmmmkknqpogsoqqoskmlufrpqomndmigomlcownmvlkjlhmnmppllgijnnugplomnlkogmuivllwhmllmisssonowdwokfphljokmqknnqlxslpmkjlkmrmoukmklmmlrrkovitptjkojmnlilonmwmnqimxlrnnqnljpqrmshokomrniqjngnnkqjmlhophijnqmglllpsqlrpoqrwknmmlmmkonknlooqoimoeonkmiommmhqlmrjpmpnnlqnomnlkkqnkolomrmnl^pooirhmthjriprpnmmnotnlmtomlrommolkmrkpoufnoomlqoobkgshumnokvmlmqqmlohqrlfpgplnmklomlosmmqlnolodfqkmnmmpimlqmoolmpqpqqmenkomplkqnlpprkmkiuqkopmrnknnqpmnlvipoipmlpmntpwitpnmmpnoqpmmokkmmsnipnphsmoomwongkgnlnk~mnmsilmornlqhrkhqgoglpmnlynhiyqnlrkrtiqpjpsolqijmk[frxrqjppiqlmimropfopmgnioqmijqoimqksqlyiwqgwnorgckspmnrnlohaiastlmpmjgnopgpnmorolukkummlspgjonjhnllpuhnipltlsu{ilkkfdjnnkpmlmnnmglnkkeltqlppjogmwhnjiboinpurpemlknqqplljolfpn{p^mompwrjrmspzsmvkikmirmir~nosjgknnzjnntppnomsmiqoonkoopkqgrinonrpoqoilppltnooqfklkhrqteolopmsimllsmmrlplmmopnhmhqgrqsqktbononllelpgnxvqpnjhmsksqlrlpkmlrkpcpoiqlqmmtgnqfkkokqqnfimsmdqsmnlmsnnokkknootlorpkknptmipmimmmopnkomuqhklmnpplswpnzmmlplupfklrjuoliloooimuplmnqpmorjhnqssmnipqkxonqofoqloqqikmnncrppnoqmnsknmokorphnnmoolnplnnkmmonmohnpnsknmsmrvnomjmqpknnnjoonqnnowojnnmlpkgkjrgnllolrpomnmnooktooppnklpnpmsppmlmqoknmlqmloljoonmormlnnpnrknppnnqolnqplmnprpglmlrenrnjospnymqoprmppqvolpnqplkqnppmojnmllonktshnmnnolommknnnornomlonoqmgmummprsqlmopoqnlmqnlpsokioumknoimqmnorowltopmimnlgqnnpnmgmnrjnfhlimssnqerionqmrpmmllnqppphknoqqnlpjplmpnmiokmqonnphhmngnrmkshkpmgtplkeknknkmonooojpomslolorjndlnmmrmomiqnoognllrqspioolhmuelomnnqlliqmopkoomqoinmkjnrnkoqpmtnnmoolnplqjnnorkmnponnqkmirqspjjnrjomnoqknnqqnmoppminpne|bnktniplqgxmmomnomromkfoqmmpnhplinlynhjnhppnklqiokpnsqolkmkmrglnppolnlolnuumqkokqmnmnoqonuqnslkoqfjjqujplphmpmnwolnkjmikplhqmoofomrlfhmnloippsoghppjmhmkpuoiqoqkjpsojqipooriklqpokpnlsnooihvnwjnnmjjsocpronmqllopspkponokmcmnpopnlqokmmrnplolkpnkskpqpniqlojqrzpntjonmmittokimleqkolnnngkkpkolhmlqjnrkmopjfluooifxpomkndllnqerojmlqimmnojlmemopmmhorempllmqplnpfnnsrlmjsqjjqqsponnsknilqmonnoqhmqmntkolonmlptjsllpnoimjlnhxnmklmrqmkolpnoplqxmiifinqllnkoflnjnllsnnlqenpioninslnkm[nklovmgoosqonompjhnkqrmiqodmmolmmhlknogfpmWsmprpmnkoynooqnnyohjpnpolivnkrnkflmomhjpkjhrnlik^nhnkrkpmtowntvmpkqhflsnpnsqmgpnsjtpkqjsqngpfhjoojxnrifg{jkjmnpknmmiltqprplkjorilslnvlmlpjpognhohjprsoxlyplloiiulplplklmnlpmgmmonqoknlnompkqpnqionksinnpqmtkokuqwmpqlqlsmmlwhlrmqnmqmlhlrlpmgipoplslmplkqnrogop^ppipjprjslyljoqfmdkmpqpiplkpwlknpmrovumpnjjmjloXpdnpkronqnooh}liolankkmmkkqnggopnkmjfglonhqprqlllsrhqejvkolim~qgkltuiljromhwlol_pljqmlmkknpkljllioriimrokautjoiipxkmqmkqlhtskzphkponelmmqlotpblormommptomgomqqnkkfo~nnrnrnskqnpvltopljspmmjfkqlhjcrpohjhmjmkljrvjsojgrqgrqnoqmpummpnjpneljnmprjkhpmmislnhohfpxvkmsklvphyiznpirqmnyvlookmrppgmqnkrqhuplvokopmsonkiljofewjgkqpnuslmilmplnnmskrttsmfquhmlnnmnrmpmlorppkswoosqpmkneslkqnnlrjnkkmltpjoxrlqiojskoiirmrlmqmlnjnnmmpnnrn_miitomcljnnpltmmnpnrgmhikjqosokkmomwnmnlnknmpkkmomiminrnolnijioltpmjirnnmpjmlmknnopomolvlqqsqpmimonpmihmrjoqkmnoormftnmliollvnpnopnlpktohkmltpjnroqisqopkmjllnfookkpomponoknlrlnndnomonmemtrmrlonlmmoomkjcmiopjjonpnrlnimflfmrpmqnthjkommnomdnpopqvotlmlwionorlmolnlrnkmqsnmolppklrlnmmqkpoqqppokgonqkrorljknkmjqosmkkrpmljmmqnmllnqgovprnnojmonnkppnjkpikgnq{meplntonjmnookpoppkrmnilqplqrmilmmmlpooooksrkklovlnoommlmrkqjuropqmimnjmqmhnsontmnowapnnononpnkjolnsmopiokoimmoqkmooongmommrohomonkmklrldsmqnqolptmmijlopqmbkmmjmonnmponsnonoqhnlpiphpmimtnmooomrooaqorlxlli`jmjpkoprpkqotlmpoiieoqgmmouonkoqxfptmgoqtugmntmqokdphkpooshnrmrkno{kspmjnlsllviooelpjnmop}kngnlmmnknxqsgvlnmowmpnolnnmjnnkhjmms{kojiolponmlppnitsjmipjojjotjmqjtllnhrqqnppqnnoqpjiqnpmdpqrijlrkknlqkmtmolopsllmoxlnspkhknhrmllioljpihqlmoqstpdsnfnoqjq^mrmtmuxeollotnprdiioglmxqmoignllrjmtqmdpfrpylkkjcinimpkjptkhpmnhjtmkgqpkknnkvolklmiikjmocopjfntocqwlqpngokgrmolistpkujnkmifkmnnpmplkkkmkjuirhqntonomvpodfslozlnmukxomnmelkrmoqnipvunpjgmlsptonwkkqspnknqnlmlmmjqupmpemnmqotdknijoyqmjlqliloshlqtqpmrnmpiqonokpimlopoorllpjimlkkoxsq|qpyonnloqmnonnoxouxugjlinkttmompkphminljuqppnrolelnnokplqkmromqnpminljssjpmoylihsippnkljssinllnnloronnjsposinniipikmogtnndnvprlpnsmqmlnotqljindkmpsmlmmiqktopnfkhrnpnlneionnmqqpprjmoodlmjmpjhrmpsnnuorpkmksjvmrnnpnomnkpioklmlsqplgnmpnwprqpnsiopooptkoqeomopnjnukmwlkmmnikqhnompoplpnltkqmnopluhlrrmcnlnnolnnvmmnonlpngnrjnvtrpokfjlnjmmnmpkmjkmlolmnqqpoqnqslnnqlolnssmllnlponpskolllhenplsopjalouomngqmiomnipknknmnfljopjsinqomnlnnjnplmntvlonmlmoummnpon{ns}pomqmironoontpnpnoronnkspkpnngnllhdhoqpolrmlqtjnvnlmokpmkjjolrlppkohlomonqjonoippsqsgpolrmvpmqrrnxrlponxnjpikorksprpsnqhpnokjooclnnjmnpqknqvgokskojdlnjpofpimkqpvopnnjgupujpqlsqnlukqlllrnloqnktpquimooqnnslmufrptkmpiqnqmsnoqpmmrunnourrhinjomlrqtnsqrnikmrljtostpnpfonoptojpmpqpniporxjfkpjslpkrprpporlnnnolnmmrlnomhnqyfnllpmojlojmrsmmnqsopossgrjluqmimglrmonrnjsmipohsprormkomnsgqimrpkpshqkrtlolqmnqnuoepklniXoowlsyjfimohrnpnrimorpooospol|orljlolpnmppmektqkgodmpprqiknleokrfqrpkinnqolmommko{rklslskmimjrnlgvpknralnkomjsplgrsomkndmnjormqkonjkhskjmmohkrjckpkmkooqmrtQosloonkmqegoqokppmlumnmmfolpmhprkolgnesnoqmzunoknplpnhnmljoxnm}mmmkhposmqqmpkmpmwjxnnkomoljntnjplnutkimhumpkomvgsqplqmonollplllmjomiqilqmlolmpqottklmpkmkmrlsmilqolioomopni`lpmgpnlonkqmlhlsnqrqplqojplokmguohqmmjjkshnllnlnpkpnnnmlljmnpmnmmmnqklrkmqqmonkkuqpKlnqpoqlmrgjflslkooptommoemkonnqjmrumnnsmrjtoqkorqkmonjnolkiunssijomqqoeplnnqqhnkohkoplnktltmrlnokxkkojooknlonmmtlppjnqrlknoggnnpimnttmomniplolojrlolnmqmkmqqpmotqmjopmhmniphkpnoohoomnolikqsmloqmmqnponmonknonumxnolhnnnmiomqnnmkmjplpnmqjnmloltkonrllknnlmnpooilnssonmnsqmaoqmkvmpqqqonvnlgnpmmsnksnjpupvolmpmvpg}otoknlpkhnjkukknikpknolosgmptsporokplnflgomoolpkdppqpplpknonq^uoqpmmppoloopppkmnmoqijornnornmmlhopollkrqnmrammonmqvnrqnnkonjnjnqnnrsmfooitpnnpiknllqllnrgmjtoliokhopmppmtpmrnpkonotsommhminoorimoplqpmmmjnjpkinaoiolmqlppihmmppssmnnntgmqmokjoojknknqougmnnueprhpmopmqlpinrlrknmllnooghlnmoloipljllqontp~mqllnpoipplrnkojsnpoqqljlqommgmnqkqnkjilmsregolmpjnmljlrpmvrpskqpgilnmlmomnpoylogluswnssonsmtnouonopkolmrpomjqronprrlkpnjqntlpmnppqmqjmmmqlitqjmmrtkokllsmjsnmqroonlknnimklqpjnclqldrnfnfnlmsopusnmolkknomlolrlhhkzmo`nknhonkeknnjwonnhnpmlb|k|ajomstnjkopnrgncvippnmssnsmpvim[ktilbpnfpjqllqnklpmjnnijhndsfnnepiqnoqknpnknnjoo`wojqkokrpqovnpdmouqpvnnqmpvnn|pmqohoolkorpqpo{d\sklcnmlnppoformmooljkoo\ghflnpqkoiysootmrfnlflprxiqolkkmonupppqmjtqmussjmlqnhqolomjmeknniuptermsmlnmklojmmmmriokisqjlnqrolmtpnqnjnnoplrrgpqosjltwomkoouoosfnlirnesrpmtkplmmqpljmpmvnkkmnpqmjokqmiunrnnoptolporkllpnjnooopqnqngqpjhhkoonlqoltkxnqwtqmrlgsppmnrqtpnosnmn^pimpoohqjklmjfnmjkqsnkooprkkmqilljjvmuomulhsmopkqnrdktloootopelblnnbrp|nrljjikonpmkmsrnmqpmpgUrsndpihurpjqionlkiobkqlmkppvglkolomhpnnlehkxmoklmoolrkulefminpmormoievknkpjrjinfmillumhognimsjtnnhmkkoilnmkeppnoofohkmlqjrmsmjrvpqkewtqqwkopothmoojnmrknvrvuloxpomqlookpnkltslcrnovllpnrmhlktlwqstkuclnkxpeoltkikmhpnqjlpmpmnk}ponlrnrtrnkkmsjgjvnvkfmhmrlorovklosxlhnlujoukhtqhvinskghmkoomnomemij_qrldhhosopmrkoiqdzmopmnimiokmouoemkkylmkkl|qmkkkojqlpsqptm|lopl_pejoimjulqiqohelqmpmhimtnqmqkndspoqhjrotnlqpolpsgxpjnlqhrrhjhigfmmloxmmqpkpsikkilmrmilnimmlilikkllmkpolk_ipolhepjWkqrrrklpihvjkpnjlklhiqocdspn{mltsknotmkkoriqljponnvqtjlkpsfgnljloepmjorjlrnqyfpmn^pykdkmihjrkqtmgonjjTXopmnnipaoqqdjhhplqlnflldmlosqopjgnnmeollmmfmtrilkghngpiltjnrmnpipinqmkbnmhiqxifoppckfkqni{mjukrrotoenllkvqkgnlmbjljjlmk]cmptuo|iomtlnnnootjkjicjqmnntnkkdlrnwgltkyhinpjnmgohenumwjvoqpornvemgkjakiarflsqjmrljynlhqgbmqhorloih{sunlrptzlnkhfutppe|Vkipijdkjthmc_oojvubk~tqmejplqiqmrusrhsepojoniicqglkelclrrtjjolkdpytkotijoocknoaokowdomvnqsmonvlkmajkSokdoppiolivpyoqoivmvnovkkmflcmgnhtnunplprpqqoofq]mun|fnlomormpp{lopmmkmlohkqleonprqonopmonopnormnronnhjwjnimlpwmnnhnnanmlomtolsnslnnotmteoldnolnqdlptlqppnpulpnlpplwppmryjljpnrpZnpmnynoqorpjqzljqnhmhjoojnrmmhoomqlqtxollqlijlkpqpqznhqqlponpmarmqRkrpkn~kojpnqmnhzphrmlnoopspqmimwpsnoomkpnqrimrloiqmxoujkhlkiolqqumqmjmitrnuloizijnrqqhuqmgqrbkmrdusphwnnlnisqtmnrkmxlkpiljjjknsyrosljrophmnldjmlnjinnmkoqllpjo\qumdkqzrrmimnpqulsn`pnqonpimdwlyninjqmsionjqulfnmnomlrlkpbknoukemvrbqrtlgwprrmomknlvvjqpglpWpuoppksxfnomolquzonevrmqtjmqjsirmnnmgqreowjniiiom|mimjplplkmwontlsnjp\goqpqrmmopokk_pmqrlqkqplomteogpolmtmsmomvgrolpyrhboruoem{mmq\qogomlpnrop{olro{{orn|fnlmpnoldllnblmrlkkqolmnpkpzkkmjmmvoqqkmqormpmanmrmnptbygppnmraiqimonnrgnsno}polnnkluxdnol[mnozhoollosmkqdtnknsjppuqqkirhbs~kitzklrqpinhpknkolrgoooephmmnlmrotlcpkmasompnwqdronoljnsofrhqwkspojnqrlnmnspkgploikqnmlosgnpkqwpznohiolnqmlkqpogijmplnnnwoktjyomlrsjnumnopmqmhkghplnokoolqrknqimlpqmpxofgkkrmkrhomlnlnmnoiqgmuknmnllkolompkrmnqgqnnkqlm]meobojdnmimjhnnpkvdop^pnpozmlmgqlskunaqihnmwomomooogmmpioqrorpnhlqiprnhooqeanmkj^smnomkshlvlrqcloq[drkppgpmnpsmoqnmmesikkighdcmgnipuwnnlowkppohefphlnznqmqpnopzosgpsefjrllpjlmlqztxrqloreiushif{mlnmnqjobomfnokhnnohqllqhscpoitmerplmoksoknslekpoqylvrwqqnookntrppherdyjprmantmigtqmljkinlomrdbjeksozpmtfjomq|jnglknnflhpmhl\jnfbplonvmqtrlppgoqhjriwpmuqllrn[tn~rpo]esjky]olskojpqzrmdhrumoiwkduzsinuyj|jozplqlmkkq`llnqlgvgqtojlpapoljlvcfpaljrf~qntw|{eksfniymskjypknjrlqrqkqqhvnrmmo`iiomlegklcophjrjmlxqtmioghljptlu~qnjgsqquqlipmo]mhulkdntiolunomthppiovforlurds~bbofslnfxnbpunpkto~kzmigqrermcammpmuqvqQsihinrlmonklljpljmommjqllnnqoplnjmkkmmnplmrmjjqrolmnfxmqqoopqjgomfqlkrojmnpdhswvl{ljkqqmpmqplfpvumlkrdojnppplqcojlZrsfojlrvnmrlnmvkmfolmifproqshrmolrnlopmlinkqvhlnklpptolrtlhgpnzloqpmmhpjpsyinqmnpnhisnsmhlypkktkkpjphlmilpmltrlpmpmoikmiqmcppsijpgjjjwqrpktjgkolmoiklffintomopmliqdsqnmrniigkmklnpotqkppsherfisiposm|nprhspepnnnojlrimsghoospdzrnourlminv{juotkZsnsplqdm`^ccikjllpljjpgnooyimknomho_kstokouprjooljod^jmnmriwokhqlingkrlpsomynlnsltcnmkluxpmjnrqgovqfqdmflftnfjrmsomhsqosipsrnd`oorsnhjolnmlnupkmjplomsarijmniqthkpjhmknqiinvbnqglopomno`lrvet{pmvpnvgqjpamrmlmnrzjqoskynpmmyqlommmkitkkj[uqqmilisp{ttmyumnnfjjvull}pkxrp^mlumpxkmmpslekmjq`mjqhrnrkrogkornusmkhm\oclxvxljmkfoomunowmsalmnlklmole`mnjnovmjnmufkkdtpnxpsrmwcqpiishknlknoloompdkkunpdjrsiwk~sefnttlken{k|qnh|pmkqopktqiicilknwqnkkoqjmnoopiigqmhmuqummutkogoqmjlnrkjnkowohjhopkkrjiuhrjhnhniiloomiQr{gnmunrrmsjuonnpqjnlqlbqnolnok[nioqrlqdlgkljkqjiqonpkjlhmrwmllnpqipnmnjsmkgqrpqormgmnjnlkkioidoqfqahqlimqilumwrrklqnnolmmommlrmlkqjmphpsltnhppmmkomooknqkhnqkplqpllojknmo\yojpjpmlfonoqkmhnoknnmkmmolmnhllknor{nbokpsh_inlkspinmnrkngrlsoorjn|oszla]nqmijgujnllpsstoypnnqmvuppooooqophmgopmnpoqhlokqqlwlnnnlouxmmpnandmmnjonqmonoonvcjlmlpqjrmmroh[kasnokmnlg^kniclnmmphljsromsoixq{klflmiklfoulqnjkpsxknnrj|mpmnfqnullkoqmqzlln]mglkjmimopn`nmnhmmnojkdmkployqpsnqonlkpmnmwlmeemjrlYlrvlencnlmkto{oolrmkklznwvoofmmqgtlqmnqnnelhnohnompmtnnorkngtsilfpkhqnqkmsokmunorlvrlnklgnnknmmsnqqikmkjknool`donmqjncmhnnqnmnq]~rnophcxnllvnmnohimnrnnznrjk^hooqzmnnnlpl}lnmnpmtxrnmhogxlzopjnTjvmnsowvpmljprngnmoulntontmjoknojmmq|enmsnnwmllmsqdkmmtipqqqnoqtnqulolgotiqnouksnnplmnolhkgfjioxprhkqmqoiqoksntlmjfswmnpr`plh\mmtnnmnoemornknojwsppmklummlnnotthtwpfloe`knkknsyollqlpvcms^rtqnvhtqqlmhuus]pwwlknoknjxionokspcklhromlrklkonojjiknqptlmlvltlomkojdoqfm^gmuuqoooqlgdollkqrgOhot`ejoi\ztgnmokp`jggopaekzrpgqfssoomjnkhjnmbxqljtdprlrvkprpnnkptcvl]hltmckpvj|kus|gjoidhlejlgpohcZgtrmlr]k~nsoonpmoiorlfmjmjlnnmqogktmvokrhppnx~qvllertmqcktpijofunsfkmq|[nmnnstaeijuibrvrUluprnxn[lqixqjmgsligskknlPoctppsigphlitjtz`kltjmrwmtkftpmpnknmkqxolpgopnsepkmnoqlypprjookrmninskqbepnlpgrlrmurmnnlnppuokplpnmnmpiomnwlmlujkstkjonvpnplltaitpmoxynnjrrpqugojmwmmrnolmlolhpoqvoinlqlkrkktonmmspYknlqgnkqiskqqqsmoknpuslhnquomnjioxxrojojoplqrohpknpdnklempkqlrrmtvqmjlmvqmlhpsmvnglotkontksonkmommmolwnpollrjnrplmppXjonomkmonojnhojfpmlppmomoocfommpvmmzqi{pkmnnirmromqulnmjlsqo`xkpmofk\noilonnrvngmZdopdj~mmmoomnuqkmo{kpomqomwmnkkjosmlprmqUuornjrrmjnmjorofnmsnllfnlomknjqhuodmqtnrmvrpnoqjssipdnolrkhmnonogkmtuokjrpiopqoplmnnfplmpnplookqoilsnopnvrmoihlmkroornmswinpsqqlstomoqskiqfqolnnhmolomlnmqnrpokopkrmmonksrywqokkojjionboqsnompttnnosqdpklq`lkftnpklirlplliplvkrjyequlnninnpmqrmkmmsolnplpogjpmhonjojpmmhgrmnonhmmjksmrqlnqmmtltmmmmmeltjsrooongopitfilpponpftnpqplxnsmrpnjpgmislqnowqjgkpnunlnnkqlmnlkllkjkonnosuqknmniorpohhnpnuqtmkkjosokjhlpljmnmoiilesihojltonqnqbkfertmliqmllokquxposgimhqpmhloqulnptlnrnhnlbflyvitlvqvxpmuokgoiqhokqnlmpipimnlumpeptopnojfmbmrnmlosqnprjymkhiimpnmqepkmiwmqumjhmktpoksnhjhrsmboulkkrpotrpfgjmiplipmllmhnjnmmnekphotilopqflgtkpnlkpktholmhqqmtotqokqksjhlpqgfhnjahnrWrsoslgmkltrn{iqannnnnwumuuvtoiqqrm_vsqsulpsfpmlkfsumbwoklqljllpnoxqqvt~xbpqhpXs`jtmmneowoTnuzmvremuos{ftppkssmlnbpxnjrmprpqwqnhnugdlw|qjqrgdtwpvs{tlwwnf{sqoeosTpnrzcgdwmotejho`psvkmnhnjlexriorsilrjmkqhXicpkktnnpnztmkxaqsunoppqowhmrtkplqroveclillnkolrkqrllnuquknh|cjoimnrispnrlvlnphmrnknetjqojplnncjplsllqlmpipopjjpjnonrjlpmhqmutlopmktlponqurckopkqukoipovjprelmnlkjmntlcnnlsvlmmnnfo|sliipnphrtmsmtsmlsonsflmpkjonumhgpmilrmjslrlompjoirjqfqqpjtzmolpnpdorkjvnyokswkmujhmingmjhnlotmrkrncgllnoirpmqkipznsiqlkhmvwnohvklkipqnljqnllbmelnlpn{ovWnolpnmhpqn]lgrmomnncnpclqjlkbl}owmmonlnmmvitnoolnqkookpojpsjjzpoomlfngnnomingiooonktkummslqrsmnqnkpgskroto`ronrmis^pdkankxmuffnqrmqhtcsmlnonlkjmkjpnpqsjnnjrlnprmlipllZmqnnlnqlllnmpqmnvktqpmuxmlipgmnkmjtjhqjlhplmqjpmmvlunrkjqprcpp_omeopnjnnirpqblowqgymlsrkepgmqmuncnplonlqkmnojn|jkpxkkltoojolqqkumvrffnmnvlpkllpio^uqlilvsvlmimoepopsmqnsqlmnqhwhoroin`lldnmoornjhpp`uomnpilcjuqfprlitahvnlgll{hp|fmsmldkjnrqsmmling\of]nponjmgknlnnokolmqonoxnrimuppuitoqmptipikdpmlzulrlrlkprkqzfhmojkof{klptqgmmijopk|olnqqnqtllrmipqxnrqnnlpmsmrnpikvrnqomjqrrqrynrmbilr`nokphekmmnvrfmopvuwljjolfsoqmvnlpnrkkonlnmqogknjtqjksorplylpvmopmtlcgirjjj{yyjktqllnmbqlhidlimsumltomqjtonhkrnilmjqypjrtmgkegjruqpfqgpnmnsqnonqjllllkpjnliqslpolhomkpoufawospfRhomuooyrmrrvgqeimlnoiidqjnwy}wpnkpqwqmxjiinhikqrpopok`ovkominciboaszdgqunjnkkflahskfufnqpwsmfYjrhyqgumn`}nflzhqjmvoiniqdqwpl~d|gmnlourqqmdTpirjkoprnujnjsrd[dpkpp{imlokljlklonajlpojviligplou]skblkemxthioipw}}ifwnbjtpmzjls|olmielkvsqqosnuoorpmojnfkoqok`unpplornnollpokrqgpnokmkhpopokylkmjqvpqqrnlsgik]nkllnphnoolmkmrnnllxqmilnrjdojinjqknolylknmmkloklmhpplsotjlosopqljnyluholmgoynmhoqowntrmkopk{pnrnmofnmnhlnwkotommouikqhqlrok}gutlnjonlkg}qoor{doqonltmkonmi_kn~kmvlogosomqlkomopnmhiqqkjmopnkqmjjpkpkpmnmmsljpojqqzpfwkfmqklokovnmmlplmnrqfojqmupojvnrkktlnms{rmqpsjqpkpompmmmmnnmpmporomiiqqmprjnpgmiqrpmpjmrellqgklgiqppmdnqoqqtqlnkskvbooojnlnniuqmonipkqhmoopqoimjpnlpppnmqnlioltigppqqoshnqglmnqjirkvpingqnmsijnnkfsmropsopkomqkpdmlsjjknqpoplwsokmpipmmmkiuopqklpjptrtqrmlklsl_mmjvvhkkhzrknpqjpgmlnnkqdpspqpprllkgfprjskwncwkjmlspjjcgoqjmhvlkplqcdrtoskknukvohp^mlpq{sq|sipemhknoatjqoivkoroowhplgl{pk`mqkjnsklgpmmnflsxksqvjksmkkkjlpngnnhstlksilsmoekqsnomuijrro`mnokpoup^t~mlpmmhnjpilhonpmtqslmwgqrmgospekhncljkjskoqkplsjipxmpmohmcnkadqr^klmkjgxipopkqiokorkfeluonsvjwlpkeorrjhlqkkllftlpvijulpifkwljnajroofithippumkderwmnqnypjqnpnqpnnjk_glolqdknborsiorilortqftolggmioklelnippmolmq^lupmmlehelgfmustfrmllsgkooicnsmhigmqmppkkkoqf~lxhttefvinohrfllqmuiqkoggirisjrllokpojdmpnmhggfnqrgmqkonkvjkorjvrnrmqqnksynmkomdlppnpljkomippmjkpskfihhjltpokvlhlftoljtluhqjkfprnpmlnmojujlgnkkiinlhffqlkqrpsmfsjofglflnsmklom`irpqyoolgrqjvmsrkvomrmklkdgomknmunoqhuqljhtgnqnhoyrmgjhquvnoqlilksissntonrinhmpskrumrmnqhlkkelnmronstmmqrlhmkvxojqllmmllsofpmmipnojltkmhdshmi|yg]]zmejhkgi}pnnho`jjpodj`d`jkqvpunlmoqigpbo`kulmmoeprmtjopdknmukplnhmomokxoaoowkddpuptlldmpenrrnm`nmlmpYnlnmpkppnfjpfmlqqvpnfp^hrpklnlnimngglpj_pjlajkmmeihinjpsqnmmkjgzqmtlnqhqtzl_mknemrlhwyq]wkwolpgnllnonkmnqmpklbrmjkinjpil`llssrolpkiznpbggk{lttqgqorklnlvfklmknnqomqtpknn|knrmoonmkklmigpqorlwuororkkqjmmrllmkjnojonmnkmjsnikkrrrmwhpxgnngufmswnqkgdojomoqnhonmlsmmbpslhnnkqnrnonkilnjjpkqnqkloqinhoqoirmtjoqklqknojfxmspbkm]oirljqglrhlloip`omilnqmnmkqmliqnforlmjpaknqrfokmomnnuknn`nmorlojsjzusmqnrjnoptsjpkeqlqhlpqszxjppgjowesqcmfjrojskioficobo[lphiepppopurgsr~jnnktpwqigdlncqvugnncrnkojom~lyfprnmjduwxouerkroujmxikri[mgnksnkVqpkvdonspkn{gdpmjoonloltlspmfpgnlmqjxsmlynsmooilrgpmnulunknqmo_ujnljufvmmqfcggmbfkrlpprmnnnip_lmppcimheomqmesmjokwplksmuspahpkkolfllkoppjulkvlpkgomwpttulloxpnlciqimeopnffkinnkqgyppltpopjmjloonpmsmnk^kmpnxmojhnlpmdhqfpkonxgolqrqvqpupkflsbtjhporrljpgqmqqmnpqlhwcpnyqloklqpkopnkmmsjtntkkoooctmmrphlqmhmpstolppghqnnotjlnsjmmlnf]pqnmnqpsoniloinnkyuppuowgnlqfmpeihplkjhrfyjlnnoirmfmlnwbgiolmrpzjqbmqomhdsk]djepodik[^hlposndjdhqrgenjspmuymmjikikgnmnoanslhnmqkmktjrgepknjgXgimjpkv\lrijhatqqpql_olniqioidpjNXdknencmlmpmgjmjodumq^nukfcnerkilfgfhvlmpgpnsllsiandlhnpzumonmhnoVjsmkBrsrffan^hgkmiglq[zl|tltbjepupjwnjjfjhcolkek^unifqchnrhumonvzgpnilhj|ig`mkroccpkndiiifjjnljmkpgmpoqinnnonolnqjnn[poylnrjwwkkdooopponxkmqolqmppmltpkpks~jnhxnosrpolqmojofoimlillpmpkvnxlpjiwkmsnpmmqprpnzmqhnsminvniovnrlijlljpmopplllqlgllmpqmlpetploynpk_sxmmhgghkykfjnnnqmqjpkhtonflpbglvllkrmpnznmnqlplfkqljjmpnmniqnpgmqpfgjpprpprsrnlykmklozfrqfrtiiofsmopnltpunmfem^punslqpmmqanlkoenqpmlmpnunqokmjnjtnjlepiwrvxoiq\lnmslghgqwvjopzhjplqyserlmnodplpovmhmlllsnqnqhonmljpolmgrqlrdhrqrqkynqljytrhknlejojvuhslvonpoknvsoikrkykkfmntltlpskuiolhoqojeoxalfkoventpqrpuqhliwqmromkniqaqqjemklifnwkjuu{imloquklfprupqqojbrpikhotlsokqkrnowsiplqjmkosnnmjjflotrjpsrsnqrwnloemoohopmtqljnppxoro_hdlfnfovomwwomsuikpunmprrmomiqmlmmnnnqoo}ujqrdkolrmmfkmjpomjjlnmmnsjoqlmkoxocxtpqnnronhmnvollw|nieknpjeemllmmrvqprnsonlomlgomorlanl}kmimvrrrkwlnnpbogororljmlqiupfqgluokmolsfqlmrnqkmqlpoullponsnnlmmslrpghmppokwprjmomolqmolbooomlnollspqnnnuijnqsllnprj{ppjknhlsksukjmpptukvooksssonpplosjojpnoqulnlqrqlhlmomqqnllljnlmmkjlulfnqppppnqpmpumnloumhjnvrvqojljenmrnrrmllptmnpkkomohmonsjnpllhhmmpjnwjpmmmqnkpmhkpioonilwqrhkpkpmsqlopkplllkwmkn`kkp`momoomloklnnxlprnnlnnominjfjnmohrqdgkp^qanmotmpmofmloqnklmilyYhjrhkltluknsrnipo}nwvoopeljrmnnlld|olm]mkhoikmhipmjmprllmrnjbltloqlmoqnnoolmhimocnmm|onksmqycmncflzkupdrwkolgjlmhopmmnjknlvmnlpkqwfnfmgkjlpmnoomonmnklotgmllm}wkkn|omqbvlhxrtupjjdldonrjeqkpmlhmomiqoqsimmjpqpjqpjpiqloprnnteqqnqolqhlouentmdlnqrrojlwmlrlpmjohkntpjxjdpilplslomlrvdmkqrqtmrpojdohwjksupjtoonjwvmqlroqskommojkqngmtnjnmkqknpmnqlnqtlnonhglyrppwpj{qejgleknpkkngmeuunothoopmpspllvnwrkoknpomkinrpokmlkhlnnnrjonompsmokhlosulbipjtnokat{ilnqpienkeoimmmisnpvuqsnplglnho|htfkkhymvyrdnhptoenky}pnooqmmxuqiynhqrmfnkkotmmlulghpkmlflvwkkisd_uhdoojlkeoihapspytpfhsjqzkukjp|lfrhsidginnprhfgpuiqomolgrvjsmishumkfrq~igwpvnogqpngcsnpmtompmipnwrmnmlmiklnjkhrpgqfwu~rqjqxllngpjpp}qzklhqnoqkmudjksjnmohuslgjmpomglodrjomjqkknmnhrlmopmoqpmmhjknoqkqt`ojpmlkjqepvsrnjpopogmhtoijjlkjcmmohojjiqpmrugjmgokmjvoolmqnqnrruotitfqqmgjlrpjojsipplnjonjnjomhmolnpneonkmpmiuqjpkpnknomqmlkmqpqhqvolrqkifmqdnllmnbomkqfqkkmkjopkunqklmmpjxlkxnnnnlomnvmgomppmiikmnuneskhrrsekmvkkwpppmo[iojq{nirylmmtkkfkikko`bnpoumilnjtmpiqkqnnkmjurrpsncmpmfuononkpmonlrmlonkoonnuunlomsogenvp_oommqYooppsjpVosnohqoxllqpjtpnrqmqkopoqlkailntoslollxnnnjpnpnnnfhnkpkir~puppkjompxelgpmpnmpnlomonloklpjmnojlo]onxorfnolnpqllmooqimnuoolrqwnmnmjjnZs\omonkmmfliotglhkcrlplfimoiqiojmokpniomikpdokiksrknnml}pgkfjkfekpvkmkooomlemyixqoilonjmkqhdlsofilugnvqmo`jmwk_prjnelsillhklpjijxptkkmhlskkioomihpiqioyhjjnonsoimkokqmhmnnjpmenlmgmllphjssljflrthjrnpkhq}njfpnqhhnpjdsnmqjlvqpsldprtusnyoomqhmklnqmqnorulojqowptqopnnmsugkmgsjmmlmmrprmcpkmqnipphorowlomnmofnhoprqnjmiiorgvpsrnjplrmtonnmpxqnvqfnlplipnowlpopkqyefnomrlmkisthmklqljpllqlphlthnnrjilvkrkm|klqmrmlrmpokprjmolnnloekmrmqprrpjtlnupmloppkm~hnnmpmnxtpplkmumtfqremslnofomjlmmkloiypxtkrlmjmlpqjmpprpmmslonrsovohojrlmmqnlnnvenlqlkekmkkqlkqnrqkljrplnomqlmusobtmonsokmmrwnrqpojkfddrslk`qoldmmfomookiolnonieiqnnol|wkmvloljrqkjhlucqkkvzojmpnqnlkqoejcnpgmfwqnoomrfmkornnoonulpnsnrlzmjorhoirliipsemnmullkiljmknVlehijulnlngfknkumronmjmilmxoxdupjuljnorsmpombmlonmnqvnlonjjmpjlhoorq{lnrlkmgolulwlnppfknon_qopnrjookmelnrpnenploonqinllnoyxnslm{ip`rtpmsopoolvimsommoophmgnromwmrmfnmmnnjqlsimtpmoknplnjopmnnotlopmupjxlkqk`splmplehrppipbo}vnindlhpmhomommklgnp`qnmnnlpsknorqn~nnovkmnnoji~nqkfnqnrqmpopnnoeksuvpkplkolnlkmsnpolnnmdmoppigompn{np^bijojincmqksipomropmkrsnommtlpnppompklmnjflinmlnqnmrnsurnmmmrttplj`omkxoomjsmripmloonm_kiomfimjrzwkrlpkpmtrqljqnmnixnppklkoxsnljwlkrkoqpormjpimhkmonpobi`loonmoumpsllouknmjoobqnkpnnpkinknrenkqlsmmlknllllkorpowpnhqnolnrZ]juilrmolqlmnrnnmmmonnlomgkqinolbko}mgkrsojgpklnrnimnntookmajnnmnpoeloiltqln[rnkmlnkookjnpjnp{olvksZjkxlpntmomjlmprqjnpinnbnpnkqqmfoxxnooqompanopcrnpnluoposqgmuppjniooloqglsvpmmsmpnopprnfiolookomnllpmrlhmppopivkmkmlmkdvtojllsmnnmjhrlllt[ljngqsnsnojioqplmrjhmkmmepoonnqnhmslmnnklqmn`mdkopommodmoormnpqpnmtqmgrfprnpvjlshqiwvhrfsjpqmnkhqlkrkliorllpsh{sjsojmkplnbjupplolrijth~jolqfkqmimllvfepiu{miognlstwdngpryhqtmqnjglkopnmgkssqupojfmodjlptvltjmwtormmjrnrkponqnlmffpnrkrluifgmhoknrmrnmqpioilmgsnmmkgvkmmofsoljqfcokqrgfspmplqnrqmoopllsl}ojnsloi~kklnjuljqmutnoliiggniolomoqprpjjmkokonrolprljpmnvmpnnopnimsoslipjqomqmnhn[kslpnomwknoljmlovmlmot\iosmmkukhqntqoqlkqt|nnoofqqjppspprulnnvpnjjimm_qnlpfiknkokjnlznimqnqojnopoophonkmpoptmnnklncxnltorzmnfogmkmojrrosjnsjlomnfqnmmonaevmnjmfqlkmlmrmnnlnnqmjllkdnpqonjomenopmleconlsnjqkdgjsrhenr_wljyfdliihxjkuerporrvkrsfgvmpnqvmttqhnjsjftj_jtossiriiiqtpsqqgvrglrerprnzmysurolgfsuvqlogpzstrgvmtkrfdpojqtoqmndpenlp{mnj`{luilnisjmqhqlcnpdodmiqmusjmjedtmpoukmlnmsmpbfniocpkonsjidmmjzgnkc``qrmojrkoppolodiklpnjpgomogcjigqg^msmms|qrygkklmtoosgopp`tomttinohnmmuhjxvvunooomohmugjggnrnmqfuqhnuqenqhjsmrjiknholrhpnmqntnrqillpotolknnspoknxkdpqnsspukipkoyjpjhkoklplmmmmonkkkbjpqnylprkvloqlnlmnutosnmumkmfrfjpmogpliqsprmpwp`kistovlkpbulnfkimm`jmislpmncvmjllnktnkijwjipiprgmidpokrlmjillnpmmqjpmrnrmlkomkpmznnrlpoqljnnhmkkloqhpilqtenofqogoppnllilnqhlnooijnt`mbcrpnionlgrponooqmpkolnx}litoqvdnt}orqpnemzqpisnkkvlmmmkhkdgoknjgodlprkdjnosqmlllmoonut|gognonsqojknnfmqomppnqlsnnjo`xjpmpnSowjjkknpi^uno_qonokgnqlklkmnliw^Tqm}onkqmnlsoqnlqlpmopm_pikmmnuqmvspprpxnluslorsijohlqbqnnphoq]poindilpnomkkloznswowvlkjuixtxfwojyltkjrsmppqenikplmtndtmgnmromdqpqnxoijoplpbpeoolrj}uarkerrnltr|xnnmpjtnkqplsskmodkppjilirpelmhkrrolotxn}ojoeqoqvysvlmlhkspylsoqnpnlpm{nkvogipxtqgnmnsnhoomskqpiphu\rnomyosroonlkrpqkutppihjsqqjjpgmorncmkib{oomotmqtoploojnopnjk~nsknnqjnmnnkpmoqpotmppmizqkwnsdnnqpnkm~hnnkjqmjholfn|bnm\qnovrpolqnprfksnxhomsvboonnpnrciopuenmjomomfsrnqjposntonkbvnmnplnnmmpppsnrlnlmoqrhnsmojprizmbnorkllkpnlnnhhqqhoqmqmmqlqvlqrpjqz^ienlerrfjlsluorlorokvooocnmplmkkonpirlnijkgrroiqlgjqoxhmlkskmmzmqnpmmmpvwmormqmqrpphimmrykposn`hlqlskoopuokohnnomqposommvnrqojvngtpkinlnnkjnlmsoqmpuigmqqmsqisknmganqnhnpkljpmnclfnnkpqpddiimrmnkhmmjmlnknrlnunrlkmmonpngmunmkmq\rjtqnjlnipo_jpqilsoknlokoolflctspooqrsmsmmmsksmlmrjnnwopnolpsonuuknqnpvanhngo{nqllkspuqvtjqmooojjexqkonomqjplgprpvntkrmqsoinelkmnocpilponlkponipmknmmk`luefdjqfttmmckkuqgrlstsqqkqomoilhsmmjlogkbmsojdrmlnqqsjnojtlrmocmpnmlnyjwpltkhljojhppsnxnsqpnsgsiqrpq~lwmcjvlnj`lsgopnmqmoononnngpreteedkpojmslqpnonrnnknsmjmkqdjwllqnrlhrtrkmksrjnpkrkrkloqjsmpprtlmslqumsemnonmsmgnotnnswdlmpoekpqsqplqzknkmpronnszmlmomnjloqjlhxonoqsmjjvioonmknqqhxlorjoinijlomukqmqypkoapyokpmoqnspmkinlnpngoponmhominomvlxqqpsqgqwormmpritjlvptnqnttprmmqrokokcmriqrrqruhmfotnomjnrsgmm^likkqonpllnmoqpnmmnmqojwqrvnleiooyklppjbnupmmgrksojpolmnsohqqooslmmgoojoopoorppmqibqvmlqpjvpdcrrnoopoopmoipmnqmootmfvndruekognlpopnszitscnomoiepqqpnlnpiqhrunlnmscosjnpqlohrolnowy|rlnjnipiggdqsmmnrnpoqjopqphmowwlpfql_lkwmmpnnpmigoj|mpnnjnonqjqomqleojriisnomqplosltlonmpnnqmgoslnnrlnm}xamonputnhgnopdgpghssmlnriflwgtspwafqpntlkdpnh|{hbhammjrtritxzigip`{jonPnqzxmnsjiljiprkpqoqtrmjk_nrllrsj\thmhPmtTkjf~ctuky|udjvh\osnojvrjqbprghuovrpeoksnmwsagkhtjnenYjptr{xionoomqiuppfpkrkjlimshmrpluetvjwlhrfjelkojpaohsuxql|trmrlpnlqsjintrq|njqiolptoqnsro}k^iNqsgnjtmpcqrbminhonmlenwnplrrjbqjkrrljjknmsmqkpojonkjrlfpupoonoyunnjqlohhnnljpnsnsrjhklmp~`vmnsirqskocqttolnjpnorsejqtpsmhrlkmttmkknnoqkgmiqqllolrelqvjnnsdkepgphogpmtnjljnmsjmkknpeqqpdjv_ohjmportvptkjppnrwojtpsovkqojhgnlonpwqfrmpoilkrknrpipmyqvkgoulqlqsnrkqmj[rmmrrVnpRqgesqlopikqorlommcmmmmhnqtoogrelksmwmnnmngjogknmgprltwjnkpmooiojprmpipohlrlu{qgtrlbkpkkmetllilajkonoglnjhnhnngkmmibkomviopvxkvnqnjtrqqebprskjqtntniljlhfhntoqcx`ptqkljrgmnpqqqhmgflhbbqrotolianozsmjnruirym{vonuklpkzkri_ukrisnqjqrumjueptqqkwrmmoqaiphowqrnnomll^kqmiontpkrqnd|ovpklnnhnrolxmlglgZklikllkxqanppipnvormiqlloppportftopklmuoolopoohwqsnnmr]nloqmhmqqphogprlrktnljpmowlopllglmYeluntlnphjpiornpqsmqmowdlnqgmmsxsmontmciloillqkkcineenoojvnmpqomprlgngknh`rniiknopnppokpnijmmgjrmlqo{ons}pnkqkiqpoolnnlmolrbllqfilpvjskgilimjolnbnipnkollilppqwombkjfpnqknoklnoqkktmhmplmnmipmliioijiditlnpornkknqjholnpohelpnmikkirmlqWmlinmimcjmmnhmrfnqqkld{shotlnnhnpspqpuolilnliopprlkbgxpcjnomionjtlmqjp~okorqqnkpnmlmocqhsmhwfvnblojqmpnqmqmjlrmjlqlmifqoilonmnglonqp]xllqzmrppgnyilln{tppxkontpfqoqknoikq`nlnknkiqorvojemonnwzpfpmotollosomrlpplmnkhnvpngkpposskxlmqnkmoWqsgmkspconkmmumqkjlmkurXlivnfdsjompkmmqnlmhnigmmonlpklpomkjnqirolxhlopnnrkjmnkkqilgqdnemmlswumqknplmrmmqmmnrqirmmnnoqhnmnmllimtmnmonroookiltnlqpplxitnlmjsxmomoifmpnoynkjmbnlrvplmojkpmkmnommnoonljjnloppvlrcmohju}tnnlmompoynnlnknnmoondngcpvskrq`hqoqnkjplorpoulntkknmkqmnmvnmonhnlnnsmkvmltrgqkjnkjlninzlmqqpndonpqmmnoonkonuhomktorirlnnokXpomqo{nmnshgrfkmlnklrmpenmplgqivtkmqzlnlpmhopnjmlqoqslonwenlpknoknlgmlrkruiqnhgpmngkoxknlprkqkrrmpkqjfoomlnmmsmmomuimolqopmpomprymmoouphnoosinvinpqssnjulnynqnolp`jormmrmqdmitgvlnjhhpnnlirnvdpjl{nispimnkllqoonklmollnppznnmkhmsjonmmpompmsnpgjjloppiijml]kpkm^owounnplmmojqjplnnjmlroqmpnkhlopiimrokporqcmollmnmpmmnsokpmiojnoxojoljmqyoqpromrlnroplnrgjqmoojmpnlwpmopnhxmvmonnpqtpnnnWmmqqrknzqx{jnnsnmnjsnqrennntnptobpqcfpjmknjqpnnopnolvwljmntoolmnmqkfokimooqmnmottoopzqilqqlon{rmogpmistpikmpqrnpmpmh_mtmtjlhnsdmmkoe{jqgmnmhkjpqnhmposynkslnnqoo_icopmhqohojnnjoioklnpqlpjpjjomqnjpne{]nqllypqhqksljqlmninpojonopnrnokokpslnnoxo`kmnnorrommhkllolyigqurbolokntousommnnnmoontmmoepoiginmrjpnln{ltpsfomjpumplhspnlkoktyqocqjjpgepnjjnikqilrooi]pmjlppkrmkkollsnhjnntwmmplpmfkrlrjpomskkrdnmmh{fmohemqlkhkprknjkrnvbnrlphomknnsqnnqonpnkmpnpmjfppgmkloslinrlqjoiirknpoauonokankfmjjgkjksgdpljlmqnnqtrmkm^kcnlgjkplej}mlmljplbkrlsnkpotdfmohwlkmgtfinmhppkgsmhnpmirkllmpfmzlmngqknprmf_bsnmrcjsfyokqsllodrkhgllnmimjrmnrmjlpessormnqlsdgmmtpnoklrdnsolgftginoh[qnhqptonlosmhvllyhmxqornoluiobonllkmpll`mioskfknonojqnsojrnnkknnkgofnlstilkqnmipmenioneksjkmqckqqjgkpgrjubqnolqwyq~cknhrfoXajtiroclehowjuonnpflmllwetrorytnripwlomiry`nngppgttgglzpjVh^dqufhphhsouqmnuksfutlipnpwflipiiurlsklke`kpkorpqhjlrqotWissrmuloomkgooj\pwliatkoklahmqimq|nrpmlgkivpomngpqxmrjqnyn]flki|lomwnrnmqj}qphdtmlnwkrmchljgnftpgotpxq^rpjkfpsnommkuhsukoneptqmorofkomfp_nshqksnmlujool\knpfnoonpqrjjo{nrwnnjjukmiirr}gjdrjhelklpsqmkonplrnmvkvookvojj{pfglkgspsooklkvxo^unqsvodpwsmjnurnohnqjkqonnekfksmuskjqiijmkononlsohrrvlvofdpvilqpmooturjmfjlkltjoqjqlsllnnrqtrmujonnvkiputnqjjslppgqpnkn`llkaorkoo|mnfdkzmloljujmojfrmekrarmymq}myrimolwrnmnlqononmrnitozplhjf}osmpmnmak\tgroolukqrnnmjnknvml`olflorstnnqoqmhknjnloajjoonotmhmnmmmkktooinlgalqmnqtsvnpnjiknwpglakoqlmdopllnlkoknkopkmqoj`pwwssqlnolmkwlolmklqmknmgslpsnlnnnexdnqzosmpkkhvkqnpnlslnlfpslksooppmppsplmoklzononomqpppqqpxllnmwwrr}nqpsoumhnmhghnmmpnokmohnlyqncygkjpnlqlwsgmhfopjryqnlopiloqnq`mpeqiolermnopokpmhornkmpqnyqlmnnngmmnomrmoro[kmqlonlk^gn}pozlomllulmlm`rpsvlnplhuqmmkornjrmmkrojqqoonljoqopolmooiqnotirpojnmknlpknjotystqnpsouklmvlvsomunpnfkpogbglqkkkukpnn^noofwimnjsiopmmonrwkgqmryqonn{kpbirnqjppkthmglrbomlmjloospzokmrgunnj^mhooqkgnrmmnaulrkqkoonkitkhnmptngllfqlknifoxqtiiloltoqojsrttkqqjskonovrqginmrosllpsojpmpvrg[jkoqksnimuokompnimojqisrrnlkoifmlnljmpjnrgjrprjuqrqjklskjooorhjgclnojolneklrithohfowkjonlpohoclriffhpk]lspoklponcq~iqdqojjpyopfknskinouhze`rohkqlnwlpzupnhjz|btplochmshlbkirmncejllokjlpjvkffsnhoonmjhsbjrnklnpemtlipmipjjnouoqkjijgoonlr~jghkroiinknfZkfokpejmqkopdqnfawmpnnqrlhjsmxonwmemgjppkgokmglpijkjtltruqhhptkpmcouosmnrylpqpfrmfillsomjpi[sinkmokotrufnoogjmpqlenmkoknlpmrrrfoltkqoqriplol|kulmpsmmnlqpmjliotrjjplfmpmouqqikpprkslousnloikplnoqoooplosomlrtsjmuoprpjnbsntrniqnnnjhpmkfmfinsnonhoisprknvqojolllmljoq_vomqpqhrfnnslpmrqoqplrwionloqllsmoouptikmmespmmmskntmpropnkloonpflpomjxnyqXllgnngmfmmpmlonhmpmogjrjqqohlxreqnorjgqvooolohkoonyYvsiclimportipnknsmlsgoimnolkirstmnkunrsgzllpchpgneljixlkmnhimnumponllnmjvmwlklmnilqjoqknpjpnixfnnjfodsqppkkopylupqhjmnuijxhnkfnfpmrmicnippknsfkfqmqhn|millkqmnqjpumnnngotopsmronhhffqtolgtimhmwmjmm{lkloknrmhpkniljppqpomvomqlmniolomnrlfolroiq\wjkfmmqmnqnnjnfqrmorropnlipnmlpi{tpoopqqmpokcjqomnjnoiplnqjmjmliscpnolklpnlml{mpulpmlp~pvrnkpqn`riolmomnunosntrokpionxtilftr{nxmjhgjmrnjqokknlnnkjmfnqnmmfsmvwipkpstoroonqnomnmmnplonpjjgldndprsjgkmknnmmgpgrelknjo}lkopmhkokpnjllhrrnonrrptokooomqqmmlomjnnrkpknmnojmpnqnomoolppllkllylliikmtnmjirnosppnngxwinlnjprtjpomjninslj}skwommmoforsklqkljklomysoimcmglnlmnknnoofonneomopohpmooikoglm{oowlmoikfohnlonmabmmnppuoqnoulxpr_mmmqnjpdnqkolnnpinnupnknhmdrnnzcqooshvmnlhundorxnjnphx\uo_omdmnmwkldldmlntikkerjsqutsukaunonpgplkpxbkhpmdkpxqqglsuumxgrj{d}uljrXnxrplkl^c}rjjqochlnlw^cwdiupnrllemtplorhjeiqqgkokjfimmpktfmpsgqmugqlpmkezoklghj]njcrgjjsqnqmgvtholupgxliouimqlmektoiq^jshinilrdq^_lnjkujrekrlnroljinltnkiiefhrskk_sqnvhhmuhrifmlijn]cgohmjpzr]rkmjnsntnimpmmqmkmpkojqqjowmphklqknnnnkonkbovridopgpglmrhqooloodg{sgpletglmrsoolrb`hqiqkj`\qjprhingmoksnnqgnqnsckckkqonummjnmjp^o_nhnrjnkleemrnhhmmiloerohgqdpnlfhlofmvlf\olphgrcpr~pxqqmnilknqlrrjdimlrrplnojgslspdqmmvoljruksksvk`nfqtlnopkkrndqejtpiklmoqhhqjrpnonkmoqmmoomllnmtossjvruekpcploininpmnukiojomioflj[ksontevnppnulolnlgoktlmjnhlmrpgqltnoflmrr]nmphfookqglrinpmnrhwidnnmqmolmpjomcmjosroqlpsmmomjjnphnbrnkhihtrlmfnkrlkprnoqgnpikllormunofslirkbqposlnnopimiuiplmmrhlrmhvmmmknnuopwlmskjqjmkl|pqsmkjmmwnnlfnhrnkunnogliknmmlmtqmkoirjskdovUokokmmoommjroppsllmlln_jn|iq}knwpskpnvuplXlnwltlqplemqmqpkngqhklqnnsoqkr|pmrqtmjjpmmnohrlmphmjocpqhnmmpplomssmsopkooqhtlomh`molppiqmnnstln_ppmmkommtspknjlnuv_rnzoksojmqhmpnlrmpmjmkrkvmjqluolbvfjjqlnnpcr_plmjmglvqvehpkncplkmnnbqlrnoktolnpkqtrolihfvqljjo{mjbmmilqennkixnumolstfqrijphgsmslhmorrjqfvhfqjutskpcrknpnoprmstmdegkqmtrlknsiioqlnzjnkknsnoukonqmvrnfnducgllqmqnrjtsnnnwionopemmnlpdwklqcpgisixjfjkimsnlntqmjsnmmnoqpjahuutpncsmhmh{ogmlnrhlhwuvmlzbqxuptslmmhtlqckmujjmjofnjjlpppqgbmlmkosoioonortpbmpfpskdohlerhfnclpdorqohdpmnlmnrngkfofpcoshntgjnqnopqmhojrkurfisrkljnbsmopmenpqmeiglriompijpmdllliqjrqupmnojsiolrrnonpnjkrjwnjnmgrjknqjqmclttrnffonkqnkppjgponilheqgmsnpernndfkzrqskqkckknipooycrfmpjxmloorodrppljmecqnkouuojmnvoqrtojpvkrl`lnomlskpmem_pmnpmjqlnofsjjilljpqm^onopohiltpqnomnmilmjoobogrpnilqokllpporiuqi[knppgnlqollnooloppkmSjdtjrmnlqjnkmloinncpplmfkjoksmnploqommkopflmpsrmkocho^prmru_nkrnonqmmuqmnmmvmnplohntjrmnloqpnnsqnnkpmpmrspmgsqntpkhmimhmmktnmnolommfhlhqiiqmpinqopinnmmknkmkemlxkmcgooolmjplipmknonfojinnill{lhmkpqopemvmlpqorlm{nrjrfqqm}npjksmliloautnnpl|qmnlfojmrlmnvogUontmnnopoznumnyjlo`linlomomeqmnnopmroskmomghkriqqjhpodjoioqddlimolsnlsoubmnjxknjononrsjuvijnlepqooqmloovjmtnltomnogqrpppltoumvpiklkdjvpkzlgltpeon]ojpowlgirrrk`tloqnzjaqmlhdcsdpstghhmfpolnehosmrlnpominosjjku_uomnlnnmgmtofklvptualjhckepfkjwvklrpihmppjo\zmomdsul`jorfnrsmnrknqshloforqjslggjrxksotqioljpnmYl_|menmimripqmheqqmimmspnldqumtxmlvprwkmrsjzhnjmntpn_ulmplnknkhusnlkjqkolourljkhxrmktfjvhzjrdonlms{nmgngpnjnmyfnvkojlmjjnsqnqqq_vmhkuqrprpjnk^nhfmfwsnmreotxrrornyljlrluugjontqoqoxneqtpjimnp{dqjhvmkknkonlljknqmhismmksljonmhkjihozmplhfqr}jumhlpnlgqvmosihhmflzflhqilpgrronnosksdnhqjqrkfnvsonrikflmnwlpexurihtktrsjlhmkmjkpjkrnhtjhmrdpljnnoerssojnpdkpqtqjjkkrimxuhoqmknooyunommrmiqndplmjjwofqnuqvmmdqdslrntfnmksj|or]qmthopmqvptpglrkktogmpvstzqlylokpoitjuwlmtemqnmjslzosqrjoklomnumsqkkiqnmkpwmojpphiwlltr|osnrirtjsnljmpfmkmmnrnosskuiumvpjpipmmjhymkohnsgtmngopqlproinugpnossjpgcrrqislqfpnmloknpjlmncmnyitsqq{xorrnxnmulhjmkxhmkgnpuqoommrqovslmnmlllpulgvfjhimitarqlogjomjluojshlnmjmotlntmqklvnnsjmptmljpjotuimmmennsrnfofmmn`skqo{nlqlqhohponjmokosfxijmlqmimreolpkjwshkgipiqlinlthnqpsxhmrlmseiinpmkfrtkpkriplkprgingiptwonrhkrkmenhntonmmipnijikmiiqpmvsmioypnhosqmvkjslqnlhwsmknvthihng_rlrrpgtumqojnqndkoqjh_gnpmtglhmimfjemikptinldl}urhgzlkkbliqppbmldjpftgmnp_qhjinvoqpsfpmxhpckgkvqlT_ptjohrnVkluhpnkkhojjilkermnolnlnopdqjlzomognymdljmpjjppqwnjnoolqnhmknkXklvpllrxonni`qopqokqmffppljmfjnptoqslmnqmocijhjohgjsquimrnnjkpom`lrkkjuqjuopgjiKinofxole_uolnnqlpeokanmgfjqojplubtqiekjlljlrbqpormzqiuobgoljtcunpknpYoqopanlzygjchjmkkr_lktae]lkqko\[ormqsdqlmjtfhonocoijzkvmmmmgjjrowiouroliwpuvqjqljlm{ghpmkjhjgmokpvpfr|`ljomhokk^nkicospfojznjkmmippp|nmonikuspxifpOsdsfotloupsnkykvsrtjvkjm{lwneohppjkpycnjwooujtnqrkqmkpokpkkqqawloonloonoiolmsmvnonqmomkeomlnhnplmqpkbrnlnlqmlooopnnmqpmjofnnpcmiinmoqlnqmj`krqitmjkpinjlqnpkmnosoflslntsqlpmoilpmykqkmvmlinqqkqlnqpkllskprqortmmpjpozojiomqlqphkfognikmfmmipnlpjmkxomyqijoqlomqkqjplmpqpqumstbkqrifmrl\rrllnkmlprnvqlllrnpjoauplomkniupksmojcdmirpiqhlptqo}ollnnimmqnwpltjoljlrmkorvmmosmkpp]pmvfmqnjnroklmgmlkonkdildkmbZolphgnpfkomsnnqmfqnkgjqilkmpmpohjopqpmssvngmpslnnlmmintopoqvnpdpohkompmjgrmvkpwtmpqjvZttoornthnkkhtswgqknkokmqmplmmikomlfvktnrmjlriolooq^rljjqnwtjmmpallh{pqemonzs^mpmtmnosoq|pmplqmmmpnrpnwoflmnloqovillnpjopmoqolvlisqkshpkuipkojlmkgmgpsnqpqknrohlunzjkuqdnjrmqhrkkhoooxlkpohjmrmpigovppynkngplmdsrnsjjziqfpwieotrvpnoqekmfloqqskjktlnpdmmrpoqovrihislqnimpurlpimp}pwrojtkmognqhkgkrggqpkpqmrivfnmhjmsknsmlkrmhcmlofomrqlsnrrnomoommn{rjknnlqnjnnphzmenlqniekthnmpkojmnsolwspjknplm`~jqmsk[\vminpnqmnodshyrlnnysoomtiphvmlptok|hnronnnqnunqnqompo~njkopnjqloqirnmnmlimomluonjlpolonoggekq_uklnmoknmjpaompldiooaonmnlntojnljfmktlngmtkulkontoklliltlnlmuon[kklmiofmqoojnnrlioornjnowgmhnhtmyqwqomoljmkvpojpklhrnjudohampphwsolkmkdqltoqmrnijmlhjkmkqkpplvomimpnronpip_jljoppmofpnlrmjrhnpsqpophrrpjfnkdolotqmooorunklorsookksmunovpvphhlsmlklpfuhmokhqrmnkmqvwonn}mpgpfopmonnpkoxqmhrkpkmpiklnnwqbolnonnnlnsprqmkqmmemnnlskqnsslmjmnqpqvcnnmp_slonymmmmmmmijpmlumqngompkkqpokpmmqQtmtplpnqoojgnpljmontlngtonoomklonfasignrlemmjmpnlp_mhnobmnni{oqnnpmo`folorqmqkorptnqlksmqknxlonkscnnonijnpkknpollgonjpmcjkioplmwnqtikjoolojqnnrohpno}mnomtmnoclninnnrpqooqlpmlnmoojopmoqnjnoopvwsnlqm{omgrhontrvssxnfimoosmpnk}knmojdknmmoprqmikmdnnwqfllkmjqqmkerfflntoi_t_lniurowrbnmlnrljdsndpprfskktononqoqjnqjogsrjkpumeinnujrjbhoposqhurrpinqrkehompepmmlfynqmjkqmzimknqmlolphotphlmjglnfhkk[ni\lskqromnopsbltltr`ntmogrlkzojiolvsllkslkllwsqlknikmksjrnonnwhfqumlininrtkmnqolsvqwhlnwnojrofnldjommpmrqrioostmqkmpmkkilovuhlonnjnojmumqonjnqmpqnsocpnnpijln_mfpsmpjh]jqlpmkpfipximnoobqhpknpoxrhjk{piYkngivtnhhblpmomphopsdsmkldosoojkonrnlumiqotollmnphllobrnnnsasnqfmo`qfqiuirqmppnm[mosrotozuktjmomeqmqmokiktmmorqqmdjomjlnlokdmqmofmdomqpmm{lqlq\ppeoijpqonoqkpprpnvnnpllappnlpoklnrrsmfojvhjvlqksrlosngookoponjmpn{qpmprlpkatfp`kqlmmmlojfhonpqyklmqkpoXrrpropj^pplptrppmoohrnopol}gtnmnmsmihlvmrjpprommlploojmirftenglppltlrnslnstquolyepnkmpoolplilqnqtiilnhmmppmmmunjlmmomqoqptqulohkdonf{voqnoqhssnmilopjojonolputhvkpoqrqijjqmmpmkkmupljtpznmsjmnqkmlmmtpomkohnlkoflrephpmvosqpmmlksugnqrommhesjkorimjoljrorqpkvhpjpnkpkgtuepiqnmkokloonnpdjknonomqokoklukliqtpjpnmnqurrrofwonrktrtqoloioolijgpqil_vjylmtlqypt~dpfoonqlkjpithyrllsfhonmosrhropnnwplnpltmlhmpmqmknmnhlolpmkpqurk{droorrnxqxomnflomjqpflpowlunfjl}mmrmojqhpgjohjqjmlpnmfqgmljijpsmmqiqroonjgojnpmnknqrrppimulqoqopllvnndbtoojpjqmnnpjioojrurfjlpsgrnnookmgqjiniphqlmnrrtpkhohuslkurktsjonuomoonxlqmlrslokmnoounhjjlmhojplmjqgfsmoolpmtlkopolqqkqorgppktnvmnlpnlmijpsmyjhcooqmonhmjepljvnkumkolpfrnqnpanitgyqim\pujoeizkli[jgjrtunofnqjmninlmrlqhkijnofglnsqnkollcglcgpmkoqlinhndjrjwoljullj^poqnnnhckklmpplxiojqrlmqorqumjmrgmdntkrjpjiiikqksgbmmfjnmmmhkormmimvkxnog`hvooipohj||kehmogqllthgulsnllonospmrmpohnfitmpoqm\kgiqpkeqgljinrqoonpmtojmkspqkwmrobdmjlnmnqsnozqnmrhnlgnormujhlnofkktqhplmikykpphnhtjqqrssnphu`nkom^vlroqyomnomonowjmipwdgqmqnmqjtnpssvmxnoqyoqijoppprmgpolmlkpqpogklrnlhnkrijrsilpqmqmlmlrmcnlrlmpiunaplojlrqnlrrqomnglhjnnlqornklkixoolnmmyrjqjojvmonkqmmllrqgihsixjjqljqvpjmzy{okmprjbpmjnftrmxhpqlmlngjmiobnldakulksxjqbsrnjiurlplzqqnjtxolitripporpomqlhfgnjxvqnqspnqvofnmfky|iukvsfjohkrdahmqsmqnsuomogomjwqq`jnjmrknn_mpgmzsotoxnkpgjukkilqdlojrosimojpvpqpenklpnmqnkpmtpsinennisum{plkipfkpn\ifplunxjohliltjltcpnnppnpotmwppnqmkkquotloxivmun{lounlfhrnnfuxwomlliljjqdripvrttckulnoqqkimcjkiklrploohmkjmprjslpnqqlrmr~hkojnnqskrfnijmhknttcuqnougeqjlupukqlmhvmqmnndiqnr|nirmlolokoqspptjlhjxncnhovfoqqjjehfvppnnkltnnqnnxnipnppughhoootmrsphypklmpmjpvrrpmktfgnoqnxrntjvliprlenmqmjlilhmoprpmnozopmnhnioosaonnfnlkroopknlonovpmrbqmnnpmpktppt{mqjpmljnmpwmntmpmqmigormmlkojkptq_mtfhurkwompmrnnqxftupclkpssoqjmljlZnngn`pmmnifjpsohpcnrmpmqqrecpnnkmitsqjqppmvqrnmtkvroqqknnfruqrpmnlmbjjyloopwvpunpjmjtcnlwrnlnuqkn~ejnqjpjppoltlmpkkjllnonhrpnmtojrpnqrqjnmnlirnfjpmqnmhkmplvglovmloojpnonjlnoip~oqopnilrnnppmqokjolkojpnfptnlqoonnpmomollpgnhgmqmgo|cglkppnpgklumkpomjowsonlrpn{umumoppukmgkphmmmjlwppvjpow[nnndkzlqlkojlnrmkmkqoedqjsjonsnpnnprnnsyhiqnmpokumfbemlswlomfonqnlwsingopmsnlpplqonnnmlnmjnmnrp_qlqnwon]smpmmkdimokvkapyjtokuumlrigmrmrosvjsqsonklkflulrrpqmomprtoipinoqdplxljpkmak^mtikpmpkmoqooivmpuonipmrmhmkgnkqppgmpjknmnupgqlilqlzenmprurhmrnhmjnrhinionkpklnronkrkkljrnklkorkmmkqmnputnmoiqolumnqqqrjof~pnmoitllnnkmthokimqnoiksqtotqaijnqhnnsmpnohkjnljppslijgm_qqokqjipjoopgkssxjjiokooilorpjkpmr|qoplpmkjjkukppjmllkkqrqvjinqnnloqodwlk|onon|qpjsohmnuhptlkkorpidokkmkrliuolnorloskmeptkmnmkxpjtmooqmmrnqmlnpmrrmiqpilqinltpnqrjkpwrwnnnihoqjqplirikgqltlrpmpmozoqotvnmjkonpfithmvusrjlllitmjppilmzkrmksq{tnnmvlnqnhxptlonkknelvxplmrlqqqjcg^lpkolp^lqUnpjwpknkfhoqqqqllinjopmcngdlzkimirlqonosuopnlspmfpnqvnhjurnsoigvqkqqnlglrin{nm{kwvjkomlhfmdlegrhoiko^lmpnuppkdthsloqkqnmhksgngi{okntpbopprmqmqqozsonhoqxsncqooXnngenbkiajmqmhlotoktnvgpumottmQnoznmiylfivkbjmqpnogrpnjhmpinkqhmpqolqkonoksmrotmkrmslpnqjemlgpfaejtknitmonogmnphrnjkpopknpmmq{rjflmqojxmjtppltpinepnrmnpmnlmmtiksmtlisouqoqovrlrnodtsokqmjnmnlmqsmmlhajjnqykmpkklpjorlioollpopnqrmmmponrnnjmnoimqoqppkomlrtmmgnorqsrlrvnjcqnpfpgokrskjjlcnnqpofwetoqk{tkfqlrpkmlymmnsnnkklmoigsoknmeokpjVsnlkmrkftkompgoloqrmpnxwopdbnnkwupngpniiommmopotorlsmpnviphqlqhpmllwulnjskoukxlpqroojlprpkvrkomlypphfreqlhqsmjtizpqtpm{irnupxuuulnopopnppsmokrjrjmoimqpklpljkrnnkqmpanlvnirmtnwohunpkolvmnzqwjl{rqmssprmqmvqorrrnkinplnkhmjstqtulmq`mnlqokqokksgqhnmvpsuulnomnuopjtnllpqqoqjqsjlvrupsqkhpqqomoqlsjjpmqelhsifkmmvnflnpmmo}rxnpkfl{dlnknpmssknmukpqppmpnpstoo|tlusxqsspslm`rruiopfkkqguhpjkqom^mnodnfimojmctpmlimnjyvsqohqmlnmruoomrmvnlmjgwltpquprqyprpmnljolnpiknnunmtmkqptnpthrrraloumplnkwpyhnjvpoqoppmkoulvdlqqqwmleknjrp{tpweomnf\nrm`nptkvoqpomi{emogvoniqsqlkmofmhjpunostmgrgqqostnsmiswiqqnvqlkgl|lh_omlhkqljyjtmnkgnolmOlrkppuimimghqpzkcklqqcqmflmshtimomnmlspnkmlpsoilmlsplrullqrvphkrqthnkqrhojpilhol`jsmlohqjqkqimomlokomnfnfmqhrhpprpjqiqhqgqmlpgnmdvulihulowhrpwisrmrlsvooitngjkphpmiinkmdkpntqinjprydmhejqvlknbrskmskoqnjjlxhlurvmmfotgihuoqoopidhpjmonxjlnjgngnoltklfspgplvrmln}nbhjollkoufxhlg~noqhinxmnoqpwlfrjgnhjllmjopnlrqmhnooioukppmlrlpkhrgotnonsdsqyqokkspmorqmtmwwpeunrurpngpsqogkpmllhom|dnclloookkhpjhvljiljxrmnnprlmrjodiqptitquphlpopopnckf|jpmkfvmqnqimqanoksknnlvulnwojlmmijipmqoppzmssmnlsqnginremhn_onfitqlmjlmhjmij{fjjsuyp{oorrklneud}nnrdgltpqnkmnjmio\mnngjn|lkluokriqgklpcbmzninllgionnjlmnhnolkjdmnrjjkrvq{tiing~sifknohthllVljnkoknlfknpsorlggthicnmrnolmhnoolmmoihmolvjfkgmfpnovhlosbroktlsepjol^mlltpmmm_nmmprjnttipnugmsmmoppxlnonjsp|monlxWnphiknxmtoinomkpklrlo~nbqldbhherusfounomtkqrtmlmjptjnpjloqqoimlogjorhnhZpmjpkkpnilppycdonlqcpjlokoplkporolrhjmnknloxszrlmpow}qvhmnkkrnonlnpnmhnljpolpoyqo{|libmllolnqqnjooqmociok}w`jknklrkvkpkrpqofpmmvpmkijolgomkoqlojnqljqnkphqpnrnqopojmmpklnlttpjojimrvrngnmlpnnmktnppynnlimpopgwlufhmjmolkoonmmplmpnponkkvpsoloikerqosirnslmoporlpnppptqknomeqlnmdpfn{nnlppopknnkkklumknhlptlvnppoimfnysopnpprongtplinmrollrsihoorhiopokplnloklkmkmommrqknoekminjmqomhqwoloqqhkmlokuoqqnpooonmmknmppnniwqmlpnmgjlmmmnpupphmspkmmpovnnnsjppoqlllnpkouklnmqklkkjqunpurppprslmlnomgqmmolpqcqrkpqnymmumnqqpknnkrpsooqnjljnhtnpmlnqlonkskrqlonljokomnomjonnkqprmmjopomlnmpjiollomoqqmoppooojpmpnrliprgnulpknrqornnnrppzmmonooskpmoknskmhpnostpjomlonomspsngqpqponojklqtpqnrmroijkonnplnlppmlmjloljnltmlnqptuk^kpnqnnmrtnltnppnpnnkkhmsnkkkloppooonolpogmlkmrqmsolpkqopiliiflmnsnqirvlkommkplploomlnpkminonsopmlpnoiolprnqfmnntjssnomlnqqnynknppomjrlrlxojhmqllmplmomoonlnrrltsphojnommolnppojrnmqqktmnonmnmnrponqoioooqpjue[lloqlkjnylmjorpkjglmllpqlrvtujnijmjopjliokhptlmknkfrbrlolhnoqdmlmmhrsrlnlhopzporqcq|pjkrnhioskortqqmmh|\pnllmgsplomjqqrppojtqlojdonjhpmifmpnriqmonuklerumormmkgdqqspojnlhpvvsqomgspmfepntmsknhrqplnmipolnoonqipppijasmmlmohphqnlrmpmlsshpnpllneprapnnnojkoiqntghompnmlhh|nqqynnrkjmkkloemxlmhqnomlsmaorllnpikqjejihsctmoroelokokopqiommimqllckpomgjpqsjsptoilmjmnohnkmhpkqilnngpnmjxdlwoonqlkqjmnnhomgjmonlmrodmnqpklpnrmlsuqjpmqmqrqojnjjssmjklkmmlommqhmoji_opnkhojnyjlnmqpgrlmxmntlriwmqoopnlkqosiljsnomomliiqqlonjlfkjlinelmoqnodomodrpfnorso^soirnopstrsmvrkwomvjnhjiqphmnhogfmokjmkonmmommoppqpkmromor}tnqqxs}qkijpngdqeilrtmimxvckfklmmllkpknnlnmilknfrjkmommkqokpnlruinh|pppnktulmomrimfllmrnmmqfknkqnlskllpnvqiwlkkovqqonhkmismodmiogrmron^phqgrnpqmpnnqymmkkjefqokoojokkkoljnemnqnimnkmkpqppoomsnnmmoonllqimmrqkonkopspkmmktnpolonqllkpqqlnuoqnljnjnlmmonnlpoikonirmvphsjpplmqlmmmnqonolkplookqnloppnprnspkpndkoolqmoqoqpplqlkrnlmknoplnnoninopqnnstmllknrjmmooqonmmmqnuqnqsdlmm`lmpkmvmornnpikk{lornnotnrpnmlonnnoqnoqnootljnnonmplxltlpjkloomosmmpmkmdootserssokglnjgukokomdqnvomoqusjqmjgpnsmqskpoqigqgemponmjmtvgjomrlnkmiqonldiowoqmqlrkujqtlpcmkrlpqonqfsnqonlfxplllrlqvrjtkrnoqsloonqqmfoimsngmlnpnmkpwjhmordjpnmlmpmmkrovnlvnnmsvooblntmqihlnkmkmsjkjkpcsrheorslmirpnqlljmqnnpplmmksnvplmhkloknrqrrkmjooimjrplnpjolnrponcnonqmkpplpmmuhnnnqlluklonmosnplmsnrhmprlnnppnohmomlknnnollrnntonuiroodlmlorlmkrjhnoonpmlqqphklnmopoljrlsmrjlnlnnlmoifonoopolunnplpkqmpkmrnpplnoompnnmnpmotqjovrrhojptslnmnsslokcrlqtumnlomljlklkttkpmtmmqnljlgnrompmpnlnmjllqolnlmnrldojmjpnlpmwolmkmnsjnqplnmpkorlmlnlomnpoprolmopmlnnonppjprjkriupommmrnlnmnlnntlflplrnoonoqmopnlqtpprjnuopioillmlmmqjnoljmnnoiqiloonmpkmonnmojhpoepqooolkrposkllqpnjpqmnlipkmooqpolonnblmpklopojlplopmrnvfmo_nkkoqommklkmqrkjohlootrnrnmnogmolpmnnkrloomnnjmljnnopmpljjsqmqpnmlllfnlio|fnhapjjnmnpniqqqklnojoqkokdnpqnimisippnookhokqmmkmnmknmmqpkpnjrmqpokomktsmrhkmjstkplmujifqpcsmroopititmpgvgpmkqnmtmiooqolpklqjqkonqtotruoltkkjmmomeroklimpmtklhrnrjnqmoqinppsmpfgmroslrqijpnnpthkgjrvrklriqjml_nnomklnjkrlipionrsoqwnnpnqclpmkoqmogkloqjyfopl{rmkdnjzeoikyksjkijlmmsrf_qt|npnomnkluqoykpcnmlvlnpplworkqhroegpjlnijkh|inllmuixqWoqm`nyohyVrjjuvllinomuxwntglnnnlmjWnuilsfinjrulnkfotnnqnyrcttjfhhndhugsprjvpoohtlvoseqozlZkgoktloqlkmvmhsppegnilqlomop`iqajzjyiqwts^urujl|ipjpkqpitvppsr]spqntompdrgmknlsnmqojljjllmomnpqqnlmiollnonnrkmmnlnvpkkrkkkpmlhmojnpnkqmopkmkoprnpmpe|mluqjqkpimnnpmmlrfmwpjlqqhsknomrpqkmljbptkkqpornnlpnmyjmmnqoogrknuosjinpsnrokpinlllqnjlmknqlonnqlomniqipprmmmldnromksnoinomrnonjgrqornsmjqlpnilkomonoonnqonmjjnlqompojsolnllgsnnpmylkojmpnlnleompwnmjlkllnjrnnwtmhsknlskproikrpprlftjmrlagmiwopkpknko|nrjuppsmjoomnjfkipilmprmnosunrlminkkrqjloiqbmjejnlnmmkpvoennptmoinmklmkqrlnnnqrpommiknnjeqooplypolnmqgnko|lsmlloormnmmhnmohwwiknonokllsmjjkinfitjkrmolmiqqnilmrqohinkkkmimkinmpnozkomnolmkkimmqmmmniglllpynqqolpqlnmkmqokm{rnpmmgooinqoiomsejnltnntlpljlopmoojoooqilhjnqnylnnjoornoooljlso^imxrrppugpvlnbwlqmojimnqinpkgrqovulnngioqnsjjlnnnqplkpnhrkklmvjtliljnhkuwkplkomqshqjmhonpolgkpljnjmjkrulqighskjsmoqnimpmqguloniqmmnumokkslpnoeqmnlklqnqkmsoippkpjkmmglojkotritqmqniopqomipjjiskivnokrooltqnmjgmnmspimmptiphdpronjpnlknllvhpknkjolnkuppkkqnrtnljsrrglook\poulompnsolkjopkkqklqopohornkwmlkiljieelknpmlljoguloomlmocoogbkjmprqpkolrqlopmjumnqymvtnqkmillonrpnnlrmpokojiinkiwtonnjorpmhoqlgqroqtjnjrtnprlnsllooninvkpnknmnjtopqgppmkolmnmjmnknolpomroklnpllpnmuroklqopnhlmjnmkiomowlmgklommhonlonmimfnigklmpmkomlmnylnoqnousqplnjkoqmpkioooqokmnojnoooovmllnhpymplmomhkdllgmnlinqplomvinommlpholmtqlinrtpnqmnliipniglpqolpmlnqohkmmkms|lkhnnsnnnmnpommnonnmlnnnompnokmpmomllplpqtllkmklokqjpmtnhonotolktjnhmnmnnomlrolnpooomornmliooponlpprlmkgpmmppmpmpknmlootmlqokmrkphoprqpmmrjslljjnkiqgmjomhrmpomjljonromplrnmoktooolnnmmamjnnnnnmvokoonmmlnmpoodlnmnlnokhrmeopsmliuoponmlutpmrlmnqjoomfpqmmolkkckpionnqopokuprnommnwomnmqmlnrpnlnblomnprqmnlplouislluuonmjojhqmkjnnmipsklkkpkqmkmmlmmnoktkmsrmlrqtsqumimkrmjqsm{ilmqqmjovmgjoknirspnkmmokjovlnnroolnepoopjgtkjmiohijlwlnmnonmluipnimmpmrmrkkmjntnkqtinqopjinnrmvminmkllvmjonqhknohmmiomloprikxnltpqhmkuhminqltnsononmmppromvnimmnppmomjiklqjokpmqkqnpncfpplnkmlklpypnkmfsigoilfksnmnmnllloqnlmuimiqllonoprgstmhunusjxlneqnonmbnsnrlrppkplopmpsj^optmlljljolkjtjvpojwhkooljmmnlnkkkpkokiokrsmnplikvjjlhniqqldorhqlvpllqinxkwkmljsokhmqoiqhpnkmsummkmhpipshqjxknwkekqknkxqirnmgnmltqonolxkpintnomqlruljllqpmnrllplnjmqtkinniqnqkruqndkmnpquqo^oljeqorpnrrospdkjjrolniohnmrpirpkmpmsnhnmkqqoonoktqhxrmopkjorqtiomprloqpmnjpunjlimxohopngnfhlhqljlomkqmommiknnkqlntopieqmwklononokpmmnoiskhpanikdmmlmollgoomqopqldollnqjnpnuhmqupmnqnmoqnuotrqrpZpjohkknoieqlntqn`nnrnqmnqokpkhkmkisnlpmqsnphmnlvplrlpmnrlnrmhpml`plonrnopknmnihnglknpnpoonlkpojpqjlopiluqijlolkqhnoovlonmlnnmfnpmnlnidmmmomkkntqmpbhpmouonkplqrnnrnloylnvnmomrknlokmtprmnlmhmupornkmlmnjonnmmjqoolhomonmnpvmlniprvompojtonlpoxnmjqnnrmsmpqmmnnnpsrnnpoppolonmjpomnnkonkmmnoplrmrnmmlupnnkmnnjnnqolrominopqhopoblnp^minjzqlplnoljlonmnpoogovjsppplpmmluoutmkqmnoknmmsnlqogkqvlmrjnrhioqqyqketojljiqplnoljmmmoflmkppmmpnolpprolpkonknjjlhipjnqpsploqnrmnokpmnvqsnlqlqnpnnoqtnoolmptqqujkpoqndqkjnplfmqhmjpjtrnjjnpkrmuinmnphnpllikprstomkoknpsrsjlkkonrkmjnqlouqqokmmrghnnnlsuhthqsorrkuhznsnfikplkpljpvpqprfsjsugmnpph{njkphqqpllilmonrjjmqnorlqopjdqpqngoapplilvi{sionmsjsqkaqspvlnigltlljumqslngjmqjkimrhjlllimqpgbglqmhqnnlrpkkemramlifusloprkchngjroqummklqlrhrnlmliqmxpoeljjpkdlgnioWplmnojhohinumgpmqgknqloolrmqhpriiglmp{oupqrentfinorwkmlrqpnqwtqujomostkmiioqlpungmjsyjqjhntjpvksisoquroorhpoqnjoromqonjnknmklaontyjfqrthkkprpjlrlkkrrifpofstpopqni}rnhtmjrmolnpmsipqcloujolsljilovndpikonhpnomnrmsooumiqpkskwqmlqjopzjrmkespnjpkojnkqoolhdpmuvjnvuppwnmpmkmwonlvqsqimonoqpomorfnmmloprnplnpgspptfnlqp^hhcpklr}xqponqkoimjnrpqgmlhojnntommjnhomriwomopluosjrqorpkpponmoloikqkmklojnnphshcpjonpelnoipjhjmpnyrekpomoromonkokmnjknldovnmemknhnntrplqrpppnqlnnmdnrotpqlqmpaovpmqwnsnrnmngoiknommjpmsvkjfmqqplnorklrwqqmhknomvhmsrupruvopvjjolqqjltipnkpwpmnwwgrpopmnlionopsmookonqkoqonnqqkqmmnqqninkjlpnkofqkwrnhpnmpnpmjklgmqpmlnnpkmoioqmpnfoyptnnnomlomoirmqnqpplpnpmliqolowkmkomfolnkmoknlrmqlrksnqnntnjoimkimmnmolqnnohconnimnhqgldnnkmsqjlqonrmrfpkiolmmkqnlloppmkqpohkqqknomnlnofllllnnmooppqntnnsnunmlvrpirngogmmformsknrpokppopoujjohmpnpmjlmlllpplonmqjromlmnrlmomlyttipmlonojijlknrollononnxfmmpopkrmnjmqqmqtntldmlmrorplrlnjmhmomhkuonljnnqkonoqorlojmnmphqkmnoktkprjntnrrklrlnhqoonnmkqnspxlnunpxknokoqnmukmnilunkmmpnqrlllntmoerhhpopoqmknmnomqnkoppojmknnmoqmmpiyrpqqliijnmrolqjlukqymjkkpsmokngnloriomkptqlolpuophlnnqngsmojhmmuknnqrpmtmjnnlkmqoqkmokkloqlntwqqikmlqlfjtskinlpsbpjphnrlillmprpjrynnjhntoqkpnmqkpkmnlpnnkoksnpqmnfgquojofnklkmpoosjompoqmpknlpksngmslpwtmojshmpktsltmslkoqlthrhppngkrooglvrkepqqoikymrnlsjnipqoknjnpjlnpnonnlpimqnk\mjmvkkptmltiiklltkqv{psjlmsumdpommio`onlflfiqpoqnslilekrikrnjkliplnohiptqiqqimkmnkunxi]orljcZpantqinimpqkbohmnpjmqqpnnnjkqmgqlgmnkjlkofslej\iotmnppq{tiqpqomfepknnumm{sjlppjklnqqpjoomjkgotqojsirhqojromommm|nxwpmkwmnitpnvnquhkircpiiupmjrrmpmnlslnhnrlnnoogjplmlqmmspolqpojlipmnppmmppoospmnnlqqokmjimlopoamkmmnlinlnmmnnooqlmqokhpopnmrlkulonoqmtknkqqnnnipolpoonmplnokqqmnnlwqnipomjlsmkkkomqlrmmpkppuklnlpnmmlnonpumnknnllpqnokolmnjrlpmnnhoqhllsrnsnsgmlrlmqmmmhkoirkuooponkluoqmnloqmoonijqqnmnmnopjkpnolrmomniorrllnsklnnjqgmhlmnolqwnkkknmmjonlqimnjsoilnsnmlqsnmonnolminmosnoonkppnqqolooqolojmsqpmojnlniomrulnlnmwpplinoloqpmlkilipomnkhpligonnonlnnomlmknnqpokooopnmcnknnomnkplmlopnqmmqrlkntkjqknomljoompkknlomonpqnipmpktnqnoonlimsrolqoplnmknlnnmqqplotpoptiljmprkkrmnlohh`{ploomlxlhmwkqpkogpiripinglflngcqgoootp~qikhqipdmjirmlnnwihomhrmmismlmoimnllikrplkojp^muqgpxispsudnklorklpbknmgjnolqoogonj|jlnkywnlvtqoqfmrgllrpenvzmwkrlki|ohnmjkdoqoklpopmnsefninbklqfkijidlmmolgjmhmqaoppkpljuljmoklpbnuvnrldqoipk|grrikrlliqxokmlkojnik}iiojjrenmlklmuookoogmmpilmormomnoqdinojouxnimmpnnuopmokfqnnphlqcqljooppthenpnnqmpmqcpkmrmjnnprhmpjobomqmkzotmmqmdkmpqmhoyoslhomkqzjmjotkonillmolgminiooomgnlpkjmjllgnsurrluppqlllftomnmjmrtkjmeknoqmopcmpjmnjighjpsonkmksjmujnlqmmpmkpjqjmmhponmorsjkkgheonfrmppsjvkioomqmnppjloijjljomngrqnpimssmujmppmhpnjponotqjolivmnjqilkgrjonpoholplmlpqnpvqmqoohnnoqkmgomoouljjpnhnoqlllpfoonpnmoknorqomn`hokppmphhnqptislmlrmnsmlijqpwvjrmpogqphlwmlgnjsvhhlmonmhlnqhlrqlknpqnohrppqmlwlprmmnnqmmqlkontnslqnllmprnimqnonopirpmmijhqlniihoorslvlhmhljsepkiujuopqmkkimfvlhlirrnsqkvqqhrkphcqcinjhlprpkns|mrnmhrqfpipmdprnnuimnjskmqkfq~edoqwkspnmnminulpprnnns{priokukmpiljhlkukkptnqtrlkonlsvplmojjnunnilonilumtoppdkmnqmnqtnejoprrqhwxljpohmwmljmrqntksnkfpnostgmqinpmkmotkrsykrplrnstriifsmogmplqmtmonmkmrnjppjiofpklooofjkrlm{pnpnpmoomoqmjimlqqopqpikqrokhjpojphnnrloooqlndojirkmfnrmmlhlmpnrhrmsmpmmoflkmhnirolkqlkwmkiqjqrosjplmpplmmnkolssrmrqnjskloqlnlmnpmmnnpionmmmqmonjinllomljpnmppoonokgljnnolmmknmmmjojljohmhmmpknoenknnmojmnnoblosomokommloopolorkrqtomopmnllnglljqlrypsqoquoqowmtlhhofjmrrfpompjjqxpklpkqllvpiutlqovkqmkilngroojlnnrjgkioqjjmowhusrldlopl|anmpfeujogpoiwsoomqgmxmrgolprk~lonttkqoqpknqtnoimkrpqlumdnpooqqmnjrlmloqokrjonkssllrfplmnemj_qjrldqlm_nosopseqmprlskmqmvaljmromlrnomjnfnropmmpnjononpolkjlkmklqhrpnudsrmoltjjmlrektonomlllkmqmtoklkkkillqpnvno|mokqgirqsjgmtmgmrqqmpcmnsmkkdholpikmlhmtnqqkkguljnktrlnolojoopjmqjxjhkonpnsokothpppgtompnonnlpioponimxokrtlpqlxulkmjqqlnootspmphppfnvjlmqosskoujnlocmthkpjipmmsoqvllrlomkqulrgjmpnppqsjjoininnjndkdilkrnppmpmomhnknlingknrllsqkkxqpmhontmmppgpooqmvplmmmoeltmpo`llhqgvorqnikpoonrjoloomikqkrjppmmlgevuqnidqnjmnjznnkofbntnmimcarqnqrflmmjlgtokjnjnnktmffnfsmyepmqkknplgilnnnkllnmkwunnpwkjqlnqnglposcltrkhccdmosmojgllkptlpsfmpnphwpplonmtnpnonoppnoslmiloknplkmwjhlkjdppqrfoilqpjphnhmmmlpopolomokmlmwkoolmnonlpqomeqpwmpnqp}omqkikinooklnkolmnmmponomtroxinjlomrnntmqeojqmommsrlljmpoqoplnmlxmobolmnppnqmtoojopmmnuomloyooonnoolomjonmlmomlnlltmrlqlpskprnmpdoomonomnoqplllmkunlppmtojriluolprpoonmnoonpnqmomoonpbmlpnmpgnmrmwslqmlhmppllpsqgomjnimoyhopqsrofrooknhkmommqhcmjbnpoolt|mlrmipojpnpkpkmkpmvrmmlnmomnoroksmlnxqnoq_mdlwlhqjrnlhjlgpnpsqukomrornjmpskqinkphbnjolwknjirnrlogprnmimujjtspodkhqlltjjlnjiqwsixmohpnrkrlkmqtqeukggkpqqopswdqyoqkpqnlemjkgqprpinuolirokjssroremqmgmrjmmlinkkjklrknobvolimokjqpppqkfsplmojjaqnjpmhhkiqiqvohpquiqunlgmonwumdklonmbpuogkmmoopeslomqn`jqtn[iknYpqmdm|gwnmxzjinljmnvjllo^njoutolmhplvjllnvuki}yloljnnkpoinim{wmlslpoymopnpnpkolqlfjwlokohankqjtplmqfjjijnlnmsookzsetnnllmprp~msmojnfrnnmpjkpjiiiouqmomohng{nmpjorkepemklklkmophrpzkopriqcjohlnpktpunlkqlliehlfnlooqqngpomlmkmnmqnoqqljlliulhmmohppmoojrmtnhmkguiwpnn_jlnklcokpqkhpniknljnopnggjokpmt~srqronpnmosmpnqnoqkmlkmjqpodmxoronvvkinpktqloqwkoskkklkkjgljmlpofmqonketblcknormpoosoqqzehlmsmtkqmnonkhklonqlonliipqmp[oloqooatsrlsqniqokogmoqqnnrppokjkoonunmnonmonpksnjtmlookgnlnqrnpapkmmgrpmmknlkqlolknndoqoonotoojopnllpozmrrnnrkrnmnnnknlukpqinkgpklplmnpoomlijrjol^hvmmomopnpopmmoolorjnnhxljpktotgrmenl{msthpqlopnlqqmjonrmjmmnqnmjmjqmloknllsopnnlpnmhnkmmmlmpojqospxmulnplomnqpiskinelhjqmmplmkknsilupqmnnolnlnknkrlolknhtnnnnlhsmstprrhlsohmnqsomnmonbmwpmnknlmnqmmtokrlkmnmklommjpykrnqsenpqrmormnovnovrnjlognpqpnpppmqlkjqmlkknmnkoqsinlmmmmlpqrolqrjuslkinppompor|olomoelntmmlllomonosilnhlmomiiwtwlqoktmmonkponnnllmjjoppuwnrnmnpknjikpknqhgjmrqpmjsjjhlrpngshskmolljmvssnimkmmkqqdnpoqkmllxmpupiiogrell|tnpqokpjrlnkujruupflkhtvqnnvenmismgcussjdfnp`ljgptuppmrkcjqrpqktnnsgimftiirppfnhjemmertqfjopqhlq^qhm]kmloirrfnrbkuownq|otmntqsiqgqnmnmmpvmkmnsqfmnpkkrnloohunbpjwszomjonlmnhulrr{rnepllsopqssnlqkqrongposgqkplqgpkkokmjhpilokorqomkmusmmkpmmoqnnkulnmmrmnlmlokkhmnqqjemronmpkumogpmqnsonsknpmolpsimgpppdrnnpknkqdpwrpokqkinnlhporojollmrnjsnkoilj`npmpnnmjlmvksnllmgopkjijnolllknllqkoskeutmljnwjmllvwhlknpijpohmpnmwiokxmslpnnlkqnojkoogmpmnonpnnnlmnopmhshoktlhijuknpknlpmbhpmoqjklpojmqoncnnnmnkhlrqllmolmmnpownjppmounrqinnjknmnhllmmmjpnonnpnmmkqkilmlsmnonlmonpvlmnonplgpmnrklo`pqkljrmtmmnlmvlnnpkqjoonnoocpmnslolnmnrjqmominkkqhhnmpjjoxomnnjnnnlneoinomjnmokomlnqoinpimmqlmjfnoqqphlnmlpkoinpmlkmltkpnopsloionloepkllpnnqlkoippjnnlumlmonllohmlnjlrtjnpnmmkogrlmlnnmlnjnwogonmlhhmoimknomlolmmsluqnljonlmnvmrpoqgrnnlnpmlmhnptnnommjhmsqpzkmmsnkkssnpmkrqkkmqpnnjhjjmknqijlnqmmjknmplnmgpgokoqiwopnmmlrrmnllfflkrskponwkoqkneopoomqnrovopjjpvrptkmsplsmmojwnhkpmopqmnlmpvmpjmlnnipnlsppopkilhknusknqkpkohnnnqpkmnmolmqmkmqmofmilnoskqoqinmkrpomqknpqmrlpommpomojimnnnnnpmogorlkstnjsjppqmmlvknimolqrsllnminlukqmnqmktnkinnllpnnlpnmjnkmloponnnnngonmnmoopklqkqqlkmmpppjolmgpokoplvnnjomopmsofmnmnpmnoqnnknmqmvtrpmnnnroqsrlnpoponmukmpsroqmkrroojqllllooloqpopkjnjpnlomnorppqolnhnopojrmmlpmlnkompmqmmrismgkkinmfmliorknlmlmmnhlsoqnrolllnlmpiqwnssoplnolohqookrnoklmjlmpgrlmnhlmcnnipglppqmonioqeomlsoksltmoonlylnlomoprnmipoggrqohmipmoozlpglkllppqmqnqhjhfppmqpiojmmkinqeqjmunmopprnporjlmpodooopoqsnqihonkqlloqpjnmmnikookpmmpnlonskdnmpbnmlljkljmrmnlsmppooplnnkojnpntlorolhur{mqkhomkqpmqvpokmlmlinjllnnkqhkqnpnnkmnqpntomoljuqptkokmlqnomjkmjsjrqmeppqmkjhjpmjlmmpxknlnhlgjnknonmolqimpdlgjmkkpqpmntoqqmmlqljnnrhjtnmlgnrlugnmgqnlmhonqnwmlknnomllmqmpookmmipokqgpnpnprnoemllpkmmfnlkomunnqnroompmolmnlrnolpnjrknmiiplomomriqqpksnolqkmqnjosgqjktnoojpmrjqlmmsonhminqjomppstpooooplrporppllqtskollmonlonnmomnummnmojnokomjomnlolipgnntllpopnqmnnqmonnrlllmkpopoxnolknqemhjrkmmnmkonrkfomnnotnklpmrloocgnqpkrmmnnokrpnlnllnmlmnoklommopolptlpplrnommkjljjhpmplnmjnilknsknkootmmrqmneuppnmmlmphmnlmnqpponkpqjj{olmsnonlknsomoppnmmjnrlmppmnnsponmnqlnmrommqkolsvplnpthnorqnkirntnnnnmompnmmeoppmqllkrromluooorqmoolopqmlmsrmnnpongqqploolmjjnnkpnkjnfksqnmonlipkionmnmomholongopnknqmolrnoknnqnnqarjomjlnomokrlpnrqtnrlokukjuokqllrmvgnekpjoqnrqmpomfiiplilkormznnqrolknnomvipjjniololpjongokmlrjoiogknkrkkpnswmhqkkpmlsflkokwrtllqnmeplnql`emrsvoolgjlslirtvnlhmpoknkkollnmmfnyxmunlnnijonpomigpsmrnnnnnooilkjmnqinqelfnovoptnlihtgnqllsknomnennolnjlkoprpmrpmpslokyhioqmqtntkvolmmkkhlgqrlonppnjoohmntpomokljkmnonsnqkonlpmpnpnmnokokppppogncmolmopkwkmqonqnoppmkosfqovmnlmqrmmnoolnmeqzrkjksvmmlljrposmlkjmolqlsnhpknojnjgmllojpwqnnppmlnnhlolmiopmokppomopnqmftooynqmpulrolqoqisumoxjlsqmqmooqnokrmilmmiomimmpmnmpllmmommlonmhmkllqpjoleknlolgfmnommpqmpolqkwojkiiktgmltqmoqjolpmknppllkokxnlroqrqqsulhymrpmfqqnijrnqqqmnooonjnqmojpflnuummmkiormrpktpkphaimnpekrpspnnhrrotqiqymnmmkhlmqoojnotljlmnipulolikpmpqjnqopnjorpijhmmnshlvopmqonnnljqmnnmolcipkolhskktrtosjqmmpsohppltplrqwnnnkopmmeunhknnnlsjkxjpnprnoikumkx~mkij|kjmhopnjmlpjnkprnnotpnryopti~rmpjmqngiprpqoftsbonqmoijogmrjnibokonnmpkbrlqnjrgj\qmpulsljrpmovrngtttunmpbqspnpsooopnpnijoZlncitlqhelprohlntmsjowmtigrjoflurjnhsonmnoqommlklpnlnlnhnqriqzonlmkppm}ppomlmjjjmdrmnklreqxnlmnlmkknvpslnlqolsqopolnljndowjrrljkofspoonplomimlljrqkqimlqwooopoooskoollkoqojmklfmkpolkpnlmmcmplknopmonoorslnsjpuknmrqooktnpsrmgmqomumnnkmonginojgpqomhroglolqpqhpnkmlmlrrnngmsoqrjmonohkhonpqmxllnoopkonompnhmvouliloqmhsnm^pjoqoqopqmlmjoplrh`nkxonlllontnilpqmoiompiokppmptpnqornmmnrhkrlpoilsnplmolrmmhZmqgrqoqpnrnuofmsnmmmpnpginnrneoondoqk_lvoiukmnumdosnionpleqjomkqkqnplmq|pnhnoohdllqqirvJnelsolbihqmolqlpiippoooroiikoloqllhmkmlmqkogpsrojtnxnmhlpmpqmhptpojnmoollnqipsnttnjxqrpodnmlpqpqostnourvrropimnmo{nploentmyupmkvqpkcmhikhokknjptjnnkmxpemwunkposknoomnmplnopjmptnpmnmvmqkonmqpnmponsofpkorllomokkjhmpnp|jmokmmljorohopjlmdnpqqqqiqrpmpiqpmnmompokoholmlmmfnqruqjpnnhqinmlkroqsnklnlgmnlnrnoovolpmonqmnkmoknnkknonrmoqnqoqpnpqnptjnommnsnnkonlnqmnjnppkhsrmmtnopppunqooonrnkqplpmmnlnhonoqmllkjmpoloefpqnmojmnlnwnopnpknrromnqqphlstmnnkmqooupnnmnmvmnnoohjkhkrromorppmmmmnjomppqmlpovppmspjpljmnlkolrlnrnrrmnphmnnqpmqljmmllfmoqlnpomnmmmdnhomqnqnhkllnmmrnpojnmnnkmnnhmpxmlmnmlpmnjpnllomkioonmmpnloomihoqlnlnompovlpnppgmspmlnknqlminnlokmlmmnl{ipnmqmrloopbrslopgpjjooropprkpomqpnklvnnmkkqsnmolnsompljopsjmlnprnpnkofmqiprnmllypppnkmqfnmmmvsmqollpjikiqonkgimqnnqpriqomklknjokopmnhoiljhtmwsppprkkrormpnqmjqnonnimhorlpplonqnmlhompipjlnnnkqppkmuoouornhmsnnqknsjkjlknnmpmnmmmpjoolllnqmoqnnnmlovmunnkmkmolppjmslkpnoliltqlmkksmpllmopnjppgsjjonqilsloqot}qopknvmpsohmpgnmmpspjongmpqkpnqlopnnnqouomhmnqmoiolopmorpskljosjjrrrqnroqqxllzfmipuojjponouhmpogoriojmpfqqplrnoqqoqkjlmmnpklntpltrinjisqiiwnsmprjprnmskupmrqljimnpuhnlqjqmjstqppxdjosltpnlnpljmjqmsoogplppsqrniqoklkpmonmlquqomlqookumsmrjmnmkmnmnlknnmppoomrnrjlqmmfrofmknmnpqpmnkdpulnlpiunfkosqxnooknnmjrnnpmtoulmujmmqkiskupnpnmktlwogqrothjsoqpnmonoolsjmpollgnsknootohoorplqxmnknonqmeookmonmlrppnpqerroolotumnjrodllsfnnmmsgiikjqkomnlklmtpkjlrjiomtnnnqonlnnotnllpmomnlnnmsqmlmmpolxsknnqmumqknotkmvpponnhqkpcnqoimqqjcjskrkgmtqsljun|enlwmkhniozjhurnnzmnqnpzp`muqrjoliijhmrpjppwpmspqoiosojjilbmjqff`vUkccq~bqnmepviqmj`pgnrlvtlmmcjnhjnkolpjrnoint{odkliphnmpcqojposomjlmrplhnvnlmcoflyrnrhoovm}hptptzonnikwrknjljogglvjl~nlkrrtolnqlmqknhhqonhnoppplmkspgogodlljgmokoerlilrlqgopnmkmkkrmpjmok`onlnkxojnoonpsplokojqiqhmpminomquknqotmnjponnoolrjommkjtyqyjfonqitkgfhlpmedpnklokjthoovlotoojqmjskjsrnirkkoppmqnnmpjmpsmulmltkkpjonoqoolmeqnkslnkpkmnpqqpoppntpghnlqkpnjhmjkplkqmnqlruhqjnnnjzkholinnrlklovjnqmplojfpjmjcrjorkpmdeltljwotqxkkiwzluj`imlukpokomnlehulto|jlfhlnpgklfmgrnmmojbkijptilkjqjmdongpsnlqmhq~nmpqlushkfi{nnv`qnxljjhqplopjmjigzroummkpfhukyqljvkkplpokgqrmi]onxhpkvmurhuigtpihknieobmzjiqkmomincxqjinbpn_jnqhfpnhjvqyqqshnpgpmjmohmcunrujolsrokknkkkplmgspgmssnopluistfnmpommpjoomlokinmjopurormlusqqnmjpnmrpnrvmndknhnmimmdkqjjomolkltjtnommoooonomronnnrjjtlnolrjsiqrmkkrskrlnommpqplkokopmnkrliimrlnpkknrknpblmqmunnmrponpsnnnmokmtrnolmilsqrnn|mmvmejpohqnnilejmninrqgonppqtmkpommnemojlqgkomlplknpknslmonposlonmwnpusqjkooiorplokklnonpimlokmmnoprmklqtmjnpmfmniomnoollmnjpnnjkngpqpsnfnkitpnokumjtklmompomnhfmmijkjqsnlnqmokmoekqmmoolrpnknpmnmrlmkgroloknrlpkonfptimonnnhqmontnnmhojqnpmlmjljmkq{jknnnojgqnjloplkuqqllorojuolornqklmopgonjmkrphphqpkoklplkrlmhomppokppqrjnqnnmqplurtkoplbsjokmlkkknnsmqmntomnoknlpmstpkonoeklgkonqolmlmmntopkmikstho}omjrmnspomkmpnpnnmmmnppsnulrkonotomollnmcojklomoglronpmorkjmolslgooplkglpnopllnojpplmfnomnpmilmnoqniqkmjllxgknnmimoplonknpmmpgnfknpnorplklqlmluophqklmnikmkoompiljmmppqniokjlmnoonqojsjinnmppmgononmpmnnkloioqpronkocmoozmommponklinmpqlooknipmkonpprkmqnmltrrlzolptnnhtpmknommokomgmhhpnimrnfhmolommnkorrkxnppoqsnilmrnpnloohokmlkjosknnsjnkniqkpkeitrnkkomlmlunpmnqmpslmnjnklqonoolnsoqeqiknrynmnqheonhtonmlkmnepjpnliiqrrlotnnpnllnullmmnpormponlorpnlqnmrknkolopnomnhrnoqionprrphojllpmmjomoppololnsmhlmrlohmkqrkorsvsmtnqynrrgproqmnqollnpromnmnxqnnjominqnnlpnonrinknompnmmhkntpnomqnowqlojnjookmjjomjqmimmmhsroolnmkqjppmlnsknkomihjnlnloolntloprmohlvqmmnmolspkzkppnojopprmpjqlknmqoljrnoompnjoumnmnoqrknnqonmjmmmorjjplkpuolpoonmkmoopomlnnjpojpknkpkpotkmmmtosoplpmhopnpkeqpkovkoxpsvomopmnnkqnkoknkqnpoqmhyomhnlimslmpornmljjnspnmpolokmonlnqlsllmpovknnntrlnroohqnlmqnsnkokmrmtoolmonhmnmoknlnlknqomzksphnokkltjqjlolnnqnmmjklksumpnonpnnvcmkmjminomnmoommlononloolmmjnkmsnhmnlpeltopwnmhjnnkjkoolmmmmjnjnsqpqoopmnjjpnpuoimolmoqmmlnnmnpoopnjmrlpnqmnmnpiumrpolomnopsokpnjlqljqpsplpmmosnglsqnonhsqopmojnlnooquopismhomjnpnklimplkqnsdgpollokmpprlpngnjlnnksrompnpofmuksknqnhpmmhmmnnskllmkmonminmnmonnmrsgllnpjmlompopplropnnmkkoqpljsjmmkrlqmonmsqjmnjqqikkogonpmfrilkookmpmirhpphinjmoskjompokwmghklomsjintkkoolkqnnppplonckprpfifjnnnhmrjpjmlorsumolopglinlxamkcjldqllolcntknuokqsrsokspnlpllrpkjuoholknmmljilrmjorqtmdrcsmopomdpkodnokpqppljlpmdoqqksqkgmksnnmqihnrktptjtqrsktsmlqmmunpiooovqookmqjkonklojmvhqqmkjnplqpqilosmolsikgollgmkqfoqmkrloissopnrmqnonnlvnqknmnhjqflrpgsmjmhelwoqlqnkilnmgukklmrutqjqsookomsmqkfmkqrlkkolirneijjjwmmlmkjsqvnqnnmljnnooorptjnmlnloooqooojhrmlomrojjnosnvmlonqiomjlfginoohktunkprpjpgpnnqnemknlop`qlsnrhqkmllkjmolsoironknqplpotjomcspnjmumqmkhppijqlolmpqrkphhrnmnilqinlpnjjjponopmjsrnotqpomoqlpqprcokplnlojmniempoqilolnlsnmnlsltuoommfonotovapgopklonngupompktidjqwqqsmpkmnnkpspnikosqqhfmmqpnmmukpoommnpknmlnlonnohfoonnoohlpioqkwkmolglqgplqolknqpsltroanjownookpktnkpnnikjmnllnoplspqtnlqrtslqksnmhmpkqouujmmnlmmokmqpmhoppjoonpqpmnliqkqilroqnpnivqlpkrjmmqlmoprojonnskmqdnmpkqopmmjzosoikpmzisnopmlaoaouqmlqlpppiotkmltrprkpnmjmolmnlinpmmrqkloojllsnqmrlfsosolnloloqjpngmomkstksnlnnqnluipqenopnpimplnklprjnorokphpmfnpyqptmjpnikotnknmnlrqkoookpppmpsnodrfkmomkmojljpkkqpmhoqpjhrmnhnnmproomrnnnpklopllnnqqrmjnonvnjnms|qnzmmpwotmjnmngkoonppnpnlpqntmogtinpnoponqkjhklnnkprqmqllmmvoomnjqlcmnqninmllpnkpqkmrolroooomnlorqinnmsmmoonoekmpmnkojilo|pospvljlvlnrlgomlloinrnqmohlnomkpjnjvnmoqoipmnnplkloqmnmpomomlmonnlmlolhllpqrlppnqrmplqnpnnmlmqqfmhmtoqstmsopnumjkjqnkolvpmmnlrqslkpknppmlqoromnmtptkmrloilnorijnjooookopmfniouppornronmcqjoospgponnoulnptlmnmkoqepppmrsmmsmmpmvnmjpmihnmknmvmpkrmrjpnsslqbmppnmoslllumjlmoqikqjnljkinnplpjlolqmrpoqlmlnnlvjtorllnsrkmnksololmjjlknohnnmjmkmrnxnmmjoflmojqnfpillsmiqnsmmlpkmpnponnplnppkmsnkkppnjqnmmqroiplnsmlmosmkjmlpkkspqlkilonhjmloinsomnlmk|ogenlnooqllpomognnikjooonmmyjpmseorkpkoimkxgllmpngnnitlsmoomipmmpoqpkmimninonunhqouinjkqnnmofjjrlnpnhlmjopovjpvjpmtmopjrdqmnbolioslnonropklpuqkooooslljunjunpnillnldnrlpmsolu`nmmoopijnmmpooojqrinmtmsmomnlpilkklorrqjlnnplnnmjnngmpmnfdlsokkoootphooppkhkoonmmkoqmhvbknqjlxglnnlrnkinmknlglklalqfl{smkolplmqmnormrjplhnoeo`jjmnktnoloknujomskrngmrkejiotlnspnlqocumoovsnp{nkipniqimnjihlpoqjpgnmsnpnikkiopkqmonjgqvqnxsoqnwogrdsogknqmnshphItgdlnlnlnompmrilgnnkknqlpmpqhnuknpmpkmmzonntmkjosprpnlijhpkontklpamlqjtiqenlnljmnlfroornolemmqpknpkhmkkolonqqsmhlnmmngqjonpsnXlqinlnjllsql}ogikosipglorikniomqoovqxpmpopqhonlmomknoonnmnjpqjqmaqqllplnkkzpijlopnpgmunvmooiooonkkjnpigkqmmtpsmfhhnkoplrlnplnnmktokononnpqqqnwkmmonmsnokpmmlnlmpqlmftkoenmmqoroklnfmqlonoompmmmonlmfvstnnplsmmmnflpomnsnmllmmpqkilmopkpoymjqpnrlnkknnpmnonovpyhnsnrlcmorljpnnlnomlmpmmninosqlojtlxoxhcufommqknnnpqmkonioopnktokmkxrclnnnnwnppqonpnpoookollpbmnqflklpqkgnnnhjnnhmhrmkmjnmsnintllpkmlllqiopgornqlpnolnkjnorlkutnnikpislomllflnoommmmnlsknorpmulqmkoonmkurnomlpmppqll}nnlnwnplpnmlnoonomnqnqmhorqllmnmoroonnmpqpnonkniojpripinpmsphlmpinorskormqqrompnrnqrtqnprnqomskmrmhhnmtlmolonnmipnmhponpjsnkliloqnnkpkmojpnnllhmlovkmonnkoqnmntmeqbusnoiqjuQommpnfooqwiq\pfocmjlilnlzqseupulisnsknplqqqrclljomornqrijnqvkqoqmop_tjmnankrkiimrlyhfhme|kzkoq_jspjmnqrjobqtofkmkdgiqqhljjhhlkmpiqliomigqoymqnmohgsqfnjihavjfmikmkpnclrsmtoktqgwlolr{jmpkjg|qrhodfrhskhloieffmgjufnnalwkfmrphht}oumov`selqnjglontjtinigrmmk_lnbojljvorlhelnmsonmisqotmklmlmjfmfnppngpqhgfrljxnpjkolofnmonijlkmkokkolqunnpougkospiiimjojetsojnynnlqkmfrosptoflnnlnjpjmkioommjnnnomkmkorojgncnqnrmlinhlnqonlelnoinmkppjnqrmrpihisgnxpmgpknojgngoikmnomrhljkrkmpnjjmmpqmmnqoniomifrhlsioionfkomwoqknkdonjnpenmrrpqnnpojkppqrlfokmrnnpnoolmslrmplmsoqoonlmij`mpisoompnnpsjoqpnnkilikotsgpmtpnknmmooklrqhijmoiopqmmmrrsmfpipromsnnmiskqohpmrmplnrkzjlmpnpnunniknminhojnkufillnlnnmnqkmksnpoffmumgiqmkmlplqqsinmknonksjpjl]pjslkmnktqpprnomlmspnogkspkoogpmdkhjlpjlpfmslhpiloplopmljmmrvmpjimnrmhpnolmjlkflnopsporonpekjgnr`tjbmpmknkmksmtirnnnklnkoowmrpjoovtlnjnopndqlnynokqnjpoljnkojqnljnpm~qglqrnmmoopqiolmmnkqnmnlqinknmkolnqppmnpmenoqpooplokoslllmtqtotplrmtqimcsioojimprmpppmhuspmilkroqpmllmomnnnmoqorrnornnoksopamojmmmkiigndsmqrdjqroenelntennphkrmnimomgqnspqlotsjsljeuomjlmplkkmmlkmjmmnllmkfnnlopfklohlnomlqmqnirpqlnfpqntpslomennllmhslrkoejvrjpnlpnglkelsrolifjplprlqmrrpnomnlllqbpnqjlkrklkmnpjumlmjpipkjstpkilknmpkpmolmhklomiqpkmjnjlompishjhooosonltgponnpqpornjhmpllojqhqipmnpomrposilkpolnqpluiinmjnqpnjplnposommqipmnofqnupqinrmqmpnkjnmrmrmlpkkoiuqlmrsepknonmllkhphllq|sknkphjnprorninnmorpjkikojplpnqgqhqgookooojtkptljknnjpllmmqhljmonlqgnskmhlomgkomqojokooiploonohnnoprohlormnojorhvmklkqgqljpkpunmnlmoiosoqromnkqnojlfqnjnnkvqjjiolpmnomslooisnmqqqnwojntronfkoomnpnnkiqenjmrpsmqnhgqoonmnqxkpmoqpmronljrmqkoqnnklnqnpjomnrlppprimmonqourklgmolllponisnogpnmmrkncokpmrolpolmmqnlinoktppninlnonlnllpprmplnsmspqpnnpnlllemtymrvglhmmpmlvhpqjimooqnomjpopqnqnkoomlsppmonmslmpplnonpmmmkjlomlhlnonprlmqsoliqmlljfnkrlqjoomkpmnoommphnnplnjhponloklmqoomjqlhkjsmlqkotmillmpppqnnkoqonoonnmo}jmkqtnypnoomnmjljjnxkmmprkonjqpoopsqnonpnhpnnrknmrjsnrmmqqonftjlnnnmngooqnmphmpqiolommoomlqjjtohkollqkkpfpnnrhppptmonmpimoltmlmrirwmpnmjqllmkollnqmlilrtqkmkrooomlqomtjqmolopgmqkknmmpjpqokomglslnofsoisrmnllmnlkrhnmikkmipkfqqniosokclpolnmvnqgknoriiorlnkokmlmqmoumqsjkofomnmlnncfnloktlipihinprnnohjloeqpjollpopnqmklnkqmiokomornjkmklomoqoklnklpllpmonlrqklqmrqoqrkkjlpnjnpoprhjkmrrniqpmmti{rnuprmllnqprtmsnunrjlslqprlqmlunoipptodtrtplqikslqovljotjqilklllqiommqsvpljrovnmhpqnnponjljj|pekspimfjgbwmpymlmmilozrlmpmiqmpkpppigsompnmgqqntondgpoloi|ondlggmpsqqbmsltm|imnomiilllmjmlompnojmhmnmworllrq`niklrqutlqopppkonqlncnmuommofllfmfgpqiqknthtmprntllnpuqgokpjl`mmnprlyqqljkprkpnhootmjmqjqhpnjkoroomik^oqiloshndinn{nkqmpmrtylmnkogmqomummiloqpnromkttipposktgmnknnnjrmunnosnrrqgpqpmmjkjkkljjlmgpvrpvchqsqwpoorpimmtgomqvmplpolsjgpmopolrirqwnqkkqnpnoskrjrjroo~onjumpnmprlirqloonnp|opesiplnoljjlqoplqplmgmmkploprrlnnostmnqulnorlnrothnnocqqpmolrhnjmlmltlcmqhikkvgsnkgjllrnqnmnhnwlgoipm]nomjmosmwnrloplutptmmrjlmnnnjjsjfnhnlonknonmopkolmnrpjrnnhpvjqkmrmommnllp}sdwpnmootjjjhpimiqqpoujiptqilrpnqlnkktjnlilllmohemmjmqlolqplmntkqjlofnirqpnllkqpgmhfoonpkknvksgtvmklko^srnkkoopnslimnj^kqkmfpbqknnkoomipwssstrpisvmqnrnniphonolok`hpmlpsqiheoqkkjngnlpmojmmljmreoqmkflpkqsooronknsgoaomanqnmksmndpjpjqpppmlsonjfqsnqamolpnllmqqoqnmodtqpfoglliuphlrnkvokoxouklmrlkmqgolmrmilmjonunrlnijnrsgmjjmqlomminktuoopppplrmmkplnvckmtotbifmlpoorlmmipjttmmlkqrmumkmronnlmimrrhnqoqpqlpqsqoqhssmonsnsooqqn_npphsncgm`inqhsntqpcojnqprpopnhmgkkpnlllrknmoppjlcnepqgiopojlljutnlmmorprpqopnnnsmqslnudmxohgvoermwnroqplojqmrkdmmnolhksmkkonvnlmjosovnktnlontmogpvllqnlnojpojlomippotnmqnfgkroplneoxinjilqlpsjmnnrlqplhhionjslrnmv_opkktnknjslcqlplrkkxoomlmmlolkpnklninnpmo~lhnplshflmfqmrqpplpuqnkonzornnmjokf{olfjqnjlqjmfpppmmjnmnommlnnljllprqntljunlkvlmlncllqnnnnqnclrlmh{mmjpljrpqmodmoonpmkmknkemrklunlkoromlkmmtmqpkrppnrslomkrrlrnqnpojrqqnonslpnnlnhhonkjoopsjktnnppmp`mmll~pnmqnmqhudksoornxrmiollpklpikkrnknrmqnsmhmqujcllremhmorgqpgpqlemplsmjercslmjnjrlqpmrongnkngonmqijotroonsnommniqrhnnlnnkpkqlrmsmmlrulmjofrlspllogornhlmopsnjirtllpioikppojljlnrqk`ooqmiopijppjljmqrpjhouroqnkqjmnmvommmkrjijolptmqpnirpgrlo{knpnmvkjnnjomug]hvmo|nrpkkmknrmsmmijnnkkonklnnpqmmqlporqommtqhnmnnakkmfsqmrmlop]ptncmnplomopkklnommlrmqcnelnenmrukmmgupmsrimnokniqmokkprrphnmnlnrkleqqlxnooqtomltoglisglommrdu`mmjppnmoljpkmjinlkpqliosnrronqlkmornnnnppfpnnklpjmnrrkeqnqllohsrmqqlnlsorjlotonojqollpsomqplmsylleqqfsmrpljknltkpknmikoprnqpqopqoqimphlplqknnlnoqnmpfrorpnonkgplnhqnmtpsokpqnmpmqmuvkponljrpgnmmrupeoqnihomodknroomkoqmyktppmqnnnojspnonphksrjqpopnmkronwnmnovosoppknotpllykmvnpjpqiloslmpoolklqullmotljpnqlpponnnokungmtporjlpsoqoklinlnqqipnpmlkknmnoooemnljrrllmnlplwqpntlklrpmomskkpmosnmpiquoolntnncmrojppmkkomjpofmulknpkrontkhofqnvmljmlpqonnnlpmmjmgjmrrljrqpsqrlkrmnlpjmjpknokkknnosmphmnplnrdmlrnklphmologmmnqkoqnnlqojtslmnpovoposlonmmonytlkpiplomjpuqnnmfkoqnqjnkluppnkpjkupoqrtnonsjomvkqrgnprslminmilipqgorjmomsprrsnsnnrjsqjnlnjopjpomshmoomlrfopqmpljlnnkoolonkqqlgnmimnmp`rqqokhmnkmpllkpojpqjnuqnpoqpnmnkmnm]onqnmnoonqqdmqnlomlnnmmppkmomlnmmlkoljolmllsnmokmpisjrqjnmomtnkolnlmngqkjqllrplmnplnkmtmqlmqmlmdppjonmfokmmlmnmrnnoopoilpollmpnsnnsmqmlnjjmtlonmnrnosolmprjnnknonlqkmqpnmqjpmnlmnjjmlmnlmlnmkonnrmotlvnninjmmnnwqormeljeornrmktflkphgilmkkgilqmpmllnzqrplkjvppemllbknrmojmtdkgmrkrqfklgjukpliknnllwktndzjolksppjfvnlpnpjqni|klgktiqljqrspyllsvphhjknvoinmchkliflmjwmjmnixonnrmmfipiukvngwsmhkqgjflVoq]jonkhnnokxuivtpkmiljkokkuphloWmqqrknpm^kgsnoo]mmkpsuirlqnk}khrtjrjssklypspjqqstoqplpmsmkphllmionppmqkoqkmmqqmonnnlonmpoksnjlptgnojmpioifspklljmpofnpkpmmknekjnojkmnmlrnmrlliqro|jnlpniojjkponnpllkummbrmmpoplkqgoqppookluubnmqooqmqommlogjllkolqnknnpkqkmqlomqnmplqpommngslomlklmnprnlfmmtoooqppholooppmmsnlmsnomntoqknlpppnjmmmpljtqlknpqlqnktvnprmhprnpmoqpmmipksknojqolnlminnnooqomnppkjmllsopjop{pplfnrlglmlmnnlnhomypnoonlpultjwjlolnnmlloplrnnilnqomnommmwmoisoiorknpnmqlkqlnlolnmxlspmmoplhjkqmqnlmspqmnqrknppnrmploqpotlpinqppnrrppmnuooqnpomnnqoiomlnqhpnhlpmqoospemipoinnooppnkppqlnkomltjpoqopnotonpnsrfqpprmtojucfhhokmlysqnpofkiiplinpnjjnqspiixrogsk_hymjtpojhntplqqnrnkmnopmnormnjmnjvmpjtokektjimmnkgrmmkljonrtlqximoriolkpmjmmqnihgnnjomlonmjrponmrmnnrrqpmrkiolfoqmqnlkoiobrqrtpomslmoolhnnhmollkqhvnokkltskjlnmmjhnrmmklnmnrkltosonqtmnknmoposrqmjnkntrnmupofuulmmnduoltkomkjoqkjhknrnwnpgijposmjnljrogjnjolrrfrfpmfnnnltmkolmookpllnmoponnfknppfmjnlkqljpmropjulolmhsnqgnmmmpnooltltotmsmookkeolmsoqlymmjkkjnrlmsltoqpinklmsknqgpsmnqllipnjlpjqqmqonokjulqinljkosnuolprmlnnkllojrvirhjnsnoimtoxtiomljnlmoomskteklmlqkqlqgimeinqnmanmosoirksjttilmqqnnslrlmkmgkjmqvgonmknljrohnelmwkmkiovnnqiqpkmgmnhhfnnqlmpmpomqpslmngolopmrhhlsktrpmpijnouokkcpopimllsllqrumsllolpirmilrtolmkkqm`qmntnnuflngjjpdginjohohnnpnoookkrhqmfksekprnjnorjnmhplonqjepnpglqolimllipkqkpljojhpomknmhnedpqogqzpootpplhpmplvnoqhpjnxonhm]hjollnngliqplgn^jocimplhejompeicpmsfnnnpinrpmjinqtjqpqjgppvknnnaqholkljpkjuopnhplphnjmqkkqqokmohngonnnlouvqltxnlsltnnpmrilmnjfjloidhllnlzprhpnnlwsknkkppvjmkrqselijmtflhlgdimrmodpp\ononjklnpouoxgilmmoalnmmllpnmfhjmnnqpkjipmpwjjnj_sjmhkmlllsnomljnlpnpkkqpruppommooplmmnnoorkmijsollrkrnljqgjlksoorrrpohjpppponkomsolkmonrmkoonkpomsnooqmpnknqtmqomkurnminrnqnqkgpknflplmpqntqjnpmlomrkqroommkrjomkymmppnokpjpnppkqnmfnkjloqqojknslqpjljpsmqpqptknlqtsnmmnqknmlmrrmpqqqkmookjokmnrmlmlnpronqkkploqnmoflhiwllnnnkpszvosmmmooYpnjqomqnmkqoflhwposqvklhqqnmnhoheonllmnmjlnhqponuwmqlqwhlnojlli|moqhnongjspkpmttrnyqokpjgnqqrsnmlnjrnlkkqqprokkmomnojnntqnripmtpohprrkiwqnmwnlcsqkpmoqvplvkokjelsqmrgmpgqynhtlefwpvfipjpqrskltvlekoirneoonmpljklmxl{pkqqlrrlhisnmklvrknrnimlonimqqjoompoopjqmjnornmriqmnkpnnksunmpmilonqhrkxqmpolpmrmmknnojommqnmtobkohmrnlqtpqlnmnqqoxrljmliriokkomolkklonllnnpijprpnqrgoqppnpnrheipnlphmrjjomnmsopmommrhlnoonjmqnoumpmlmhijqsnslsmkqmomonpfnninoumqkplumlkuomspmimmnjnookllsnminplnoompooppmrokhslqlnrqrmrmmkoknrnklvnojkomnnplpmlkouopppnplqmnkoormlfkkslnrqlmmnnkmpnjolnpnrlmpllnlqmmpuimnnmmpnlmonpnmnmmtulrmlqmoonorqsonommlnpmmpojlrpojmppvhninioppnmololpqnmojqmlioknlnoopinrnrsopogokqmmrkmmmejmomnpmrolnpllpojlkunjqltoomqnlkmonnlkqnlgjgoppkoloeoknnljekpqlsmlnwlipmlhnimrnpmdspoipoppmjotmoqmklmqjloiiqrfhonvroliuqlljqqqklndfjkmpnlnpnpppmvlmsmxnin`orr}vcnkqlokootuwwvromoirpqiutnmlpmwnphp_kpoikfonknpuolppnipjnnqmhiounpmtpkqutplptodpnmsllqlkafnjemhgo|mlsnfepticrnvmrglkrjpYmqnmpmlqnroioqkoqprqunsoopjnpoomnmodnnnkppokllhonomkmknrmpsnormrqloglkoonnpnuqgnklrmpuoopqmommlowmmlnplorlspmqqmpjoliqnqlnnjmvpmkjqnpwvlgmlongwmqronlksnnnnlnlrnslmpmoioqkpnpnrlmjmooopolqmqlilmpnmlnqmomgosqorloonmtpqlnjpqrloonkmrloqnmkplnqpnrmlrokmqogqimnlkqrkuxnopnrmpninokorpkkoqpnkpsmlopsmtrsknqiseqllkqroke{ngqrrkpnskrnlmohnmjorkulsnjilglloqnnlrmfnqnqoomljkkwmnnklnmpnprlpsgkiomkmipoilkkppopkmsehoqiokksumlmkjromulmsojpcqqqqfpmiphnbiqmnqrpmislqiihprimrqollqknkjnjlijjppmeomgnlomlnpknmqlinpmlriwnnoomfoipjomhllmmooqllpmylqpoomnoqqklpnolmnfllonnmoqnnqnpjnnjnmlrimmnvnlnsphojnjqngnnhlnommokmnjoqpllkoptsjmtnjinnlsosnmujjomnpntokkqpomronmhpmmplppksqognkqokmminllolrnngnpolsnlugpooronmmnommmrqonmpnmnlrjnomotijkppqnskmpskpfhkmonmjl{mnklpnmkrokononkmlilpwkjojkqrohupjmknvnpnnnmpnuomrpqolgisopomfolkkgosmmqkpmjkqlnlhmrnkioolrqprmknmkrnnkqpimmlpsmlqnlimjltnxqogkqkoounlqmnkfoloqp{qnpikpoknmnmsglkprpooksnirrlfgrkqljinpmsmqnknpv}hppsminmpmljnqnrjmlipmruqoospnjjqphmlpekmqkljormmmpoljsqptosrplkqxnxmlsnnkjgsqloolmqqplirllqklplslponrmmlrllpooookolpiijkqrkpmmpvvnmknnqpjlnnstunmiruekprqsopohojubkrldnoopnpjpiqfxqnfnojlhlioqhemhjpgmnovtolslojjmt~lvlnjpjovoknpammswliolokmjpjjklinykpqmmrkvoqkmbglmmlYqqnnvnnqlonrigmhqrsilnsnenuopmoj{lsoplnmwporrcmrgiqooeqmpyikqiowhklnknmpneh}iltvollmjpjzsjpqqppjplfpknhgmumlnmqtppmkolqdnpnkgljrdojhuqnnlxllmhcnosonnpoklosmknloiuojnkhblpoqqpmiknlrtmkjmrtmmsmonrhnmkoommksgjqnkcpslmmmfk^nsitlqktopo\orompflinmojjumpjmhojonpjlpnikuriqmkpoflnflmuqxmlomnknmlmqnlmtqpkkqjqlnowmonpjloklqqlqgpgpkhnlhqonjnnykjtlonkpqollnjpllrrykliksjnlloiqmojkhjmpqpmmqsrmekoqftrnvomspnloilmolmom~mrlnlinpqjsni{usknsninqorspmlqlxmovqolnplnkknqmmkopdsmjjqlmjkohvlmhgorptvuooknlqspt}npfpsslpdgroqojmpnsnhklojioohupolnolnrljqkofmqorrlmmkmgqotpljiwmmqipinpqrsgkslxslihotntrkmpmlpkpuorzkkqnljrjgtjonmnjtmvqnqptpmmln`pjmmnjosqohjjsnoposdumkmniropnllooiknnjspnmrpjnvtogomnlnqpronmxpqmkomrwriyookpnoqelmghpponnqnnoskpvikrqqpqlnnolkmmlvkpqqmpjoollpnnrjqkjdqpvlnjrnopqpookpokqoqiemmlnokonnllnomppnomkoilponkioumon~qlophlqppnmsmhglndlmninlmngmonjnlmhowjimonoookoklinlpnpmknrmpmnoinklpwmsqnmlqqmoqlplijmndkmrkqonogkmmlkqtojmomohnorimklmmromnqorlojmnampoqjlknkkkqnsonlmlnposmhlkkimonqsrmokrmpuquhponnpqmolkmmkmnnqnmlmmamkmohfmnnonpoimjmnleomohomsjmllkmmnonrsnpnirqlkjuqkpnwpqtnqywpnlopnjrkphklolnjmmrmkninlnmpqpqjroonolounnmoklojlmnshhnnslnqmqnknmonokmljrnrprmpmgpmnlonnmnmnnnponlglnpmplolmnmljtoqjqrlrjhnhtlm_ovmhnpnokoorolqkknqrqlppsojqmopqlornmoiipqjoppkrjmmllpmleonnpepnmlpqmorlomnrnsomqnmmtiionnkovnnlmqnrlpkjmootnllonpqmlnunnknjhlnoonrmksnkwlphmosnmimqqiksvnimmnornlnrrjjnnknomojlonjhnllknqmnqlpsllmojomnhrmnmflnpohqjpulioknnhkjplnominspoulslrnqlkmokpsnkgknimljsphmmrqmoopnnqospkjmnmosjliphpsmrkonqlpmpkwnntjznkqtamiommmpplnnjknpojnnppppgijmlnpmoroprnmoqomlgojnpknlmhpolpnqjmmpnqjoqmmpqllgqmookjooklkroppojmnmmoeommxptlomlqooopnsplqomqlnoqqpnhnstmojrjklqrjorrmprojjqnnmmjqqlmmtjnlommniepmnjuotnomohlpmmrnpktmlonqnokbmtlrnlrplnkponlmlkmokphqkpiplmnkjrjhnnnomnmlllironqomqpodjlhpnontnikptflolknmonipnpumllnnomolmnrokljlnnmpmkhnlikomqenmlllnoqvnimrnlisqrnqmkilljlosloqkpnniqoontmoimnnqqmqjmopmgoklnosoqkmmnlsknqmmnnlkqmpofqirlplnntklupmslkmspllpponlniiornqnnlpoppqiklqsjlkVoiqhirqmvjvlsyklnothnhmllnomifmkpvshnwlnlrikjlplulhkkherrkimkmjsommtnlmjllkigokuukkpisumjmkjsojigqmnokjmatmqjlnjmnphljkkoqnionpvnmommolrmhpuhlkromnpn`lmhqpqhuukqroljqsfkxnmmorntmmonhsoqpmjlrmhynqookvjkjjrehnonipjlibapmhoplgxgrjmmoomhpodpjiekknmnlkijlorpevjqrmlkmqnhanokpmmlpbssngtnnkismformo{_lqljvtslnrmuorojiykqnmjodtlpkpurnqnljjrqlihmhrjmfotolmmpjlmoooonnloclvjsqqkqnopksqlpoqnokrqlkomcphmqpqo\olmnkjklfonnnrnrovkmp_eholonilkqkgejhqqqmsnlqoonnppmknlmslroopijelseqmivmfrmomnsniylpgptnnpmsqgomqhkgniiiikagiqpebshrkpupkkowqomlmngn]wqlvqompwklim}io}\gmmqsbxknu^kknhlcqjjkjl\brgkmpwl_vmuepmsmnlkdtciqmtniltnkmmklumgolqklkrgkqhrpgpikshqtqliqpqkjnoenjrjsmngmquonrmnWtnmmmmqlsrnqolhmlpqsllilkjinqfcnfompiskrnpeqokjrmpzkemlmmoisnkluoppmplmkkmnomnooimslpnnkjokmnoskmpknnklnrjknoqmnonnnonmolpmmmoulqomllqnqmrrlnmjomdoknqmnlpqpoqkqqpnmponoronjnmqndmmnprlpoommlorponnqnmoqnplomnioqljmqnoprpnpniolpnomrnntsnrnnoljponflmolkvnmiomoomlullqrqornonosnnmimommonnmkqmjqqinjmmnprkkllhnmmoomwmofslnrftinoskllslnspnmkmpnplqhjlmfwjjjfinok[ojikonjjlolkmnkrgnlcenhnlemrklnojnornqmupfmkmpidrnmnqlqulpmg^ntmgqqgcplngpgkmqjknosvmlimiolgsomnjppqnnigpdkrnwlilqlemqlqqvppoplqpgorqssmspjblutorof\intkmpmjjpnoplhxnvvmp\plppioonpknmomhqnjltjklkjoonkrooqpunqrmkmpnpmmqqijrprlhmpnprrqnhrommoqokppmlhmnnomhllmnqpijopmkorlolphmn{llqqolrnwnhlpsmktkmkknpqsokhjnmqlonolplnnukklswnmoqkiqmnknnrlrpnptmqqlmnyjlhnomnpfjqmkrnqnnjrnktqmmnrnnlqkmmnkrnjppqjonpomjjqnmmoolknkvonromnnqmnnmljnlnommupunokonslonnnkppnpmnncpoqkllnqjmnmsesqmlkkmlqlrlmpplnqonookhnorlimomnmpnilnrnoopnonqnmplvookonllnlnnllnmnoqonohkktqoewrqnlnmqopnlnmdnokljmmnnmmjniolmmkopvoklompnlojmwsmjkkpololmnmqnlnpnnooqoosjlnpsmpkplkaljodopooohmigppokqhnkgrpnonvnllnnillninqoqjrlonoooploroooomnpomjrlgipmqpmmhjrommppmnlmgrrhpknnjhpn^tltmsppxqlojpqoposknpopikkgljrlnrskpqnsfmxljnklnolppmyhnontznrlmlukiongnehoru^npqnnillknawoimfhnojmnnjsjmoxgsikinrosrqsfglmrjmnmipmkpmopjrnlopnqsuhprnsqpvrbokoomroqplhlqnnomcpmpiopsborrmoqeloqlnsotlpukmmeopknqnflflnepamokmqaslokqjivmjsmprnjlmnpixhjvqjmmupmt~`ljm{xjmfhgijmpdhwumslmonktqklinuUkoosjops`spptdpnvskkgsoqqpqrggvnnpilmtej|rrtwnhmvqcspmsdusoqushqlmohrqnkyqpludjoqkrtlmfkrwlgoqjozfknhmmninivpriklqjmrqkoupipvphjmnpu`qnlmuyqj{k~yidkiSrunwrlpigmxjpprlvmhrqpnkzpli|nvwmqvumk{rprkopmipjipllprkommvjqelhnommornfkpoenmkmomiokslpphqoiglpnrtjhzqokplkolqoqmprmjnklipjsnmoporghlporkmrqlophoompumolmljojpnrokkklklnkkunnmrmpmrmmmrmmqljnspisenqkmqnmonmoomknmomookummokllomfylmpmnlnpnlotjmkmosnlwmlppnlrnppmpkjotompnnnlmlnpnmkomilqfppmgomnmlmmjmnlhrpmkpimsnlnommfhlmnjkpsjogqeonnssliqkkkqhneolnrognkgntdklonjjgnojjmokqloqqqhnpqmnnjlkrmkpdqoqaolnkwosoomgnrpslijomclmgbnkojpmmmljlnmotnljkilohrndopqqmpkkhpnnknqqnnmjvnlopphknjq{omgnqnqromojinnomjjldhomnjsioqmiujmckirsnlhpqrlqnjllmnokknojkohhilppksnrqnnmllontiksyQoqtnmmpndsgojrwgsvZvknupvkltqsqigbkentpmmolhqsotlriojnoknsurrkhqminlvtqjdmmklwmionwjtpWrjtctpkopsYumliihsmiormdoulkpfyrcumpwlprrocjrnhmqlbomlkklpknpknzmorukrjfkrqmpetmqsmszsqpmmmkqnndollphkvWmkppillknmlmomwqoylsn_kommgoeqllkphhhogoochmjfropmmkmnpeopkqilooxzojikomlsnpoppjrsrrolmlkprfmqmloilknpunhpkgphppqsononcjrpfimkmpklhlltmqsmlnnqlrjsoepomhjgpiiniuom{_rpollcrpelomlktnehhmtlohrnmklqjnomrqlsokjmqqoikllvpxpollitmplglgkqmqqltljiqkmqloqkonimuopjl{jlnjiokkpfn~onjoknqojmomprmkbknoosrqpopjpmjjmrmoknlssmmoljnnnftpinlkqokomnnlkkjnniphokkmoqokrqllpllpinluwmjsmhpijkopnqmnnnpnppmnonqjrlponrqkommpnoljqrqhmpqmqlqglompkolmrmooqmknpimpqmsnooppqollrqnnqlnqtunoookllqpllnmolqnomlmmknmpnioljnlpkfpllmrjqnrnomqspnompnqproolompoonqpmmlkngonoptopolnqnrkoonkpkpmolnpcrlpnnkuplnoholnwponmkolfonlmmmokmhlolkmnlnkqnopqkfonookjniamrqgjlqnqnjknlkgnnqplnnoonquprnmqkdjrnpiroonnsokmmijpmqloolmknplponjnpmoonnootykmpsojpmtqplnomjmkolognnrjpmlopnipolvmpnopndkknilpcnjdssomonujntmpknijmionulnsjpqhllrqmshkimlilnmqnplmplpllnlpnmsmsklamnllnljonpqpinljuoktnflnhlioojonhmknqnponnlmqojkookkmqopmlmujnohns{lsmhmogmopstollllkqpmksmiljlurmrspmhmoahqjjpmnhqmojiolomotnqoylpqorlpqnmpqvotkiliknvlpemrlshjkoononqrtqjilnklomqqlwspmtonlpomomqkoooooesrklooohmmnmnompknqpilsqoorppootpjoojkprmnmhjnplolrnoktjonqrlnooorqmmagqqlqcppXejqgqrpq{bvmrppimhptppfgmkgkfrtllebosmr`mlpohgimeoksohomumromoprmmrjwrmqmnput[uaiaiqqrmlb~lmiihvnmvhn_dgfrgditijfqfwnvphbpllljnrlqrqrrotopp`qjjnniiprpovoymarqssisossimlqomsjYlnoqmooYepkmellknmenmixlvkrrPjrpglqjnjjlgnYfrrilcllolxjeoshsmksjjnvoetchmktomkqnn[rnrmmqqjnqnqtlhnbipoplrmmgmosrktpgsnpnonojpjponrnempvnkposmoqipqnikfqnojvmnsvmlltmprgnnerriqvmnqhrslimwpmusdmppnkhlpmnvmioijojkwonplkprrqheokmjklokogopomgpqlqlumiskuormpilrmnmhntupnoqorthotwnlootpiljnriumqquullrqmqppniqpmofglrjonmiqpmnnlpjpiqitnukmuqprohkomjmomkinnlnnlornnkmlopmrqrpqtplmnomnoqpkjknnklmikinoopmpomnqsqqjmnqmqkikqlloopswhqpmonoppwkirmoomfnklmpkojlmnpololojmlnpppnlllpkmkqmpnpnnlrmsmlmnmnormmpnoqjkooqnoooqplmpooqpsjqompnrlpllofolloqpoknknrmmpjolkolmklhooksospjmtnnnoommlnlnllnllrplomptvpmsqqtoormflpiljlivrmkmnkkopnjqpqnpmnkkoonqolmmijrpnrnnmmoqntoopqnpopnmminmpilmpnnlrntmilpowmkljqgojlqoeojcmpnnqpkmjnmnnrljmlonqlmulpotkfmlnkrenmjoqnooooluqkkonmlpqpmpprnpkopnkoolmjkllmmnmpjqolpmrprbpmkpnrunlpoommhhgsorljonqmjnnjjnvqrtpmormlnsonorlphnmnllqpkmidnmxrrkirpqsrmnlmhmjopoorkokkjmpquppolkpzknvmrmonoolnn_mkgoollmrnmoqlmunimmnmjlmpnlkjoospjnppupnonkcposopklullnpumolnppmnnikgjkkojkinjqlnppjppto`nrmqmjmojikpkpopmnmrwokiokpppoptoqomqkqbnqnnpkspjjkgnmpqlflpkvompnnmlpnjnommqnqnpspnmnotjlnhlpmgkgppkkrlholonidiohvjpjnsloylvoprqjppqvnnoqgpghlilpqedkwqmnrrsoghlmiqlruamtqrksqpgjolnnlpgoefmmkVpgnprsmtto^jpu`cjufulp^nrimqgrohqjo}vnnobclkkmcpufonwkrpsrmoUsvlghmfrskotu{vcrokxrqmvueknhmsrpOplsnqlp[tlppkrdjqwn^rokxkrsojTqwomqrdphgpslf`vrpm`vomqrrqusrfnrnmjm{qgov{sqtnunnpqjemhfqiorpspqonpmmqmhjnmunonloqonlrjjmtjujomrolslpqnnjoopqmkornoinnkkpoppwmklqloooucxlplnsnnhroskmmojvqgloortqqkpmonkmsijmqjolnmfksloqrtnpqpmrrmqmpmnpmqroptppplhlmspjtnkmlnirpqjrshmsmlkqqgqlZmofnkqooirpoemokonoqlqpoqrplloooppllqjoolkopnmtkplorpqminnlpnnorjnkogroummknrppnmolqonnqmmoqnlpnqilinpnrgm_omlhmkrpmmniiooookognshmnoopgctpqonhmlmfskqnonqmfmsllqjliljgmplnmmlkimnmgnoomonlmpoplnrnklsnoohipnnokoqkppmdoomrmljjgpooltmmamjsnminpfli}rkkmrrnokhlnlnhrrhkpmlnphmktkenpmnnmkmlmnnrnhlolqnmrtmmmoojmjjkmjmknlkqnpkqrnnl{rronmmlnqonnosohnqonommmpsolompoxnmoohlqnkknpllhofknqroopqppkmkoortgqnlnnqoojohiqnumloowmmmlnnmmuqlkrklnmmoomlniojrpnknpklxopjnmolnjoknqpnporhkpnspnoormmfmromhrpnorinslnmmnhjs{nnlmpknopiormqmrifeqoljnqonmlpmoollmllmomnkomlookpmniqrmnotioiplnjoyllsgimnjpZqmtnmnqkkmmpilpp`nmwipklohnmnoommoskhltpqvjpspnmpcnpplknjpqlsnrpmlqkhgorpngkslflhoqotllluqmnpquvoqmpxlrvorommkninimomkqsmnmnotmnnjmvhpljgjkrpnkpcernlopnklknoqlonklpljjpinlqqmrklonhymljnpnsm}njypoqfplpsomjkqmlmhnoyopmqnnqmqjoiiumpolntrmqrqmnmoiopYzomniqopowokkirjmjppknzmdrxtqqmlgkkmo|lpomdoqlkoWkqpionnmpinojoikphgokrkkphjsknmsqpmirdlligpiqpqimjjflqg{pikkmmikkofmrnltol|qprmlnhlklpqnommptlljiptpmljumsviponkgklgimiunovplgnmsjip_tnjrmoonmkqpmgilnlpnrroqtrnlqlesopnim{lrxqtnttmillnhpipkmlmuiiqlmoutkqokpklnkrnrppmlnqkmjjkmoommnnfsjgolmqnusnokrpjukomonnmkjmmpnlnmsmnhpoomnnknkoofqmloiwortlpmjpmllrlnpommijlmpmlnmkjnlkjmpulnppognmkkoqnkhrporrolnirnrgompmmlimkqklnnjmlpkoqisiojopkopspmokpmpotlnngmjmpmnlkmljmfqovpilpspmnnojqknkpnnommonpjqnqkjnopliprqnonkjslomgjhnjqqnsmloplglnolmfnqqokqnekmlmhpoqwnmmmrpllpsyokujpknkrpoppnumtsqoommjqjqnooklrmomnupmjtonmolojqmokmooppqigmvppiqlnnmqprolrlklmlqkrnptoqhsjmqmirqltqoqnlmjolmlroqirnqrooqllkiinqpmlpolptmphmnslopmmpmswoapofmljsnmlnnuopkmnkmolnlqooroktjvnmqnqmnjnriloootnjmqklornqnnqkim{mrluqmwqdphpmnxpjrknkhjjjmkmnonjogpuklqjscnninojmhnjdnnmmlspmmkmomllrtqonmmmnqpoholtgqlXpqnsglnnormjhrqpksjjlmlmnpmpqmnjmrokmlnqmmlmmmmhmnjogokqsloosljmimlppqlrovinsknsiopuhlidklrnhiknlkngpzmivrmnmqokkp_lnmkiprqihmmlijpnlognlqnonoiljuotnmqlrhimmilolhljqqbejooqtoipkshmjoitkspmqmgctirhonvlahjkllgpjnohoomjphombmnnhdfqooqpmhmhqqkrcjoodmlmgrokqohgmrpqmbprnrjlklrongigonlomgxpqjresmlinkkspjqnmkmgjlimonssbpgqllngpnhnolsumoiphmsmmooiakroiyem]hrupiyknvnl{jpnwhzspo^qmmninkkmmoijfrmmhoepoklmnkompsljolissgsooijnjloimkshqnllnlmmnomknofnjomlmnjiktnnupiokmpkqmvrsnhsklljsnoqnponntlnqpqmpktsriirnqkrrplgjqnmnllvkumjigmnpollrqimprlrisonjoojqqommrnpohijokpmnfrjjntmhnpqplfppkhmorsmmloqmsiorqrrslnspoomnrnpemnpjsqoljnnwmjlsiljrncmpnmhmqnnkokinpqmrqrhqlimlrlswqnljmkmmipo^lipmnkntuccullmolholoqpjnokfsprkiljnhmdqlnqoemojl~nhqonkomknmnqyqoofnkollioioilmsslinrn`nhltnumljo`qjrukllosliqgjllmplhprijldqoopnelhgkmjkcnrnonopjnjgnpjgphikptjnlojgmqmpoosiqkhspoqlniqornbongjimlqdjnkmmqoisikojqniolpljmmmikljmjjsllokmmqnrormiionkmqmquklmpljmolproppomjonnpkrssqqpmthnlnlkkrnmfmiinpspnonplnh~imlonnomnnkqqjmmpoqhqnrnijhmpmqnooqmnqlqjmvjqmnlgnminmlnosolivomknqimrilmjronpimhkpujqgomolmkpjpmpnpnmsipmlrnpmqppsrsqlplhntlnomkooqojmllkldnpopniknfljnhqogtpnnjfqposlomopknlnmongoopkmnnrntqsmmpprlpnpkmpmrloqkppmmnlnkjrnltpspmnqoijonnjomofsgmkkkrnpluonoqprrqiwnqeqomnislmopcljsnnqlmornrphmongmmjsxlnmnosmiqnikjrmpmkfplmpfnxolkrmnnpppojoqlpolnlnlnmpoknqlqnnlpnjpmjqommommpoqouofponmmnprnkkkoomsolkmompnnjonjmnnqnpolnqjoolhqnnpnlqnnlmomjtnqmqoionpiqlqmmknpppqrmqiqnnmphknstponpnqqlhnqnponjngmxlopmmrnoklnmrnjropkqvlmqpmprnlngqomnlmrnqlpplnjlklnmjmnjmphsnkopppotsskpnrqnqkrplsklntmsmnmkntnoooklnpnmnkpdnnqnqlottnirskolpmoltpnqnhnslmkjmjulnqemjlkkqlkvknlpononlljlruppjjpllnmknoojommrolplomtmlmnqqqvpnmropopnolmnnjmmjnirk^aooioikn]eklhqwmfzctoooomolqwqnlibpbp_mpmhbakpjiiltvpagklmkdon`kkqielsqlkmkihltnlpklzvZndcelxmhql^}mrrcaijhnkm^olhpijmmhmjnfwpsjh^pikfnnlpniqmomonksanjmnlduwnjkujypjllnwxowhsgerjsnsh^phmlignPljmrmimjpinprrphlollnVqqmlgponkkjgn`krpni`nmmmuomrsdmnnqplovnhelimninoipjjoonqlnpkplpdnonnlnvlmlnpirknnlmovojrowsngnrqklnmqqpotmgomokplknpnnqtnronklmlsjnmqjpqqjojlmskqmhknormlhkrolsqlumqpnmlonmpirloqsmjpnlqsmjlkknjnjnopmmqmlkpprrllljooomkmnlhovqmqkinlonhkemnqpotloqpjosolxljonnotoromnjnqkplkmomrmoijkokootkpnrngimmjoqrumrsnmmkjimtqpoqonnijeskollcjqpppjnp`rumorqvnfjrnlknpoqmqnlqqjlprollmnqoprliyllkksnnq`keoolnmrronmnnpzkqrnjqlpsvnvgyrqnispuoojlkpooxjijipqmkmjjulggpoohlsjslpgjnmnjomikkktlnzmpfqllrljqksoohmqmeqqlqmpmmiiwomuosqtkgnntiroqmnmmkpgnsonlmprrlrpjoormponpmmnjfoximil{vnfnmnpmopsmmskqpnllspjnnksqogkvnnijojlnfjkjtgplxmhroqlnlttjnprkmnniiokjjomsoqmosqfmpo{lpoirjqjpmvmkmpnwmppjjmqotkljlmkropnmnmmpnnmjmlnmlmnjjmkmuooiqnrniplkllinlmogtlpqonmkmkhpinpmowuvqroognifmontmqnkqpvjlopmjirqokjulmmmomlluoqnmmrqmopjmloonhnonnhminllsrsmvjnoqjoponstlqprlpmmlpqohmnjnnmllnqommnpsrlrjnkijnpmnntllkornnvjmkoklonkqmqnpmqnmlwpoljpfnsnlgpnollllolmuorsqlpqronmruolmlpnilkmrtqnnpqktonnnmkjjqijomoqrnfnhnnpmopnmrlmmrrmjprqlrknlmlnoqknlmmlnrmkjoneosonpliokqrmnmmlpmnmnosmmponpijormlllnnlpomlooqkmqslrnmmmnmpnqnlkokmlnqnloknnomltpnkomnmjmplmlnlkumoupjgolmrpkcnnjppokhlmsornopnpgnrjmkmionlqolkknnkjmjokhpmnniojpjrqplrinllklgomqomnioomiksnlllnpnkplmroqsnmpfoqnklmmioqkrokpjioworunqllorkonmkimnhmnmomqnosgljmjnznklolqlmmpooplnkooknjommnnnpolqnunlnposnmrttpmotkmmktoklmmpnhlkqkqmrppgplnponnkllqmknllnmmqpptpqkkomkuknpnhnnmrunikkomphplkkmlminppkgokopminrpnoqpqmmkotnkmonkppmmmrsonklmlorummmmqqojplopiljjonmlnnoiiokmpolsilpjgqnqnknjnnmwonroqnlollnoklmmoknlrmqrlmkknvmntpmqspxqopqqnnnonqkmkmokompukojnlmnonikekoklnomoookmnvhjjlnujolpkelkkgqjxmrlmmfonwlnklqpkrmnhwooplrlpkjmaslomlnskjmpqitomoimkoikjirinpprmolkbqpjltvolnljkukhkmirnrqnagsnqlimnmkilrmpkolmnkokgmmrlokilqknkiiobnmlahopemqpmilqmkmmkquobklogolr^khlkqlnriqlrplnswlpkkiqmqmpplsokqtkmhoodmpolproqlhnonhnpppstqpnoonjnilolomnqomgrmhklpoonlmonndplolpkqmrnjlppknloomhkknlkrksqnoljqmmkopkkknomokmqonoojljklnllplqljlnkjknpoojrxnnlnoplkiomlnlkkkorkpnllnqnijjgopmloilmloqoqpogqolqmolpoowknkosomkklqtljxlolpihioojmllmvjmklkommuejppkropuoromlonpmolknikjqkmmkomnomnjmoonnlukpjsonnlsroptnppoekmsrsnmosommnpnmnmmonajpqnloomjmmmnpsomnnsjljnpollmmnnmppolpmnonjnkmlgjnlkjtrooonmkjnnmlnqbunmiqmkplqoopjwpikpplrnlnqhooqonooplkmplvohmnnnnmnrhnmkmgpnlhrhmqpoqnolroqqorjgmkqpkhnnlolmnpdomomkulpnljolkmmkpuplnoqmkmtnlmpmollkqnmkumpmmpkhmlioglmnooponmmjljimoqnleplinpsksqlmlkoplmnwpjioomjoplmnmrutojljmgsqqqmjmpmkjnlooetqmolonlqtlmpmomljpinlriniphmshfolkqmomofmkplpojfrnokklonmonlrjrklhokhlqngslproinkhmplmgnnonklqrkmsqlqmnpntsnmnmmipmqnlfkqolkslmkkkmoplmwlqhwppkjnqsqdnrknooekkkmmrkqqpmpiilokskkmnlpmnqminrghnpmknjnlplgqnkmpplpisqqpmnnhnomnknoptkklnnmokorkolykmqmppsmnpojoihpqpnnonimoprmpgotkprqoojplomnoklmpolqomlpohmlqiopnnmpnnkmtklmirmmrkilnrspommnqopmmnplnnmnknknmnpnqmnqolqnnjknfprkjrlmppqnsnmoqolnohprmsnmpkiiopnqpunnknonornpqnqmnonlqqlrnommhmmrqsilomsolnmnjmqsrpkokmqqkknolnpmnpkopmsnjlnjoqnnninnmnolpqglmhlnlqdqoninmkiomkhlnnoqononpllirtuonsmmollplpilpvkonettlnnnrnnlmpmogtomngqoipnlqgnqlklloohpqpnrqrormlpnimnnspfppktnknnnkonpppnsjomhpqnmnhokumqpllnlnqmndjmjotholjjkorpqnllooenrmnlnmrnmqpmkkmkkjpojpkonnlptmqnqqjljonhknxohmrmmnnmmoponjnnorpmmlomlnjmqlmjrprlknqmlomkkikonqppgmnqmlnojjmqonmopjjkjmqoqnoklpikzomkonqopoopmlknokjoliljqmnmnjooqqppjnnonmnliponnlpllkionqlkonqlrmiknmollnzjknnonwmtopplpnlhmnonvkoonoqknilopmmmrolmpplrplompknnkloppnjmomjknoommjomgktlpqoonlwmonskmmnannnrlknlzllltqrrsnqknjipsminnmlpnmoupmpqmknnnhsgkrorlnqnlnnljonnumnongnoihqmlnmqpkrlmormslhnnnnnolqkmmlomljnosmpjklnmppmplmoqmkrpnmnnhoooploqnolnmopnmpkmlhkmompnoqnimlpqhmlpqilopqmpomjuhnkmlxpliokfpoqfliikrkonqnsmnknimklnojmnmlnrkmpoopmrmrolpngprmoqlllmqpmolromnnppiopolnskmoonimomppnllmknnslpptmomkjlplpnrnlnnoopnnpnnmmnqopopslnpoqoprmirnjnmeolmllmmmnrprmmmnq|qnlirnmmknlpklnroqplqmmpmnofnfoippkhjmllonfpnpjnlplmlmkoqilinrnnqnfprlpoorqmlpksooojoqllioojmnmqoknmlhmohpmmlpooonmopllnnkghnnmnmolenkoplpqpqropmslrsotmoopnyklommkjomjjlmlmoqknmsmhsmoumuqpojpnhmkkomjqllmonnojoplrhmpqipvognnomnqpuqpnmnrklpprjjjloilroomrvrqnmrtpplnmmnmuhmmjllknxpkkonnmlimjojopmnnfkopnjnfnhqtmomjkvqqpjnntllinpvlnkovmspnrntsnlmnkkkuqonwrtntgnlolqmqmotpuomnnppukskboiinlplmlqxmpnppronji]lmipmnkpqrmilmshmmomqhnnqonjrpnqmmnplmmnluljjkninmqlqgpnkqmnrponvilmlpmnmmoljjolpiohnprmslpkpiqmukonnpjmlkmojpwknhmpoqgllskmpmjnlnkmhpjommqpjnpmjliplsonpimprqplqrmqroomhqonlplznfflfqmnmlmkojnpkjjljppjooonpelolkopnmngmonrknqpnmnkomknpioioloqsorrmpnmoojknpsopgipoqoqjpmjcinnmmniknokkpngmknnkponnrumjpqqslpnnsmhoqqnllonmnloqmljqnqdpcmgonlqikqilmppkqnjolslkuknkjtqmlnpltoknlpvkqqruoojsmmnqopqolqnmknsgoknmnpkoqqqqlpjnenkjqoslmllpmmpmonpqlmmnnnlkinknnmljjmnnlmoliiiprsonlqpmooimnjkhopononmmjlohlnqnmmlpkupnoljkimupkqnlrjvotmipsknlsjtvoomjghmlroqoonmwopgiivoommxkhnmqoqlopnnnorlomgpkhnhkmjprpnkrojotqsspmqnpplnmorhgqjno\mlqroqoqlknsmtmrmlhjuqolnorsg}rklolomqmnkmolnjemlrqqonmiidjnngkiliqooksnxiqpvsunnlspopwltnkokoqespliknnxooopjshrlhnlmwnjqnimpjjmplijqejmllmoroootlnkneoklhpkmpoosmlnpnnmemnqjoppmrloompmhmupllnmknlhlmrmlolnojfenmkqmokkknrjkpoonlmqoqtomqmozhmomkkmmklkpohmqlhsvmqpmnioqgnjkompppkoqjnomrkommjmmqmrjopnmnppomplojlrnlqfqooomklpkpgwmoqqlbolsnnjjoooiolqjtkfqqlmmlomnokpirifllxknnnrqnmoippqmomkmnhegjnmmpmnvltqmqinmlpnojjn}jqllvwomxm_mnlhgjr}qkpjpfldnobnrnnimmpjni{oemkq^mlnihnnnohwpoomlqoskljorlprpkmmljxsmgtnpjxkvrlqjtkroumpafgnnol|hlkbptooklnqlmhmnqkwplujqkqknmnrqkrolmhpgksrpkoooptrujjglsngmmjtrknjpemqsbnltonukrsjlxi`lnYlpkksmolibothkkpnnolomorjrykjxlorjnmkmnropnimnmrklnmknhporjuoknqmlnpnoltsoontlkpkqnponrsnnuplhlmemoqnrtojnmnjjppnoqsmmlnmpnmtfilitqotqnmkopnroloqslqopneoqrnmomolslqisnjpikoikopqlmrpmqqmohpkknmnqpoopirmnokpijnrnnoookmlrmrnomlumlfnllkmjopmsksrmnoonnopnnjmunsmnllmmortjoknonpmlnojronormnnopomnlokmmmpoliommrksijnpmmjpmnjjnropompmkltronnkommrqllksoptkojlnmtmoqmppliqmnolrnhklmmmnmnlnpmmnrolmnnlopmpoqnknolkolmqsorlnmmluonlkhqsvnkkpoomorgnompolopujlomjmoogmnqploinrnlpmukomlomookelvnrtokjhgpoonpnrmngnnmknpnoqporkkllqnrkmmkqlqqtljnmmqnnnqlpmtipkplljnlqtgoqoqrjjlmfsrhhjomunoqqmilnjlopksbooinnlnomsmnokmprloojpsjgrrhiqmjoniinjkfepnbrnpokinjmqojmonmoqmfgpjjljmnruziongolpmolqjqcooemgqlgilskjmpjnmpkkkpkonltnonhmqppomrmioejkokpqtpoplrqmpmopljrvnqbinqonjoloijhtlfmoomqgnkpmqhpnkgojxpntmlnlporoommomilnqkmjlknlnorrqglpnxpnlmlklrxknvmvhlovoklplmqnpppnkpkyqqqpfolrtjmljmlpnllliiv_osllfioonsroqnphopmknpnpvnrlkqllpwmnlrmjpskkmorgrnjmqpoevirlnxworpgoqipmnjtpmqqkklmnqqwihmqrqirupolmqkkkjjpkiqnmpsmnspnlinjpnmlnqkjniporinsqntrqjnoxlhcljjvqpymhpkqlqtokintrknsqonmpjioxnrpmonunnqipqloskyhqqsormfkmimmqsounmnjqnrmupnnnkqnmsolkmmmnqnmpqkiilifujrolllmnmmpmrmjnpoqonpklqijponiplrknklntrllqilqnkqlloloomqplppntlptmjkqohnnqqlimksnjntormmsrmtimonoimpmpojmprympllknmujmkpremsrkkkmonjillmsnnnkiqmpopnkpnjppnempqmminkqommpmnjmnlmlmnipmqtpoolonlnnjorrmklsqoupoomnvhpnz`nprlroolkkmmonpqqnoifojno`mrnltgpptgmkqjrrmmjqprogovkjjmqdjonoqvinssopqnqohlhphpendoomjtjpcigfiwcknqdooknmsntjpklovpmolmplopnpnngmoqhrirqlnnkojpkj`poimttnpknnpimlmtriqkmenmunqmlqwk{omknvrsqjlnltlitmgoijiwrjyjohrrmnqpwnqhollpoptlrejumkmklpuqfkjrkeblummirkfrkolkqpcwhrmmqprkojogmmohkejmlsllslknkqlpqlnipkorjnoojkkoptinrhmpmqrpuoplllqsgnlojplrknnjnfnnihdnhummghopmmkplnmmmmporoxirjsrhnsgnornqqsmongmjpqoiopnnrnnrucjqmvcnxolkrlriipofiqoitnl\oomompinlvlnomrrqrpsphlpnotmqokgmmjlfpphpflmoppnhtpminomqoprkqmfoqrlrm}tq^kftisnqyuxmqllnyqkimrnklomkmbperkwmjltigmnntizpngpqmkomsgkjsolotkmmofknolhmlo`lqqinfniom]drmnedqnompnjniilomxqmqqollqnkmmsijjjqicoogkmumqumkmqldrzlgolnnnpmmmjkodnllmrlqqpnmkjppikpqlonlllglllvmnmpohjmvkmicnijjqqqmjomdqpnmllkenoqrojmtjmpmllmrokojtmnonrkpnnjmpmlnkmjnptqkqnogoopjllqpmmnnmruonmmlnoolopmpjnnoqnpnkjolnmnoonnpopnlmnoqnmslopoormnoijlkjrjnopmopnmqklolpqimnnononomwpjopoomqdkmommooohmnsoqossnpllqnqlplmolnmmqqlnhnpjpsknlqkojmprqmknisoomnnimpskmovnojqojmnnpnljmjpolnoooqmoonlmrqmoupkkomvokrojnnokjmfjmnqnnmmjjrpknrjnpnmnhpnoqspjlpnjnmqholrmyprtioqsllmnoonqpljopooplnknkgqonohjskkkppimjhpfhpfnoqpplllmmjkssolndqmmlnpmiqnmpiqmmmqoplpopgotmoomlmtqnnhmtpjpmnzoqnqmmhippilkoojqnnqiomnmtnospmkkmmnopmkpntmqjnhopipokomrknnoolpnmsnlonqjnmlnlmoqlnmlmmnjoooqpshjknxjkmnqmfmnpmnslldoqopnioljoommmrnqmivmpjopwmnwjjkmooinoiihprlsmqpmlmqoqokmqqpnppkrpmnloihhnlqojjrkplqoollikngkpnolmjongjmllkprpqnimrmoklnnlulrlpqqmpmmknpmrrknonnqkmospnomgohjkpilnlknnonumomplclppmnnnonnkgpnopsmoonsnlokloplnoplnknmjlhlonqwnwpkqqilmillsjsouoynmmnjkrplinnsjpionopnunmnnnpllhpqoormnommrnqoppnokqhomklwnnonponolopnlmoopnoigmmnnqllppllrplmolponqiosnpjkqoqjnkskqmqmqmojlmnnjnonntptnnnkmnjnlsmrljmlntlmnjklnkmlilonomjdnlspmnonlpormsoinmmqplqgmpmmloqtqpljlmlmkjpmlkmnnopnjlmlidqrlknjmoqmsmrpnlkqoimrkljmpnjolsnjlkomookprmljknmsmnmopoojlnnnlumqnjlmoo|qomonmonokpsornpmmlnjlllrtpnoiokdjrqrkjpkjkmrmnophrloomqvnnslqgnuirrnlnmnmnnrpnjpjoklotzqnopmmloonmqinknknonngtoroqmkfnrohkrpmnmpomlpnikprlimonmmkpololmlmjjnrknqiqplomsnhnlmlnmnqklopntfnlompnmomklqqpoiprmgnoknqrlkqnjgolskkpjnqommmonnklpnpnmnmmkmnmimjllnnpfmq{mqmunmkjkniltonlokotonnqrmmogjpmmklilnmkmsiponhlpnqhnimnohlmlonlplqkmsmmmkronjnomnmqprsoopjorrplolnlqknomlhhlojnlkumlpilomomxsqknommrlnnmijlplpnmuimknokiokimlgpnoqomntoonllmmmlnosjenltpiqllslmppotooqqkmnjpnnkjopnoqmmropomgnioqjnoolqkmpnmnpprnnorkjqnpmjurmopkkdosnmrmhlrjpoolsrmmuonqnwokkrlnopntoorompnjmktnnmookpjqoolvpooqllolonknnomomnnqpmhlknrqnndmnmmongnmmlnpqyommnqqkjpnrnpqoqfmponlnoukqoplkppqknojlnnlostjprijoknoomiphosomrmkmonopeijnkomnmimklmkmilmlonqmhlqommothlminlpqpmgqnsnloneslsmlpileunonomoplmriolsmlmmmpknolknojmronqtkqprnmhnckmsmfmnpknthgnppknospnpmhmnnnokletsjolrjnlmkktktlrsmkuomopmqmpkqpotlrpmmlmopsjrpnkpnpljjpnonkwkpvilnsmpwfojrqbkpjhkimmhomnlkjkrhsopulshlnrpooipnamoigqmkolnlmnrnohsimksointotlopqenoqplkrihekhfjopesjpcjjojkmrqkmkkolilmwpllgnqqrgmdrsqiqllkikoshjlnnliljmnqkqomppsotsopbolihotmsoogkpomhkpqnqfngjrjlojnljmsommpoqqepmplkmpkmmnmmrooomknmmqujnnlpimnouirnlnnsvwpknnomnqqinvrnkiodikgnrmmmjmkpinkmsrqplollqonnmomooonkhpjutolppqmldomqnnjqokpnpiqdftocqowwncgjnjplxloxivornhji|rqphlrzplinpogjjxjkr\ngxoolohjoljm~pnnnslkrsqirgolorjnouknqonqlgcckkatmyrjuonhtiqbgnporxtlojlglkpmstpmskuq`hnmhvsZtnriyn`pkrnmenimvklmljipqhegbkkopmmxmq~photuqmplqsl|jwexntpeglniimxuas_ljiimmejnmvkqnlrgrjmrtpwntlqninqyilm|vnoqtrmpkommqpghmmmmnrorqpnshlmnqnnrnlnnknjmqkpglnkhn}pqlsnqkqqouioollnllsnnnpoflnoonvnpnllolkhoejnmnsmnkokllkplnqljllnlskpqqmqquoohnpoolnmkjmmonpoppronnsooppqpklmmnmqsrkqofqjlnrtqpenmmioinknnmlmomolrmmlmlonpnomornpqqpmmlnklnpnpmlmpspmlqrnppmdnnkrnmlmnkpnmfompnjnptploomjnmnpopnnmronjklroknmmmmlnntpmnnnjopspnooposoqnkmnikhmnmnlomnlnkponhhvonsommloonkmrnoolmooplokmlqonolimqolmoqmsnomiqsopkloostpknskipnnmooooomokspnhhpmmninnilnprpvmjsmntqmmlkqnmnjksnkomqfkmkmojjovhliqmnlnonmonlnnhpmsnnmphnnqmmnokxnnqosqmpokmonkhmhopmpinmlroroinnljnpoplnpngnmonljmkakqjiokuljhjjgpilpoqkokmipunmnpnmrpmmhlqnpinqprvnpmpmdlefnloohkslnnsnknjupqpuuklrpmmhmomjtpilmjqmjlmuv`nkomtqntoqhovksrdjniuqmmstiiqppqqkopllkkrnlnhorgltvilkhkliore{jkjnonlomjhr\joqknqglpsohrljltqtlpnjppkoukoomrsmvngpnogceqnjoaqmffqjisukfvjvkljphicppinjmnpemcmriqfitoqnnjzsnnokpllppi[nspmqjonnkononirlimmjnw`lclhynmenkctssoebjmowpjenliknmmnlkpmhjpuogdmjogliinpjrkkjnoqojldnmvgimmiopjpmnoloorhwjrhfssnoqqkkkfowlo`llpnlpkmfrooimmuizmrocoonkmolnjmmqpfnuevnlhjmgnnorpgskmirnovqckvfspujnlcmjvljfwljjqwlpunqjtshitnqmsm{kqmlywrrpnjok_nnqjnpnknrrixlniospikmspmopqnppnimsmo[s^mgnhqrrnrkggskpqnskmknrknktooizikqndjmgiupmniomlojrlulnwomojufokomhukprojposnnkoqkmsomprppkrnjqoxdlmmijpetloivlldlqkfkbporqoopjqvnkqkrlnquikrppimhkppjpknpkkilnqrsk{lkoqujvgZtngmnkqwroqjnpjihppoliskioepfonhlefqtjnnosoqlpjtwpozqoklnfmpnommmqijoqkomlpgpkiotkonojguspmkgsrlqlnebsjnojnqpoqidkqmqdlmlllmsjLooomknromnmnqljnljnjqpoptnqqhroljkqqlmkklkmgonkhqjlqvkvupmqnlfrojqnjlnrpkmgpnmlqpmnodopmmiokjqhmlpqlnrjktpjmtmoknfgmlolnommsluolkupnohoqsqrqnmnnnnnopnoknknijlpkllgnclipmoqmuoqmqqohoomnmkknpojpqmkmlsmmqrnpjnmkoinmnnnnqnomplltllslplkomrqpkmrionnrnrooojnl{oqanpnnmfmqnmmoomolpqmqnmsmmljptnnkonunspioelnjmqoknkpnlpmmpnpmlmmlpmrrcnmomnpnlnmqnsmqjmqlhnnqgloqmmjoovokrnplssnkqlijkrmnhpkkoqknprkpnmlnjophnoprsuommkljomnjrskllnlknopnrnjolmmoirorjoolkmlnrnjpofninmhjjplopnpnlwljpnmlrmolllkmqrmoooymnnpprpngmlqrnqqjmiloumnnnrqfpnmjpnnkqnvlmijodmmnrmkjliqflmhmltknnnnokmlmonjqmkgiolgnnqnmornlqkpqmpjrogqlmmnnoooqmopqlmoplnjpmnqmmomnirmlmonnctlqhoojkmrnmerygjeomonmgmcmiopljsuprundlqsqiplutevkrprunpmnlvnmmkphkppqeoplkmnlytmjjlepujnkzjiqhiogksorotdlprmmncjrkmljrokrl`lrmprhigsokkjpjmollohmpfomdqljkhkmklnpolpojplnloomipojqikkhljmnsogujqmosmoqnsrlnmntlemkiwpllrpklmtnqnqlmrmjjijosnmojmukompgpkntpbpwixsmmnz`mjjlkkpwqtvopsnqixonsjoosoonhnolnrnqkigoopgolpnnttonnksnnmjopomlokmnpkrlmlkmrpookh]hgki[ijjpenhlpdmnfvlpmsmjoxnij|fmmmpmpgnnjflpnnlomnlkmpnmnnfgwkrrrlpnntpimnluornpnnttipqhjmpnlunnhlmmklskginmmuqjmosoioisoljyogmprnikhpomonjnnorolkojodrqrqsmnknmqelmoookqjjkromilosojnkmonnmnupppmkjmllhlkjvjprnqmhoerslqnmjvjnmppqnmoiktmlkniphqktvkkprjolkmrppmnmnqnrkomhqormnhjjqlemmpljnmlsmqlsnolpnmspcnjnknipljnllonhngqlsrmrnnnlnmrnnllkmrltpfloohpqqowmlhjqlmmnnlnopjnoilkrolq`lqsmsoqnpinmnklomrsqljnknkgnpnopksrmmomcpppsqtnnonujmkqlrnjlpdokpnoploosmmnimojnslgirlmropfnhrmrogmonhunrjknolklqlmkrmlonnouphrnrjkicikqrnnmohtmlmmnkoponllkllnmrfmponjptpujiklokknmnnonikpnqsnoljpoqnolsmlnnoqmpqophnmkodnollonmlkqmnlqqeomnnmrmpnllommntnpiplikkkminqmponqklknkjorkmoonnnlrnppglpqjpjplfxplarllhpqruqlloihnpmqoolppnoohnsqnprlhxolipq{korpqopljtomuffksinlrmuunonqkrmnhpknmsnjqohrkwrisfiqeloojioeppttkgprrmosrrouplxptppkmpkqqoltqlpsovorpoohpnqrvmltopnumprtqjlnojoqojlqmrnlsunpgpsskkmlionsrqffqelkmjoeqrpopmtttlnokliqnpmttykrnjplpqpuioioproqolqyhgtjqrljkplmhojqmoprwnmoolonqglnkqgjhkmmsirltrflkjkkojnrmilmmphppinsrkwfmnnnmnjpijsippoksimlremprplnirpnqpbklnrlqfrsmjlomnlpjognnqijohmmnkmkkpoopkfsknnklykmnkkmolqmjplpptopjltlonponhgpmekqgkbpljmqnmjkvmunjlonnpprpon^oqrnnqilgomdhcnuqqjdhookqnsifojlptnqopmjtpqtoqqntslkmnupmllljlmoonmmnnlolnpqrnqokjiqrpmlltolkcmtmlnktjmnsnmjnmlnnfntnkkqnntrokqomponunnlkemnkmemlmpolnlpmlmljogkjlnokmjnmprlmonnocnslnnlonljomprljrrmkonfopkmqmpkjonmnokmmnnrjrmlomunovolnlnmnltkommojrmlslolkrqqomkomlnkmnnlopnojoqmhoimlpornlmktmsiikuolionpopnprgoppjhonnnhprqmplloopnlpmknompqoknnlmohinpslojpnpnjppqorllnklnonrrlopoptynpiqokomlmmklknmmsmqlqoknnrmmnmjqilmqmlshnnttmnnnrnonklmpnkmplommpqnlimoqhmkjknnmnmmmsononkknomhjonmnmjesoplqnlkqntmqooppgvnpospqnpitnnpnolnnmmipknnjjmjjlppqmeukmqkphjlrtqpevqoopsjnoozhjprlploqmxpkmjornnoklkplqqopmtrnmpmjjdmjklqdmopihgmqkjljmhmnruoopqpdrouigpmnommjrimsjolqnlikgmgsjrjqroosjmqthklngnflopsinlnlovqckmtkkxopmqsqelnlnkqsoeplpioqjfmeosdomrnmonkhmnqpplphllrlphxnjiilkmhsksdopjlnnnpnjmnomotmtpqodmoonqllopvbwnslinplqrorhl{nnskmennploovslvqlskhuojjoqmnokxjrimionpjpjpqqlrnqrmsomrlsrnspokmqpzpwnmppohowmllkknnrqmnrojtohsbmrnqjkkiknqrlrqmlwlsnnnpmomnonsiljqjuqnqnlnhnpiqomkpbqgl{fqxvnpqromllpopppomnmnqqlmplmnhnppnmmolqqulmooqpusmlhhojovonmssmrnnpjkqomonkpjnmkopmrlsjklnkrulomplzgkloinkmpqjpiqmlolnkoppmnjkrjlomkkkrypqnqsjplnlqnnpmmqpjllmnoniumpnqoppunplphnpqrvrsqjpqsrqdfzjlpmoqjlkjmmoqmjnujnqolstlfiolopqokqquqpqoonVmmqmrlihsromylnpujppnnnqkijlqomlokplntjsrmmgiqoopjkmrlrpmowqpsoooksrkoolindjpmonnkojemplillopnymrlqnpqqykpmpkippqonmmrlojpphojqimiimkrkpqpjljoprnomnqmlmijpnproopljsqrylunolgmmlkkokqinmkoqlnnpqntjiwnknioljqoiormtqlplfrrmpnogoohlmjspolujgmkqpljonnoojjpmlsokkmlpnksinllnnmnonnknmnkmkmpnqnjoompqnmklrjrophmssktovekopnrrmsmpmosolqloqkmkpqkpknmmkhpommonoiopmqmpkoqpqtkrmipmjolnwibcpmltfnqgtrnpmnigtdokpmojnlmrhlnipqml_jxpnhmokmrVmqnmfhlligmonZsmrimpmpjkjkvpfopttinmrgkklhouhlqj`somgaikljlnremplkqmkmmlimmtnooigkdlpglruolsmlnprpncormineqypgptktmdwnnroqmnqlsqmnlrmjnllpvrgaqmkrjrohnpqgtojpntmlncosnnqnqmkllojfjtvtqkkoptqoppqnemoonlmrmho`bcrpnpfqmYcoviunlgucopmqrhjkrrinegkkmjanoknecenmqsobsolljlimqqpknonlnhqopjrlmnnnqnqloowcmlqcmsq_ilgsqsrccjjotnmfbqjppgqoplsoempypqkketklnllplnntkznolimhlmlgfrlxmlnsxfommrkrlppqenqmhptelohmqshVcllokqsiquohmkqnnuppt]oorkmrjmlul\nYkrpprgllsnujlnlinjonlenxnht~dnnklm[kllkrkptnnhejjlknlprokmmhblxolfpolgngknipkztolkopontnjrqkjqlgq}iqolkhrnklnapjuqnkngkmkvmmgrip]jkjvknn{qrjnsholuillepqpfuoniorlrlpnkupbjmopjoprmgrgklismlldhijsmppniimoooojmknnmkunrdorrqmilx`ktoj}pshgllqmtjlmptogtogpqinwnkmkshppgvklwtmeonnpjfrrmbprmqloundqoolmpmpqjfpkomnkoqpqonmlomhoinfsonpqlklmslojoljknnqoqnqkkgmlkskmmpompoplosmgnlqsjiqmplltlonlfqhhkymmnpnkcjkplnnotlmmhnvqkpgngponjoomqolmlolsnmonnpqjjmnqmnoormelmnqksimoponplpnrnkkppiokmkpnnqjojnoproltlllstirnmokmpokmppijoooolpmpojmlfmrpknmxmknqnwtrhtmjqpgnknquvqrrmokilumtnnoxqlpqknlrynrtltkmmmejitqopkhomljopoqrmpllkilllkjnklknfllqrkmmqjn`jsklnrmqmglmpqospnsloslpnpmppnhpvknljormqoqjnrrononnslrtpjntmomjopohpmkqlmliqmqnololin{ttntjrmsiksosjlnlmninzoooprptmkqpsdngmqknspihomqmnnmrornljrrrnpmlommqmjpnp{pkmpofeounrohlokpomoqrrsnqonqlpnpoqonoonlnpmignplskjqioprpnmmmqownsppomoqqoipkioplklqpimlijjroknjlmoqqspnomqmrkpjnkkorjiolpopnklmnkllrnlpulijnipjnlppknnnjmpmknnprmnmmppoimo|mnrnmilnmnnpjrkqngnlmjksknhrmtkqugniuppjtoqmnilrnonmooqkmmpourjmkksplprklpmkkornossshwrrqmnmqosdngmnmjvolkmmfmpqmppkqlroowoepirjthlpooqmotqvnlmnmtmrnrplpriphorpooliqkmkinpmynkkrknknonruqqonljrttjplprkokmpspnmmlmommnqomnlrsmonqjqnihjomlhnnmlqknmhnlmmjsinrijlrnmknjflonninrlniiqnkpjkkhutnkqjnoivmomklsjolqknnmmlonrllqmqrrnosmmoinqnlrmiopnklnjqlpnvlopmkkllinonljqopoqpmomqnnpnolqkpmnjppklmmnpnnkojlkmmoqommppnnolnonoommqoomooosnnmpjqmjklrtomokjvlqlkqmnmklnnmonnmjmporoomonlplpqnlpqglnmmnlmnmpnnoumnonqonommmmplqsophmnjmpnnnrloslnbqqqllpmpmmnjolnnplwqlnpmllonmololloolonmnkommpmompoqnnuoopnnlloktnkqnfnvopnmqhnmrorgtlkpkomnmsokruxmslolmxwnotqfpcnormqorjpopnowimmogqpknjzpomqjkojnrinljopoqprklmivgpn`lpoqestloinonp~rnoljmnokkokmnjqlplomcjmklpppkqpkomkmgkjmvjrvkoloostqlno^pqkojnnmlmprrrmrpotqkjmkmsgsroopnlktsromnomnilmplhknlkmlkoqorskqhppnookiiiqmkrlrilgqollqslpuqskhlbjopmjqkpqlopgvkrqlnprnqlnmomkpjnmkqpgslnomnlopopoiknmlkikmkpklnlmlilihnnolfnkkisnmmomomnrjmggppopjjnxnnhnmlosqoknmnjqjnlqkspjkolnilrnqlnmmkmoqnmpnuqppsormlqolumiopbqlpkqkjufrlolkglpqnlenlplkoknpeuprlmnpoonlnqoqmmroknocipiknprplsormqnmjpmlnpoqlmkokksinlmnqlmnnommtnklooihnlmpomlojnmnnljkmmrnmnkoqomommmjpkonsqokloknunjomqsfpoppulmpmoornkkmmqnnqiolomnmqktmnmvqltlnnqoomlmqnkloknlkwonenpmojnnpsmmorknmnpnkeoqoomsnmmnomkknxqojnpmrprpsnmlqpmsjmnommkpotqlmsnpkmmnnnnnrpoopmqnmnnonglmnmmkllpnnoknrllonoqkoltkqvnpsplmlkpqhmmqozqooqlkmlrlnkqqqrrnllmlpqqoklhmprhmjtnmljomononmnnpmoooposmhkilmyomnrqpntqkqomjmeqqkhliomplnknlpjmtkmoqolupoopcmnjopojijlllnqponpwpmormqsrhlomnpnrmkplclwrminqtkmnqvsqjomsmvpljpopsleionpnrplfooisopntlnnmokopkpmmptnxlmnrjnlriplnpiquppoqlsllqdrqpomooshlojolmoolmkpwkrkoqmrklkpnhnnjiojmmmninvngooklolmmlqejnmelpsliknprsmoqllnpmoljkjnsgsmpsklqklumopjqlqpjqoonnsoqnneklfnnqnklkngilomopmhnginkmsjinhonnzklknomrmqqnokpmkmtojrogmmqrmqpliqlnouilnjlovkljqgpmslfnhmnlpnopqokorlpomosnmpqpmstjotnnonlnomnpshqqmorhjlsmpgirplxujnknnokonokpmljgnxmhpjkjrosknjxlmmmopnmmlsllljnkpswsimmkiprjsompjhordkqkvohuqkqhllsmoqvntklnnnmomnnjtknonjlonmleoinjplnrnmlsilhnpkpl`lkmslkrlisplirjinmjnqnnlmnkotmcimjrkslnikmllpkgpiponbopnunmlinkgmnomomsjqkopnrejohonmdnnipshnpohqrnzlojoppnnmornoonqljmnmpkshmmpnrkpmkplnmlnhlprocmmpnnoqyn]hnmqpnnktnrenqiqlvqnnnrolohnqmoqonlllunebppknjfinmkimlpugkqoqshpioompknnqsqok{osmprlnmkmpkpqwliomrkolstspqitklnojsqjonprwolpqlsmlnttmpnojlolmmsjnmrowlqkkpmhlomsp_jlqinlkmirmmqnmmllklzrkpkljpnlolmqqwnimknwkzqrnligpsxkrrunpunkromtonqqokpkknpnmqrimomqorqjhsozdnrmlmqlmnmgitldj~mkolnpikkogwnnrmhiqliieppsnohookl^ligpokolrpijnsxjgnlkkjqhnommplollnnqmronkinqtmfotmukylplojkioprplrjzlkjihnqqnllkmmofprglonmhpqnjphpljiojslioqkpxlmn`olonwlgsrqestpronnspomhokmnj{hmhmkswnlkmksnqtjvmqkilkonknmjmoqwkotqnqlqvnolsirkkklkljtnownolfqjlmepmnqtmptmnrllmqmminblkvvnmrsonhkkkexrrvmkypugkotpwlitmfipnlneoonmvshnmsjonmnmkktmmflmmkghsiphllpmppbptptnnmnrjjnoumpglqnmkwnjpmtkljgogtuzom{npnpnmnjqdninmtlolipskmnhoigqhsmmqlosjnlnqrpojpqlerojjnvlihmhkjpkjlokqljmloqopjpkmmooqnponjtumljiminmpuqrfjonplqonkljnimnipuopnjkipklpmlnimjrkomjroonnnsjmpnhpootrsllhlprnkhmoopkrmnoolljklhkmenmljnvliqojmpoklvqmnpomnpnkjlomvsqomlelpspnqjrnonlpljnonnivlopntlpoumnjslpklppqpmhmmkmkqmmopnlinsnkmmjljmkonlkkunqlkpmonlrloqnlolnkomokqmkrqmnqnnqmlnnnronqqtlnnmnljrpppgrollololontkkoplnnnnorjnnjmlqskltltmonmnwlgnnnnmrpnmlpmpvtkoknnlsnognrmmpoonopmonmnwjqjnppqlwkkjnomrlsknrlklonlnlrkrnnknlmljqnlsmnoqponjmlollpnmpsoolmlqlooqqmmolksknqinmlnpmlolqntlinnnnnnnhrplinmkmmjkmpqj\imokllqrnowklonqieidvnsnllpqsnpuxijunnkrjpjrmlmlqqollppqkrknokepfkohbqojmrkknplqpnpqtkmrim{onnrnpjfjqprvqrppksjqnllphelsnjmglspd{mnkligmlroolrqumgnmflhoqmkngnunhngmmqrpkxorqnhlonkjnolnnslkljvrhojupltvmntoonnmusnoopqosnlpokrpimpmponohipnqlollgeplshnfqvlpjupijkmgomplsmnkqopqrekrrjnjktrnknsnlnmolkppoujqnpmlmhoorknjmqjopjqlpmsilmlmjjkpklrplmokhnpmmogrkkpmppvloklqqmvpnlppplmnnonpllrqknkgnonoqhloqojonrqrkgqjklpjisplpeomnosfpmoocmpkmimmpoppekpplmuppprrqmisltynnmhqoeoiojk|spomnpoklhmmqmomlqqlmmmpnomhgjnnqlimtljlkeijppilkpoXopmipqjkveqoqrotghpotlhjpmkonmlnifjptlicmeoinjkmmnrmnmlnnikmmmkkunnqufosktmmnhnpkjrugnnpkohhpkmcckiljejglpnmmooljmmtropjkmksjiimyommrnpmrpnflmmfjvixpjmvoviiohrlimhfqjqjlomoo]nqhpstmcnomnmkqnjpmuooxupoljnfijooonfqrvmjojinfjdkklrgqkojjfrjlhloontnolbkmjpohoidnkmjjrrisjninnmjpooqloqlppimiopkkklloprin}mlipnqnlmoofokpppknqmlqprmlomollqoniommkogsmmqanoqokjnrnmniilohqyiqoiumnipqpmoemjomjpqmnjrjkipqnngpnmlosmksqqqmqshnmnolnpmpnulokmpqhqdmpqolhnqdomrhltijolnntmtksmarnlorlknnkomkjkommrilnomplkofkomolnolsliltlinqpnjjppsjknpomrrrtnoqlkqqmpolmpumjmvkxouisklrsmlxmloonlkmsmnqqnmorgppmomnlnrkoolxlloroo{pmhjrqnsnrlhpjprkjppvnqri|jsorpmoolqpropktkonpormtnlrmojjnjnvpmnolpnwlplisnpoopqmgslkrrqppmjosimqkmiqmofnlqssklmpriroolqonvmkknwpmnprrsmnkmpnklwmlrnsjoklonlloplinop{arlsnsetj_hokpopnkoblmjkmolnrlnmokimsofpioofqrookenspnompqmnkmikmojnchowmtqtolrkmvqkpdwjltnnplgrnmigjoejczmvmqrqcuepjjomqrqo_rpnktkobqogqpqnjmljkmjrmuionimvlopmmpmikhkjqpkpfpnfurnlnkpmpvoosippplmktfhmkmoynonrkopokknjmrsmmlnqnljmrkmojinnllllikonrjo_igruskmuyjqrhrwpgplpmjnoqqgupoognomljlrqlntnomfnnuqrrojjmpofnpmtnliqsnldnmilmmrtqomomnegqvosnonthmlhlikpslkzmpivuknqsomkwmnrikpoopnmjnvnjcmotjtkombmnjqslnrqmhhsnooonknknomjlrmmpljpsfoimlppjmqnnqskjkn|mmnjjkkenijlqmnpnstlmdmeitmqriijofqsrmttuhikplmmkllnskjplqommjoostplmosnpljloijmolypnpinfqnomfmnknkpnnqnjsuimmpqnlmpljqqkqqnnolknnpkqmmprqmsoojoioesnjpmlpolljqooppknlmnjmlmknmmshpjljimpkonlokjjmnsijnnhgmllnnpmkoqkoqpkmssqoonjkqorkhllknpnnoknnsjngkpjknqnormmpomwllnlpgllnrmonnpfklqpkpklnfplkummnkpmfnoqmnqmrrpnnkonqgmlrmmoompomotjlpkqppnpompnqqnumnpmqmognlloijpnpqknlgqkpsoqnkmmijoojlopokkqkrpjqlmlpkmontrooiookiotchpkoplomllohnjqkjninplmlnoponopmqpmniqmnjprnooqnmloorolntljnlhollnomnlmynnqppjlpl|spkjnsooqjpinoiilhnnhnorlqrljqwgojrmjmpnokmnnjlnljmmqmlrknpnhookqqnnlpinonpfmknjmpolnmrljkjnlmnimqmromnovmrlonnjljlknlkkorooolj`kjmqon~lnmgpnyqkmppposspkqlnnmippnmhlqlokilpjlnnpoknlninllnkmllhxnltlrslojnkjopjrijmoouiminonlnroooqnmuqkkmnpnboqpppnvpppujpmnpztoknnrjnjlmilojlmmomrpmjmkrtprusupooaqmlljognmnmoinnp|ljqlllmponpqjjmpqlpomsf^0Ev!jtz6}uI0Ra~`]giX4<GmHOOit{cK~x]8lCb4q^r?T8 v^sYktAUCla]9kGUG[WVL\XO]^dW[VrX7VOXT@AW_Q^[WX^CUIOTZS[W\STS[TXVVXWSNF]\QPUUPZTXRULYTS[XUVUX[TSUVUUN_ZVXXSWXMRXXZ\NXZZWE\UU]YUWWU[[U\ZYXW_UW[YL`VSFUXVYVWWVPSVTOUQVTWRZ]YXSTY[UUYXX[XSUTZ[OYWZRQ]]XWP\SWX[WSUJPVXWV\UPYBYYVRbS[@UVTZYVUWa_UY]_LYTTVU`XXPZYYVXWYW\UPWVRUVU_UWVXSRUUY\SQ\[VSXP`[VTURX\RRUUUW[\XXXQURT_VZWZN\TX^ZVWSRUUR[UQRS]\ZTcX[YUWXW^QWU\Y`?[ZUV]WWR\][RRYXZZRP_ZWRU`]?bMMqSUR[XYWVYi[ZZ[UPYYLV_W[VWSTY`P[T^Y^V[WYMJO^TTZY_YSIY]\[Y\F\TL]Q`\[]^VYQ[M_S[W]\^b]XO[VW[YX[G[WWXxWT]SVPWRTYTfVVXWX]^_XTYWgVPcSqWVV_\VZVSXLWUWQQcRU\OPZVGZbQRV[WYYLY[VaJcTaY[MXXUVOiU_TVYXDYXbYBWTZUYXXXVHU^RWWU\`Zc\XO<_ZW[SYBZWAZXR]]ocZZT\XQYYR[XJWUZ\YT[>`@]YTRV9RZZqP\WVUc_TVY\TLYToRObkTZ]eVWZW[WX]VbVtZaZKa:RNLSVVW_iX\FRVVNWTdYfVTWVXZYQN]XRXUUQXVVVV[aWVUXPTQY[SX]L[XXW^Z[ZSZVZZWZY\XXW\SXGmZTSVYW[Y\XYYPWMY@OVW\W@]XWPZWTP[[YUYWXGZMWTO_YPRWT]XY]ZRWZa[KWYUXsYVX\VYYWVNXZ\WYZZZYLLVrSXYXXaWPXXZ[]WVVZPXRURUSTPPYXVWYWSX\GWVUQVXWXbVYT`YYUWZWPXUPXXXW\UOXXTWXZRPWPWSTXZW[YXSYM]WYSU[ZYWVXVWWYVVVV^[YSZRXXUWVRYU\VVVXWY\dSYVUVTTPWZ\XYXYXEN`YWQTMXUYWUWPVVMSXSZXZVWVWQXSXSVUaV[XX[Y\RS\URXUXOVOWSZS[`USWWYSZWYY[VW[X[VWZYZTUTUVWXXWQIWZUOFTU^Ti[XS[V[YYNTTYWNWSYGTUYSTgUcVQP_X.TRSTLQQUXRDRUPHdRT`WZKURVUmRTV~bbSYUtFTXrQRWORUR U[SsXh^\fRROJUPOYfnUdJSZURWWyU8SUTRPUTkTgWQJWVSUPTTSSFOUSRR`SEWSb`W`ROU`WUZRQYXUVMVXY_ZS_\dXX]WUPYYLVUUQHXNZVY\XXKTXX[ZZY\[WSVVYMW[WaW[UXYSZX[^WSXXJVWMWZVYYTQ[RZW\\LZVSSf]SMY][KV[UYUZV\SOZTVVVT[[VYXXWXZYX\_VY[XSYYYVXAYXTKLVXWRZZWXWZYYPVY\QSZUh[YV\VYVRYWU^YYXiWeNSPIXWWVV\YZURWQYOXLZVLY]XZWYWYZ\Y[YTZZWYS^\RZX\GYYTYXYiUVVVRhXRYXfSVRWTLVURZISVWWW`V_Xk^Q]ZTW\ZRWWNU=S8CcUKUFQUXQWWYUQ][fVWUIVIWeRkSIRRVQYR_SnSS_XMUV?T|XTWVPTVOS^_bSYVUURSQ_WUcWUTWUTeTV:U\PWVNWYVVXUW[SWSS[_VVVVLVdWN^Q`]PQ^X\Z[HVWVAQZTEZPXUXWWQa^ZUWeURYOWI]jQLOPVZ_WWQ;T`NUQX[XXXXUZZVTXYY@YeWSTXVTYTTMlVRNWZRWVS[XWSUV\WVMVTVXVLYZXZVVITWXTWP\KDCV\W\WTZXSX[`V[UkWmTTSjWUUqUWP\RSQZWWXlU]UQZDWRT\]YWYkWDLWOVPVUMUUY]XZUWU]Y`]YXVTV]VVYX]RWVVSXVTMWX`X\\XWTWXWVZOYd[XU\ZVXVWUPYQQ{RaUW[XOYUXWQXbWURkXVT\UU[NU]TWVTShVTYQW[^[QUZSZUW]SSPUZbXZYYVX`WYWYY]]UZTVEVVWWYYUUU\WVUXXWUXZV^]\`Zg[Q]LSL]^[W^W[^_TDS^\WRb__UZQtXUW_S\`Z^XYV_VRFUYOZcYZY\[OVeSX]_Q]]X[SL`TZVMV]^ZV][P_aP^Q]U\^b^Z_^\^_ZZZ^U\\]^\a`WO[P[Z]X_U\^VXSW^_WWZ_MWWTQ]_VWYY`WWYUZM\]]XYYXaWUQWUWZVXXUL]V]_XLTWWNWcUVWTX\YYY][VSRISVXcZYWVTcYG[YVWWVVOXW[UVY]UVKWLWXTVXZXW[Q]_WR[YWWSXIVXUWT\\ZXZ]WWVVVXUVWXK]VZWa:WTXjaRXTZT`XZXX^XLX`YMWR[MU]WRVdWYXS[MYXXc\`\]V[VPSWOZXPdWYWWXU`YWVW^YUXW]XVY^DT\UUXTQZVMP[XZZVYVVVPVUJRVVSVVUSUUTLXMVVVXWV\XRQaTL]YOPYU\XTQXVUOW[XTdPSUYTQXRSUTX[QWVHUYXVUS[\ZXV^TUXSUP_ZX`WXUXRWPSZWSTQUUQHXVTWWWXTQSR^ZYZPSUZT^R`VWDWXRWZZZeXSXSRYWXYZa[UXXSNW^QLaIVSNYdTRZTLXD[SNP^ScWYV[VMUVVVV4WSX^UQZQiZTTWYUYR\iP_IW[RVW\CXRWXWXZYVTVvUSXUYRTUUTTYWJXXXVfToTVXS^]TZZUYVWRYYVPUXVPXMZTY\cTZXPSOUXcRZU_SWTVPVX[Z^b^VQZRPZWYcVUVZV^ZVTXVZPTYZ[Q_UVTcVWKXPYY[YXTUT[VOTXUYZcVZVb[\P^YYX\YV[RTU`ZZZ\TQYUVVOYbWOSVZWVZYWVWVPWT[U\\YU\ZZWYSQXR[KXXQ\YW\QWVZUXYVYZ]WTVXV]aU\WXXPXYYQTWYX_TSYRWPY\Z[SQPTRU;ZVUQP_QYUVLUVN[VQW[YWV[X^ZTWrZSHVU[SSUQVkQ?UUYR`QTX\ZJUYvKNTSX_VPV]VSWU_UJ]RRXTXVXXLW_TRXTTIVVTFXZR_DZT]\XWQUTdUJSVYWCWROWVTQVTXXU[NJRYVXWQLZT\QTRIOVYTESHYRVUOQWQ\KWUTXUX\TW\[RPUWPXVaUY\V[]ZYY\SUOW[VXTPX]MdTM]SQ^bZZUIY\ZUT_YVXXWS]VXY[ZWSW]Y_XO\WXUMZWYXhRRUUYUF]LUQNVUNGPWXOZ[YWSO]UY\Xea`LV\IZKY^]QPd]\`XWg]Z`eP`dimmg\SVc`XV\XR^T_;WWV\@]YVU]]UUe\ed\RZ=[_TPbH^NFQY^UTW`xQ__]ZT`i_xXT\Wa[XV`][_ZX^f`[WNObjL[[]XN\rXXrWW]WZJXOWXWXW_UYZ[[YYVR_RTB]Hb^^\TZYVUXY_ZY]^WVXXW\V\VaWLXb[TZZZWYGWVNW^JZSSWUXYTmX[VZYZRYPOZ\XU[\ZZZNWVUX[WXWZXYN[VY\WVTZXUOXYZXRYY\WXVVYQRVZTYYTY_ZTM]]\[U\SSWWW^X]\PWV]YYPUTRRdaPZTQ[WWWPYYdXXYU_PVSUTR[XZb^VWWZ`T\W`ZPVVT_\^XWb`^UMTUUZZ]Ri][WY[YQSZY`Z]_UTOUTDPXALY[VU?][WTZYhcZUY[VW>M[c^URWW`TXURNYNUK_qPbfVXTOU[A\YX[RaS\[K[S[kWLXMpVX[VOT\WOYLX^RcmUfU]WUWWTOSHVa\YU^ZSSjJ[LUWV\V\VbSTQKV^X]YUXTUZUUOSVHVUUZM[ZQgXZX[XXZWU[[^[WTTXPT^_W[W[TaV^TRX\TUb]^XXXT[RT_TRUVWaTZYVN[VPXZWWUW\WI]TRXVOUK^cRVVXSZYTWV\X[]YTLYXUYPT\LXU[T[X\MQXZYIV[UU[SRYRX\V[RQZXWXNUY\MVWWWTVYUZMZ`ZUWWUY\WPXKXXUTVXYYVXWSXVVZWUXTWXVVY]YRRTYTWaWHURQVaWVYQURVTZXYWXYZWZNDY\[XXLVYZ\YpVTWVRFUJTUSYk\ZYZ]ISCbQ@BXOLVUW^XW^XO\TY`PZX>OYSSQ\aUN`R`XWVURW^Y_cKWY[XRTUWWTKNXTWaVTYWVU[aXYa[[WVRTLYcWVYXXVX VPWTWSWYXVVdXWYXUTZ[XRVVRTYTZUiUCSXbXSYWXTTWVSWPW\SKTXW_X[LVVMTVTTU]ZZW[XQPSURYR[[YT[UdTS[TNV[YXYQYYXT\XWUUWUNYYVY`ZZXRZTTY\XTRVTYQSN]_T[ZVU^QUSZZSQOVUZV_VRWV\ZZXXXSbRURYYX^YYSXTMOOYT[WZ_^VWTVUOVZYYg\M[WTYVVYXYZRM]XVVYY[XXXRWH[WXL[STTW^WWWYZYNYWZSXYWWQVUHXMZP`SYXVVVXVPSTPZQNV^XUSXZKVWIUQWVYaOXMYUW[UUQRc[TLNTYbZTWPWqPNBT_PXSUXaSXRRYRHW{\L\SVsORW^ZMP[RSWYT[UVRQYP.DNUKYXPUZ\QHYUUTXXSZW\TSQUSWUTQRS`NSSTPSTTKYKLWWWWGPUWWMRW_WXSjRVRObVP^V`S\^XXW`PZ[][VWXVXUGYLZUUZWR\SVXbZN\[_`LWYX]VX`VXU`TXYQVXWTTVUWTSUPZZZWXXYQYUZVQRXTTRWRWNWPY[WZbQ\XRZY\UTW]WXUXQXUVWRXbXWYMcZTRYRXVVWX[VUKVZSTUVYVb]]YQ[WZXPW[VV2\SSXXSUVW[`SVYNUR\WX]V`PVXWLd^ZVZU[VSYMZXXW]W[ULVW[WVRSWWSVTOOJUZV][XbJfN[VUUW]SC\UOWWV[`_VXXJW\ZXRS^YZYPUXYTXYZWRWXQXOU]YNZ^^SIT[V\^\OXWX\WX\SYZ\OXXTYZQV[VXMQU[YTV[WVUYN\][U]ZQY[TTTXTWNZWU[^XYWVUWQWTMT[U[RYUX^YWXRY[SV\ZXT[XYTQQ\KVWZT\P\RYVTEZVZKTWOTR]UXXKU`VNVSZTXVWUbUVV[[\WZQ[U[WUW][UWVRTYS[MXYTT[YWUUTYYYXYTcVS`WFYZSZV_[W[VPTZSZ\\d_aRT_NYR[_\]T[[[]UNRZYYZc[d[TWsPRQ[R]X[X]]]^tRQWTWoe[[N\RT[fTY\^XcXVM[OQN_^QX_\ZO[YFU\W]M]XO^S]YYZ`Z[Vac\OZX\]`^^YZ]RV^Z[_Q`BSZRPe]VZT]VXT[WWW]VXU\YbUXX][OXVVV_YU[RLXP^UQY[[ZWYTaaVWYXZWWXTUZV^YTXYSUWWUXXVSWUUTSVUVXWFWW\Y\WZTXR^WNXRWWVW[\YZ\[YTXWVXVVSYbZWY9YXZXZPUPWXYVWVWSWRKZXXXS`ZbP_]dX[UWQY\ZU[WKZV[kVU[Y[TX\\TWTXYUaZXYmYXYRS`VOPVVWX]\[HY[WVJVW[WZYYWXYXWRVaZPUYXW[\TZ`_cgUV\\VWdXPPUQbOTcTJRYRN[MSRXQdSPUYZd\hRNXaMNhXFORXXZTSQ^YhNU]S\MN^V]LYMPPUSYV4XM^[JMWXUSSYQXAUPcSBRSTYGSfSRXWQVRTW8UVYUSW]SSRSYQNOQ`URYWUUgVTOYUd[OVWXXV4R[WP`XUUROCQbQfZY\[[MWRTXjWeXUdx]YZPYXYdZ\\SY\UQUVZMZHSZkGRJXTZPWQ]\NrVYUaUPKW0XQVSVVT]WHZXVUYXTVVZOTBMYWRVfX`XSNZUXUYKZTYZZY^ZZZW[X^Y[ZV]VPYrXFYNNW`ZYYWSZ^\[dXZKRBSW[EZWUZZUZn[PXSXSOUWXVVZP[U\W[UOOY]]OZYsZJXRXY_[[Y[\RYUYWZ^[YUWWJ]WZMYe[RSW>YYLRTLTaWZU[^LWTVXW^VW^WMQ|Z:TTV_WTeWTUU^VVXcmQTKbdQWSrV_UVVdSSU\Tj\H\VExXO[]UYR]DXICXQQYV]YVUWUVTSUWISXXR[PXU[QYXXROHXZVTQUUR[YWX^YSVXSZQQPPTRXUXYXP]ZZV]RVRY]T^VUW^ZUXU\XW\ZYWYW^XTV]HNZYUW_XVWZUWKX]SFVS_OY\XOVg[]SRZsVXTGWUXTHgUPhSXVU[\V\JV]XaXRFV^XWWYWTVSZaWVXWYUZOTWYVbRVXTYOWUXR^]_XXYS]XNVHSWXXZVSS[VX`VX^WSXUZWVTRVOZSZRbXVTXY\UW[UYWYWXUZWU\YTXWZ[WXWZRXYWZ^S[WWRRX[ZZWXUZKZZ^TPhNYWSZTX]YaZ[YN[VWUZQX[ZYXWW[QVSLUUWTUYSVUS\RUVUUPWUWQNVVi\R\YQ[WMTYTZSWZX_TAUVTCRTVMWVZZTXTRYUSRT[ST7fUM]STSYbb^F`YMTQUPEVGXNWU[UVKMKXLTWW[VRY^\WY\TVVXKSFWUYTWTTWfZRWRU]YjTTW^UNSWXXQ[aRVXXWWUUXRTVVBZYYRWVWTSY[VSRWbTQTZWY[UUOT[VOVZXWc^VPRNWTGjTQSSVVMWQW\TVWWVPTeZWVSWXPZWXZ^ZYZW]WbW[TX]VW[YWMYbWV[X]WWTUXYUTVXQ\UgP6PRYYYT_Y[XYQUVUR]K\QQ^ZWXSSJ\YVXYoTWTUUWWQXOWVN\WWXNSTeCVQVLXX7WqWZV[TWXVUgXXTUTSZTTPiUT]XVUZ\UIZV[ZUSVXYXUWTY_VbUVZScWWW\Ti[YVOZOXXNXWTSZSZVOYK[JVY`F\XXUXXX]XWZ^VYXQX^PTbYW_IZ]YVRdW_[\WWRVUXVYXWVWZXXY[b\SYXXT\QUVdXTVZXVX[WJY[YY_R[YVVXUXIVMY\[Xa[]WYU[V^XMUYS[UZlXRZVsZ[Yd\kY[Vh^ZZYT\Q`ZWYTUWUKYDY[4AXSPX\]XZiW3OZMUi[YIYaWZX\WYZ_ZzPR\WYSZZVUY[MZXXUCVWQSWSLfZQW[WTUUV[QWSSVWRSQSRYOG\KPXR[YQYWSTVSUVSD[UUXZAhVTbSSRUXYSKWVPMUSQY[^W]ZWYJXUTQ]\T[NURSTT`TUTTLTUZTUQP\SSQ_RX]UPZMWUSRYVSY\SXXf[YY[X[Y\[X_ZZ]V]XV\[YO\G^^QIUSW\n\[\Vv]WXDKJU\XN[^YOYVXR]YWNXVZjYSSUGNTHgaVV`WD]_][^Xi[_E\VZV[[YZX`\DX^VZYZW]\Sf_P]\ZYYSZFWOWTZ]XXUZVQ^YS\YVWTRX`XXfU^KWUY]YWWVV^Y_W_UZYRSRW\SYYS^\QY^SWWYS\[TOQXTVUZXUZXXXVXUSZOSYVRZV][RZ\\UXVWVYQURWUW[]WOSVS\VV]_YSWXYZRYOTXYYYHZZVZP\YSZXUQN^[TSSQUUUV^[WXTYTV]PVYY^TZYU_^\IT^WS[[UZUVWcWWaDT\W^SXWUYUL\WZR]SWYRWXYTDUWTRRSVSRU]SZ]Z\NOaN\VTW\MU\^QYYVSaZXNWYWNXQWWQSYR\X[UQWXWSXXZ^`^VVZURWTWW_UYXXWRP\UT]XVYN\S[RVYXVSV]\XW`YS[T[WUYRWXW^__ZYXXYaYRQZVWRWVVXYYUVTRTUUVWXWTYYWTRYZ[]WWXX[UVYaUVZX[WRIZ[VXcVZVWVkVE`XWCWXT]dXMYWiVX[eI|U`RVWWXjXWOZYWWZYSZgWa\aPV[\XTYYWQWU@bXdYTVW`XVZYYZ[ZZ`cW\U^X[V[QSYVTUYZZXYVXZ\Y[bLO]TU_YZ^XU^]a[XEZWY\P6WYUs{Y\LU]RY\\[P\R[+_eeeWM\][C[S\V]SYb]YWMWW\_op\^AS]]ZO8Ydk\T[[[VXWoZ]]]\[YV`[O\YY^WXORUae_]\[\_ZZQWS\_VWQRYUTWO[XQ^VVXYWW][XJTX\U\WYZQT[VWWWOZ_WYYX`PXUMP\b[ZY@Y][RXUV\\Y[YRVUXSYZXXV[YXdZQVTWXHYX[T]W^R]RWkYZS[MZWX[XXWXKQV[WNXVVRUQSZVWPUVSUSZMWWXW\RUZVXZSWODbO[[TW[WYWUKT_WZP_TXRbXTQcTQU\TUTKQ[VHUSWM[NSX^V[RVX`RWLVVTRWWMXXWVVZSYYLSQRSVVUTWRSRZVZXUUNWXTSVSRZWWVRU`X\NX\\WSNVUSRU[X[YOQ`RSR[WXGVZ\XZVSUPW_X[K`RIY]PV`^WVYSS[RQ]PV^SfXTWO\\ZOTXWXXU[ZWSO][XYZYYWXUZ]SYWANT[JOZ\X]_YQT_ZQKXY[U\YZWUZVYPRMS[XSWZWYPWZQTRWWXY]VXYZ[]USU[SXWVYVZOSYTXN]ZNSYX[YYYQRW]XV\VXQTYVQWYTUVY^XTWSZISURYZ[VSRWZ\UZV\YXZQQTRYUNZYRRUSX\XYU0VSgTVWVRUVW\YLUWXPZVUZZZTYeRLQVU[UUgZXVTSXWXDVUYMU]WWVSY^ZUXTUUXVWQW[WQJPWO`[XSWR[V^VWXXVUW`UUXRYXZVV]VZRSPVX\ZXYN\]YdSVXVPTYZTyVXNRYeQ`WXUOSg[VYSYOWW^[(\T8`a^VTY\KQ^WQaX]VHEaTYhr^UM`XVQUS[TxVQZOTb]XH[YK\\U]O`o\bS[VYSRXOU[VUWYSWVYXvWUUVV`Y\S`T]BZVU\VMUgYYPTXWVQ^eVUZY]WTXVTWT]Oe[RMXX_ROT\ZZTT[ZULV\U`[U\\a[]XcOXTSQWZWDUYX[QZWPU\ZTZXZVR]YTOWWTVUY]_UVXQVQWXgaXaSDWaYXLPWS^W`YVW`[WSS\VVbTZ[WWQ][XXXZW_ZYUUFSYXVVVTbc/^[VSWYRX[WYSXYVdSE^QZ\Y\X[T\\XWU[MY\T]VWZTW_ZT^SWYYSXYVTYQWhZOVYaXXXY\[ZRTiXUZXYVV\[]YX^[WWTYQ[\UWTWTaXZL[X\OXTYYUVPXTO\T_[XQX`YMXYZXYWYZU\SUVYZVXSgVbSOS`TXZ\\W]TY[[VXW[TZ[WYTV`TVTW]U\SYVVFPVTYTZYTXTUZQZcTUUScTMXZULWVZMTZRT\SRSROPVS[XYRXTZVVX\VWSW^ZMURcXSY\XWXVTTXZNXXYVSSTYTeXWYP_]OZYV[WZUOX^UW[TXZOOZUXYZTZXNWTOX[XVDVZWWMRT`Y]WXWXYPXPIXV_YWNWYUYXVUZ[VWXTXKTXXS`XVT`SUSPTPXVXWV\QVGMUWoSR]YbYXYVHVYVGNZU\[X[WVhVZH`[WS>SS[bWH__`BUWNZSZSOZWcXWYQWXZAWUVZSWRXU\\?UYZTTUSOSTXZOQTU_VMQ\WY\XYVLXdT^Z[]IUEZVVWl`WVZOgYb_es9ZPR_nZNZVM[H\O^MX_|ZXVu[fda]VV;VXVYV_WTYqWOqT_ZZibV]G\OXSZSYTY^WWWYXZ\]R\XXY`NYa^TbJ_XQ]O]PVZTZVWUZi^TXVUZWRVZWZSTVXWTcSb[POPW[UWW[WWWXWXZccc\TWYRY[ZW[[\WYTGYW\9YOSVj[UbXWZZUTTWGdVa]SYQIXcYUXTWWW]ZAZYTWVXUVTTRYWNZXSWVRZVTWTK\V\Z]WY[[ZT[VRQUYRZ`QOXXUYVT[[YYOTTTZMX\XW[X[YUagWaOM^Y\XSSSSS\VZ[YXWZXX[WJbWXYPYZb]V_ZTYWWTYYUSXTZ[T\K[RZTY\cTVW_ZZZY]TW]VVV TTKVUMUNWWY^]QXWYOZWUVWYETkWbQLZ^UTOXWWVKUNXhRmNLX]RXST]]iZUUPIWTWDYNYKY^XRLRUYS`VVjZZ^V?XVVUpYIYXWWWUVWTSOTV^\RWZPY?}YUQ\[VQVXXYSWWSZYW[ZRVXSJHXWX^]X\WRQWV]_W\XYKWZSOSWPXRW_YXRU_\YTSW_WXbX\Y]S\ZPUVUYWNU[XULXYWf`TYY_ZPTUTW]UNV]VW[]WUX]TVSNVVWYUWZ_VO_XQ[XSsVY@ZWVUNWUUSSZXUUV[RUUUblMb^Y_PQRRRYTTVTYVaTdQXXU\WSSVTXXQSWRQgU[WX[O_]IUWP\QZV\JPbbWVUVVXeRNTTXUWRTTZgPTTWUTPTO\`RJTSWUVcV`X[]XYZ[WKXLXTXWX^VWXXTUXVV\YW[jdYK\YVYm\YVZSXQX_hXVUZ^VVWTW[ZWXWWdVUXnZa`]ROWbW^]XSNMVKeWZURYTLVOXUYXV[ZSWOWSUZWQTUXQZUkYXZWZOVOQLTYN^YUX^STWMYZT[PVUWTTVUHU[^\XWY[WZ[XTT\ZVWWR[ZZVJ[XW]W`RU[[cW^ZZZZ[MSOXVWWZW_VNZTXT\V^YPYS\ZZV\UTOVTPTT[VQYQI\KNL[YbYZXU[URTTZUKUWESY`ZXZ\_RYa]Y[XeTYV\T^XiP?W_WWVWaUUY[JYLY]fZP]Tg[XXY[TUYZV[cVU[UYA[U`pZN]\\\UXeZ^E[UVNWX,YaZVY[UZX_`u]U^VY]ZV[UVUb\^XRZb\_QW/VXKXV^TRVUS_TNRNWYWSUWXdTYcB^e_YRgT]TVWSRVUVReKWSYXURTd[EIQWRSYW_VU]YWVSPVX\T\UWcXYXQXbZQDHUOVUUTRSXUTZSTQUYbZVZROWWVYZTXQSY^YVYEVYUNZVRVWTXUW\[RNMR\T\WWYWXUVTWWRSPYQXYXWVUTUVUWWRXWV[TSVNZT^Z_ZWVRfZ[RV\WXUZWWYVUZRM[aWWZWTYWW`VWV[\WSWQ[VZTR^UW_VZSVWWaUCXTWXNSYZUVTZYXYS[VT][]ZQYYX^VWW[QPRQTSZY[WF^OXKY_`LXZWZVPRZYXUTUU?TOSYUVQMXVRIUOVSTYh^TZZPZUeBKdaV`RSpTVWUSVXSCqVSUXURTVGYGWUVTTUSYWNVNSNL`RZYRYLYn6RPLTTW_RWOTLXKVRWUTZQPZZLSSXWSTW^Y`WUYUU[XT\M_\V`T[TU[WLYZWWUTZV[UTTU\YNS\\UZ[XUR]VUUMT\WR[a\UKT\YRWSWXTZWYY\SXUYXSVUXXWZWQ[WYV^RWXQXYV]VUSUGWXYWUXXWX[TTQLYWUc\XYWXWZX^Z^YWXSUW]XXUVXWWWRX]YWWVQYVYVV]]_PcTaX`T\[XZZW^UWURPEWWX\`VYWVXTUXXUAWUYKVZVW\WXVU[XZXXTS\\UYX\XT[X^ZTWYWUYOW[XVVXWWWXSQWYSSVUVY]W[WWSZZ[WVZUTYVWXXRXY[W[XXYVXRX6WIT\TXUXY[VXYYYXVRZdWUVP\SXOWLUVZXXhUXZ]WXWWbRYRUVYVXTUZ[KWXYMXU^Z^ZUY[UXX\XYYUVWVXXXXRTTQ`XXUYNWF[ZHaSYYS]USZ\YQXWUHUS]ZQRKUSYVXWQYPXZYPZVW[WZW[TSWXBgYY\L[\OXVOWQUZUV[aXNYTRXVWT`iWWUMPZ`VKW[c]^YVVYac]bU[]_NWU[X`TYUUiUUZXV`RWTSYAWYa\V`Z]TUOSZRRUTYTRSVSVjU`Q>VK\nQRIXZRUMRQV_N\WIZXGX\JWgUUV[]PYXVGUdRUkZPIrY[KWUXVSZR\SPUVaX\SPUPUSUPRTUXITUSSTRPWTSVVWSV\UXZSeWRUWXZUXYWWWR[]UXZNVVXZ[F]PPTZFVUI\TUWZRcXXXaIPU^XSYWO\XbORYUTtXU_PXQOZNMXWRVVUTV_ZoYX\XOTYRUKWRXTUWTTZgUQWXX]ZXURVcW^UX^WX[]ZTwYU^XW\XVXYY^Z_YZW]aW\XTUXVJT]R`SURZXZUWXrX\VXVJYYNBYUWHYTQVZUZaUUX[XURWW^YO^TZVVTOZ\VX^WTWWPZOXSWYZUXP[U_V[XZXYXVWUXUSYWUVW\^VWOWU]VUL]QSTO_TTSVQSN]ZVNPSK9a>D^KcXRSS[RT[XTR\qE\HTGOUUDQRScT_WLVVO_TMWY>SX\YPSSN[MZ@LQTRWTQGVJSRXNXUWRSCNXOSTNQL]ZXOJTTTQRQP[Z_fV]VVYZPV[WXRXSWW\PX`R[\T]\\OYYYXPTVUUg]VVZ[_]]\Q]LjG^XMUOZYVXYbYU[OTVWTPSX`VW\[WSYVMQZUYX\_Q^XZTUYYcXVSWXlMQYWJT[UZQVWTT[XZPaS]?SRWX]UV^TZVS]TWVYTK]W]WTVTN]HXWTwORMWX\VVYKZ[\aVSaBXXRW^ao]YRSBSV[QV^WK[]ZM`V[UXXWZVcV]QJUYOT[TKVRPXVWQ\WWQSWV\Y]\YUKZRVVXRXY\]P\]RQ\f[P^U_OTKZeYYZLZb_W]eUbQIYV_ZfR^XZ\W]V\[YPN]O`UdWM^PYScPdWVThQ^Rf]Q_VXN[]YN[K\V_bR`TZ_RYP`]a[_[VTWVf``X^]NOJ[T^SZ_YQ]PU\WY^UTQNZmMbVTT?XA[VUWdHWTXQhUfRwZXPXVYDTVUYRU_ZJ^:Tcf[YPPZULLeVUS[ROVgZLeViXQ_bYSUE\T[VNVVV_UVHS]VVVUYYWAWM\WWRRXY\aSLYURfR[SFQUMDPcLOP_JIK^PDQGLVIKMTJQJLI<@F`NoTHQRRLO\LRRDB4SGOGBPWWOFEZNUM:N[SLQIUa?:MOP[VBUN5LP:FWINUWUN7PDQMNMOJDGM_COOCDKPR^KQIGQVILHNUUaTVZSYOVYUV[^PnVTWXvXWWYSxSiZ`TF[SZWVVRYVKXSVTglN\VOVTXUR]WYXZXsS_UTOX^eXTOfLZXVaLTiaVTTRU\\WKWZUWTVXIY9VVUVTWSQRS]VYZXWUWCUZUV\XWWXV[_XUWY[[V\UVWSWSQYXVYTUXYWYZZTWZ\[UTTXbV^XSE[YZX[ZXXXXYV6WXVZ[V\VSWVUWWWEMWXY[ZWNWXXTZVXU_WPYXQTX]YXXO_S_STZZVWV[]S\ZVTXYRXVTVWS[]SRUQTWUTPZWXUR^^QWQ\Z]RUXVVXXUSVSZ_U[XTTSPeVVZ]`RUZUXXSXSUSUT][YVO]WUQYWTWQ\XY^W[W^W\TSVWY\[UWRNYLJVZX^VU\TWa[ULYWYWUWYW_UW[XYJSYXUSTY7WWT[T\YUTSOWV[WYYWT[TRQ^YUPWPZJ\Q\XMYOYZV\[[bUP[USTZWtYXWQZUPTZX[Pd6_X\TB\]XVOZ\qIeRVQ`KXWW_ZW[]V[^@TSRWVV\[PW^L]\X]bYPVOT]VR^]Z{DRZ\S^aXnBZUYlXS]ZdXUZYZXVcYwWPQY\[VVZbjW_PYVVVOX\ZYUSbMW\U_XZSXZXU[P[XXQTUGWUYYVVWWZUTLYTTZUWYVUYSTWYUPMWP_YTQUWXTVZVUXN\WWVTcVWS^R\WQ^UUOUSXTNXZT[UU[IW`Z>\TUWV[ZCUXUVMTSa_V[V_SQT\P[SXSST\TTRZ\^O]Y]XR\ZYK\RX[WY]XYXXWPQS][PVMX[Z\i\cZW^OPX]U]XQ\OWNX_ZbUZWL\WUKOXZ\]Y\NYOSVUUS`YTQNTTRUWZS\ZYUSTTS^W[U_WYYP\]UVVVSXXTWX_WST\U]TTRXVXSVXUxWQ^[UQQa^QKWZXQ_UYU:I^Yc[GV[TWUTJNV\ShXVWpPKZnHAURbUUTV>[Ug_UPRSSVaVGXTVXVVU\P:OZRRTVQUVT[YZ@SVZUUJQXQh[bUHMYXZZd\UWVVRXTLYYQRSUWY[VV\XV_ZRUZ]TUX`VXZS]X`WVR\]UWUPWQX][\VO[XXYVQWZVVZXXUVWY_YVXWPZTW]]UKXXXU]UIUV`U[WOWYVZYXU^SR[LV\XH]aYUYSZUZZ[PWd\\\S=S[YXYX\QdiIWX[W[H\W^YWZ=[^TUYZRGZYUQZ[]T]^XSWZVV[`YKsh[VQXW\RRw[m_]hX?Y]LXqVW[]W\[X^PUT]Y]\_[WRUXX}^W[ZTYYX\ZV^SXSU\W]YP]SRL[\ZVLaUX][[W\WTOUXVO]P[\fWYVUV\SO`eZTW_KPSWTVX\U[YU\OVZU[]XUUTeYYZYaRU[XaVZZTSSSWTQRO[WHY\T[T^W__XTRMY[VTWRUWSYW^RLTTUZVYWWUXVURU[V[RXWP[PO\TV[XWSYPbKX[]\VWV^^\[Y\[VVPWTYWXNTWYQ]UVYP^ZUTXYUSWZUTTX`[VURWOZVRXVYTXWVSY_VTSZXRRVQXWWXVWUUX`ZVXX[YO\TXUU[XIZZYXWXUQXTUWYNYWNUYTTZZWY]WUV[RVXTQXUYT^]]TZWSWVUZQU\YT]ZUZVYTXTY[VQ_[YUYbSYOWUY]]VOXS[Q]GUOYTWQWaV_R[MVYVZTTTXUTXYV[XQWQFSUOU\Z[YV[hWY\TQZ_Y[ZUXJkNrX]kYYf[[WX[YR[UKj\]^GW[SGYWYVUVXWNZ\XXYWUZ^NZgQVNQXUYW]X|XWYXXb\W[Z\XXXSXcYUZU[VY[U]CZSc)RPWU\ZTXYZYYYQX]^2XX[YX[VYZYUVZU[`WQYHY]WRM[[][SV]VVkYnE[_VL]UlZlXVXZUY[PVSTYXWYYWTXPQXU\ZYTZMXPYYMZVRU[]\WYXXXQbWZVXYXZUXW]W?NXMXUWO[PWMYXWVSX\BL^\S_\XXQVMR`ZWZ]XV[TYYaWULXWVWZ[ZMCVuRZX[YYW]X\XWX]]XVW^d[UXYUTXRUWZY^YZZRZPXVH]QckYWURZSVYZN[VVW[TTQXTX_XSWVSVY_[[SY[UVXYeXMX]STYNTXVX^YURZUWaVVVVYOW]YXVUVUWUZXYY__TUXXVJQWZYW]SVP\U[\VRYVUXUWYUUUMQWWS_VT[[YLVVWRRQ_TVZT_UVV[^Q\QZRV[XYa]XVVQWX[LYYR^]WUSO[RWUUa[WTZT\]WZIUMTSVR[XTWU\ZQYW\QQWUQfZ\XZaV\RVO]VUU[AZVUXX]ZRS[USY`WTbVYa\WNXWUWXXYPNTWVXZWXVTUYWVZYWZWWYRZ[U2DcYWMZWNVOYWLV]ULzcT_QlWUTMVOQVWUY_T^XbTgRSZQTbUTXYUcmX]CXNXMWWRWIXYVXZUWZXeV]QXSWYVW^P[CO[U[UQXSW\U\]XSVVTOY\\F\U\W]VVXWYZT_]abTYOWT\^`Y]Z[VZYZZYcTZS][ZYJW\YU[SUHXVYh[I[UVOZfQYYYVUT[i_XR\WYWZ\~[_Y\W[[ZZe]T]UYWY_\UPXb=XXV\kXRVWZXVUTVYdWUZVTX\Q]WXPVYNP[YWZ[aZ[TZYROSb[Z][ZZZ]VPSQNTV]`YMWTRXWRZUXZPXSXUPVZSRV]S\[U\Z[[VSZSTVVXV[QQYZ]UWWWPWWOVPaZXQWZXVXV[PRSTdXX6fXWU^XR[LXPTTUVZRXXYWSa=aXA]OUUNYXUV=WYXIPdLPYPPWUZcZZSXWS;V\WHYS\NUYVZUWZMSKZZHMUQXX[TTVYWK\TTVUbTNSUR[TXYXUk`TUkWWOQM[dUU@UJ_VUWUWTQSNWKSNU]KUSVSOLUc;[R`[WYTYQ_TSLTUUXRdPOW\QTVVSRZ`QVX]SYTMVYU_\ZS]^UUMUX1RWYUPU^UYPQJUSWTSPVLRPQ[MWURRQWX_QFJRUTT^SXRWSUVk^XN[YYYWUULVTUPMNXSP^TQSDSLN9ORUJMSD]OOQ2NEPQQ;VTORLXPQDKSNLXI_JZlMcOVRTKMNIM_LWULMNHLIOQQQRDJ\GKLPVTXZHYWN`WYS]TWWZPHTTWWQU\WWE\]XSVYZWF]YUXSXWXYY]XRZXYXOTaUVWYQXXX_XTUUXSYZUV]YVWRWXW^]VTWWXY[TY]RWO\QXYWZ^_U\UXVNZSWYOW\SS\\VVZQYWOUPUTMUUZ]XLXZSUZVW[\XZWSMVU_]^ZXXMWYSYX[TXUJOWU`]VZRW\[bY]XYQ_XPZXYZRWQX[XZOYPWXM[UXXVYZLWY[WRUY[OY[X\VXT\WV[]X]WXHXWOW^MYYZ\WW\[WUSYW\\VTYWXbZVZX]SQUZY^YUOYUZXXNXVRQSVUYWY]XZb]YXLVSX_WYUUQWTYWXWRYYYTTVXVWLUSYUXWWW^WOUWSV\VPY`]YUYX_YXY^QLHZYXOXTTZ[MW[XWYUPE\UaYX\TXVUT[MTKWUYRMN`[IXWTQ[ZZWKYW^WTYZWMT\Z\OecXRWWXYZWPVQV^Ya]SZZVTXSVXVY^SVU[]Y[Z[YK]XVXW]XRLYZUWWOWKWWR^WZ_Y^XW_WPSVY_[U^WgUXbYZUXQYUYSX[[`^ROVVXS^YYVYUTYV`V^XR`_VU\VWTPkW[UVT`\[SW^SQ`WWX[_VTT\ZWT]SU\YUZ[bXYXV[]UW[VWU\SeW[UPYWW^^_`aWRXT`XU]TZZZZUVWpWWRYVOUWUUV^[ZVSUX_XWWQT\ZeYXPaWZ]TTXYTWXVUVVNW^QV\YVUSSL[XTYTQTUX0WKSaTSV]UVQVWR[SOSVWUZWUPYZVZUUSVWNTS[TVUVWTSVPKWVVSUUSRS\[O`LS^X]\WU]OPWU[YYUTSQMTdXRR[SZVX`YVQW^VTVWXXQU[XTeVSXWT]VWVXMUMTKWKaWZYZT\VUTRZQYVYMZUbYLX\NZWXUUXWH\WSUWYYRTUOULYZXRYXXUVQXY[WVIVUOUYPSTYWVO][WTUSEXYUVO`Ymb>W[RV[YMXXUVbUTWXZJVVPNXXSXXRPWWQWJVZWTdPVZTUZQ[[RUX\VpVUVT\TSPX[ZWVWWTUZU[WUYTXZXXUbWZ]JWUWVaXhUZQWUUXWeXSXWUQZTQSWRYVUWWTYUKVZEYVb[VZYRVW_TQV_ZNWPUYTXYKTUXYWYTnUYXVWUQUSMTRX[VWV^XQMVU[SJX[^VWVTTVSVXWRXZVUTVWSUVVWU`YTWWVOVVYTHZ]ZQ\OXXWY[uTWX]XXB\YX[ae]^GEaU^[YYZYUZ[M\Q[Q[nOVYT_\U\_KcX`^ZMYN_]XYVZOGY]JTc_T]eWAJX\]ZXaEY\XZXWX][_a_\XcWXWURYPYVTY`XZ[XZbVWZXTOUSbUVWXVQXYXWVWMNTUSTNXSe`GVU`WV@UXVXIV[VWbKWTYZWRW^XYNXUVV_XYUUW\SYaQXc\Z[TV\XSWXVNVJWVZVjVXUYRWWOVTUU[TVRX[]XNT`aUU\U^VcWWJYRNWVXNVWZZbVTWXWVUPZVUUGX]UKPXWTXUYUVWVKXYVcVHWPRPaUXQWSSVY\XVZUYMYaTQaU[[YR[VYUN]RfY[UWYSIXEWPWWUXWQ^Z]SXXWXVSUPZSYVZXWVYXJVNXUT^^U[SXSW^VYYV[TUYMVZTZUY[ZR[PQXT]^YSU]WRW[TZWJWQUKJXWTQXURTWWYYX]O[WTV_ZTPZYZWXSXQYIY]VU[\VQUU[ZVYZYUWRWYVSTXY^XXSYNZUZWSVVVYxVSSXWdZQWVZPWXRYU[X]UVUZFYRhY\XUU[ZMURTVWU^Ve__`WbUUWTVXZZRSX8V]Vk[RWZcJWYUZY[WS_RbXWVYQVU\UWUWWU[TVMWMXVYXQUUZYSQVYIUXYYXUOXPZORWXYOcWUPTN\WXYOZYNSQZYMWkYW[`S\WVbOJXQQOXVQSXR^^HbTN_\\^Ya\NgRZW[NSYVNWV]SINQT[QJcPS[N[XZ_KYTNTFJSYV]_[X_Y[UR=VWYS]d]Y[RTXZWV\XZCYW_PbXXUXQ[[VTSo_YT[[cSK^HP[U]VY_XTXVKXSV?@UTW^=WUSQ[aGT]WUNVR\EVQVUIVYOPQSYUSeZ_VYeWXSW]X[WRWYUZW\XJQZYVWZUWYZNV_TZUVUVXVYRWUUSVRNJPSUTWYXTWTXG^WWZhKUACIdaZNVSSP[T^UcR[VTRY[N\QR=TLQZSWL]PWYGZGU\C:YVMURWRQXOELS^RXT\GSISVURUSS^[_Q\\UQRWKNFUUYIVVYTQXIUU^VVPVYYVVUVVYWWXUWWXUVZXYUQHNR[_UZZUYVVWXVUaSVSRSMVPUTVTX]SUUXUAXWYQTPUWUUVNZSYSWQ[TBTUSXOYV]UbVRWWWTTTYFQRRWYRWSTUZUPRYXRU^U\UWUXVMUW[`^XXX[MTU\UWIKZZY[gZtSR[gT]\UA[XYY]Y^VSPCXSWWVUX^YTSUUr^MWj]fTXH[bcUWYT]ZZWh]NSWPZUW\d[][V[WUVX\SU\LXWZS\WPZ[[U_XWZZRUGYUeZWbWYQU[[Z[NYHcX_UIJSR\Sk[wJDFQ[UY]MTRYYS\P[QMNSRbZTXRW[ZYQdL[XYNZJWSYWbI_^\WX]ZRRWOkYYXKT\=XVX[[a\YhdMQQYYXZY]]S[ZQc[Za_d^9RPUQLMUHT^ZO^KYRZJPW_OZSM[WXLTWVOLRUTRQSFM^XLYCYcSJLX?|QLj]OcUNWLSL\O[^bTWNGNZVTINcXUVVTT_TXN=YQWNVPJPKS^\^UD`OQW|OdZdP`PPS=UY_aWWtQUdP[WZYYXX\[ZXZUXNW[YWV^TS@IcVX\UXZ[ZXR\YZVV@eS]YS[[WTUWSYUWZaXYTZU_RXIbY^QP[UWPNVNUYP\^XR^WUXVYXUVWZV]RNWXYWSVVUVWU[WWSVWUvVWZOBT\_PUWTQLUYWUZMLXVZUZYVXTXSWVWVZV_X]\VTXZ[V\TX_XdIZ]IL\YXeTRYUWXY\YQU^VLZXX`WYWXWRTYW^XSjP\VTOUYSUUX]VWXYSSTR\V\T`YVZUcTTTX[WAWY\]W[`YYZW^XxXUV^TRXYUYZWO\l[T[SU\RXZX[PXPZ`j\S_W^SYZ_TLYWXXYiZYSfX\SQQbZcMTS^ZhaZNZdZc\XPXbW[YWW[ZL]gVZd[WZY\]QLYXZZW\V\Y^XWIVRWYYXS^VUXVXVYUVSRRUYTUS[VKdW[SZVSQVXUUTV[WMaRUV_QVUUSWXM\ZTPOU\XaXBZ`i_UY^ZVTUSRWJfUWUWVYUU\WUUVRYWPULXSUXUTVUXZTXNTTW^TOWmVT7XUIYVQVRYQTaYZVTWXSXUWZWdV@^dPiWYUWSWTUSDVRWRbMZTUNUXUQYJSSUXXTTWX`WVWVGJWK\XVSU`kVTVSWVOYSQVUVTWUUWXZQGXYSWWUWUXUIVQgWWRU]V]U[^^_]WMQSXQ\NRYZXXWS\aJV[NS_ZVTRVYWWYS[Qa[UMXZYWWVe^\XX]S]VWZ[U^[UXY[XTWR[XWZ[YHUNWY]UZZZRXW[U]X]YYVA^VWVVYXe\Y\Y]O[UIXXdYPJRX\\RR[[XUYPYWXW[KYYV[OV\Xd\_XPXXaQRUW[X\TTWVRW^WYPWWX[WV\WOY_bRYZVaQ\X][US]SZWUQ\\U_VW[^YYUZUUSXQJYXVPRXZWW\`MYT\XTa`XXV^XVXVX\W\ZY[bT]]XYZWYRMSUVVTXNXSTZWWZWRVXU[X[VWRZRSVPUPX[[\_RSWWUWWWSSUYYYaXTTUT[VVT]XSWXZUSWUYSSY^ZVXHQUSWXTXZOVUV]STR^XTVO`ZYWTUZTWTO[SZY^Qad\Q]NXU]_TNZPd_bLeU_Z[[F`PUZLYWX]Z[X`]_V`Z^JN`[NT\WWQJc`\Y[VU]XTXL[W_TW`\MhOZYWYP`I[ZT`YX[W^LYSY[Z^YW]NZTVX]W]fcPZUQ^ZUT^UZbXVZWShXXQZRWWUTXLTSVTQPZUSXKUTMYY]SSYXYXSWY`SYVEUZT\`IO\XdX`[`TW[i[QVgV]VP[`TY[WVVVZWV\VY^V^XNdWUWZXXWVW]Y[UURVZYTTRdR]Z_VXX[hSOUTTY_RU[TQUQWX[SXRSJTXUUX]\ZSVVVYUVWYSZLOaWW[WWYTXTEXXXU\SZPZV\Wg[TVGZUWX[V[PY[Q_ZZX[eUZeVQXSWU^TRRSRQVYUVSbSU[TVSJbTV^VTZ[^XWVZWY6VRUWR^S]SXU_XOTTTTZPRWZTnXqBIFYSMWWTSRTVGV\XGeITWXZUUYRWhLXSUS=SYVpVbQXYYVNZWWSTZqVY[WJUW[ZZZARUTUTWXdUJUWPUUWUOVXKVC^XTTUUREXL[`_dXOOY[RYPQV^[XYXWWWYYVW`Y_\WV[[XZYIO\TVRTXTYSUW[cSaVSTUY[YW\ZGWVdeXYVVVWVTVZPUXXYXXR[YYRRYZUUXU\UQS\TWPWWXXTUV[_VFZ\TPVZVWZUY.YT[VTYWWVYO]_VPVVPYSUXQYh_V]`PhVWVWSV`TQUQRVCMU^IZEYU[WUSFUYTYUZUWZWTZUHGSJ\\WUXY_[SXPRWU]S]ZEUQSWWVULSR\VVTVSP[WaG]MXSTaVKRZTTHTX_XS_TVVRR`W:RSST`UUXUWZPYPRNWU`[WTYTTRQTWRO[TQRYELVWSX[NTUSW:SZVEVLQRT^REdSVNSWZU?_TQXPXQOYVVPTWWTUTO>RYMXXWRRVZPWO`TUOSNVcXWRWTbUTNXXTU]UZXMTYVUPTS[WMK[VXXV\VSXWXSSXYWVYWYW[PURRYWWZXSYQUXWSWWU]X_XWQ\]UVLWTWR]WWVZNYU`UYXW^V]T`MTX_XSZXUU^cYXV]VWWSUSWY]PXYR[YVU\]WS_\UYZPYX[XNP_YYXQYTWWZXWVR\TX\UXTXWYUXR]TVYXV^V]SYAV]XXU^ZVURXWWQ[WXWVVU^b]YVYXWZSYWUSTYSTMFX`]WWPPS_UQOXV[U\OSYVYPUWFQUIZTUVZV_YbXUXYT\UYSXWTWQRTW\W[XVXUWLWWXWOV^UVYVcg[W^QZWVVX\V\XTZTVYXUVUXW\WWZOXWSNZXYT]V\VUPVXRSV]PQ[QVXP\XU`\Y_XXVUW^SZXVRWVWJTVNOZRRHVUVbUJ[YWMQ_ZWTR]OGfYYZV`JWtR\XTIYQ\LbKTIaD\TTN[HbU[XQKSZ[EYI`WbOY]TR\ZSVOYG_WbT\R[OULVMWRNWUfYMYPTVTSXLV_RVUQWSVWHXpWYjW[Q[WWXeTVQ_YQUXVT^HWZ[XTZ^S8PYZiURX]ZWTYYY`M@QF\KVT[eWXMSZZXYVV[MU^OZWTTZYXXPVeCWMWKWWVWLYZWVVWSVW]YYZNPZXZXUS]`X[DYTRVUY_UX]WTiVZSLWZVX]XTXZWSOLXVYYO]PT]NVYXVVMTHZTSWXUKZRV`UYHWW`ZSWS\VR]YY]VSX^PTZ\bXXWVVWUS`XYVL^^XXUYWVXSRUVTYS[RXTTWbY`W\XWUXZ^\]^[[Wf\P^UVXKWRTQVXZQVRSYPVVTPVZ^QcP\UZUS[XPZTYVX\[UY[]TNLUVcTYcWW[VWQRWUZVZVSWX^[Y\YUVVY]\YVZYZ^TUXXYWSLWYWR[W\YVVZX[UXVWWVWRZYaRPWZZTNWWcVVXNXQXWXXZIYWQPSPRW]WWYZZ\XXYZRRYQX\V^X^WN^\USXPU]YSZIXTTQW]^XYTT^VXXSW[YXYXY[Wc\ZXVYU]YWXXZFXWW[_?OWJEU[[W[ZVYY\VZUVVVZSWVXaXSVXXVV\[UUZRWYSLPQ^TUQ\ZY\W[VV_U_VUXUSWVKWXT?VVMYXY[WXU[XYSaWYTWWXYWYUZVVQ^QXSVXUPW\WWYVSYZWXYQTZ[M]_SRTUXOSaXXM[XSUPXYXWYY@Y[LTYKWPXY[TWU]ZYXSTZZZ^>Zs8RR`ZUWX\ZdYUOZaVhX[YSdiZXWZ[WcQaWV\ZY[f[a\Zc^Y_IW\SWNJ^wSZPXUYZYZCVTYZXXWXZVZUUZZ\XbV\vXF]XWUZP\KUZVUcTTVYS[Z\QRZ^_PZUVZ[SdVY[UWUSX`WWTTYaP[WRV[UT]U][eSZTJ\^ZXKTXT[\VVXXSW[UO`XRR`UWTKRYW\VY[ZYUWSUNY\VLV`VP[HOV^TXXZYVWY_XabTWXRY)UT^ZUXSZXWRa[WTWVgXSSX_VTHWQbWXRcUOTTVTRU\UfOXTQUVRVQdXMLTXRU:V[TZVAPNF_UAdVTRXHaVAaUNZIXT]VFYPTUZXWHQDUPTVXVXXUVHXGfUYVW]PGTMT\V[VRZXYXad[]YUJdRVZLRS[Z[YZYUYVXVWPXYS\U^XL[XZQbd`UZTX^]YZLVL][X\\SVUV[WWWXS^]WWPQUUKYTX^_Y[WUXXQYYXVZ`YZIP`W]CUZZWZXYXZ\VUYUYK\\YWThYYZZW`\IZ[YPSWX[\UQ\pJ`mZVOZ\=WnVT;WaZ_\FRR`FY]S^]_KYaXYB[[X:UPXG\aVTFRZNTLUbapYHV_WRf]TWTXWXY\f\hXLUWZZd[`ZZZP`W[OSU[=كèΐpᾶž~kuOuُգoiREMlyoB~b͍x£|Ƣ4d֕nQ~})w}mo~Z~zk{hevv]~zqno}jrw~jy~wo~yyy~uco{|vx~ȯQf}gmt{ęřƗsx|kՌ~utuvu~v{dzd}v~xyx{|~z{z|v~vh|yury¢tĊzp~{z\~ژחwz|{uzDž}}l{z}}{t|z~֧|_|]ɗs`qtj{}|k{{}nɘzzwoΚwxm}szm}qy}q˙}syzlzw{{yo|svowvl{xwwŚ{^~}{~}ĜysyvĔznsn}~Ιqyl|{xz|~~}zql}n}{s|w{̚|Þzwz}w{ݖš|{}yygkØ~Qyy|y|{xʔ}{|i~bv|~|~}sz}pth}~}qxq{lyvx~|~uuymzÚy~|~vtskn}ԫtytlyuyw|rwlÔƚxhbvv|wskri}w~x|zw}}~|ow|}tv{yw|z~}g{}yɖ~zlvä~zx~wx~v~xwwysxs~zqs{}}rnv•՘{{{ƒz~|yzn{{}y{jt~t|~}{~{7j`}~mw{o|lVtg|hg|~{{zhuzn}wv^uw~~xve||po|}~t~|{yy}~||~|qvv}|j7kwrvwO~|e|uS}o~z̕Z~||@z}x|bzy|w}~|~|]||yx{}~sx|xvt~|{uJV`xmf N}ȅ~~}{|zx8px{~r|v_o{x{}~~~n[zsy~vTynq~~~}zs|}{~}s~~~v~Uy}~{z~~{qsšl~\XWz~|f||6\||ks}xsgvzsuba#k_ښ{Řz4~|wYA1yKqPǕ]y=E;zzbdm`xP@Hmۉd ,y'qNxŌzOruYg_fmihCdl}woccn'{xs`N oezyWw]]ȃym jZolAi=gWsv[c&z`S8{^^gtpwtpstktujsofqghmss}wjhspqysvlljppuvpqswji{thwmoy}poloqtnvmihqvpnrhnrvtsofunuttuchs~reupol_nrvkxnmujofyssxqrlkwyupqnpsmuktqqtrrsruqyumtvrsuqtmlsktmjukronorrssuoxnonrpzrnonptrtvol~onnsri`rspqmwopyporwpl{ps~fvptkk_woit}wpiuouyt]qjlbltvovjqsso{uzmxhlk_glrknorufmwqVmfremev^srfoqrrmsdvlcnwtnypwZaorpuewl}mnozpqqnhjswejmqtjysofknjostrxjiiexrhktilklpfgsipgoogxt_tfwxddoobnhqrosppqwqrypqpsq[qoqpppqonponrnpnspotqqpnpr|qpqporspqqmpoppupnoobnrtevprg]|fmouqoi_lrw\ffwuwausmtkbsunyXorop}hre^ryqz~fjm^fmeokjkkl{utxoxqrqqnlvqzssqnisuywnwz|otrrqsqnjpomqsf_{zqol{odpptlpxu~tmirjy{sdmjyziq{fwohmpu~aswrowlyn|hil`gnfrqgnnmin|mzpqxtvoxiklqwcz~rplpmvxtsgliv}ltvntsunxqtpx{qpjtmpnqrteq{xveljnkmcyqqjppsTcbgjpwunhnluqsqn|jfjmloomsoqafurvqjnrtes|lyhkuljskp:rsvvrso~cvGpqvdm~low~wt^rc|nusw[dthl{hpoyssycwtwmzcmjl|Ohe{~Otenrl`dpnvY^xk{oz{~mple^urqc`wqd^qosytn~jq|cmshiirybohjnrxlpzcpvkjiuijjklsithqokn|~svocsw|qyuqtotrknoyonmjnutvjjqvvtsruqmomdtmjftghnpormtsgiokrq~oee~{ndkptofmzt'om`mudvkRvrxnptywchumylkvzp}}qur{}gromiwktnkq}v{~oordnvvqlwkhkkopitrnqqy]ovdk}yylskkvnvwsz}ytsnjk@ollyq|olktjthnnn{rswnprtqj~msswwykmjmqfqirhrsmnturpo|sxifkprertpnqynvwwlPqpakprlkJw~rtwfkiusxxohvtl}vqotrnwtbnz}}xlnprnrttmSyrvvwtk|~yWxtmpgqxuwtwrplvrvqqmtcotwuzrznturzw{qj_ssvxvqb{}x}h]qoo`fLqhhtgvl\tjsprvtbmgtq\lpmhjojq~mxnsqjknbxwyzk}Szuujclmgqnurpmktumuukixouussytqkqqj~poquywoxplpwr|cqk|pottssmvqprimsrsonzohyu-txqvpntx|{cmowktlwurp{zuqpoHrsrooown~tyw{xkv{pwXpzshssugrqguktmrYqwpknj]bqmahl]vqwyozrotmjnl~opkgommmchqxrngqx}oqrY|rKeer{prnimqwsd\gn_bwrPdvqnbszevdhg{sprfpprztrZfkyacxqElT}budqld\_x{mall^fpqo{m\spchwkhuslsK||bnrtmruqvp{jxrkznrlptrlsqrqmspsupsjrjopl|rktrqpqtwklsnjvskqrorunoxphpjl|}{jvpvq{swkkqhtw|hr{oukmz|sjxnxysuwohokfmt|p}urv|pegrftbnyrlweYetfsd|{kubxsppijnpvl`mwqiuag~kpuwiiouc}idsoikrd]elrsmcjunreohnjqvgsursuklvnbfmnuqysrhljutnmshd\}nswXo{qsoohipcoqnsow]kvmorqpltemmnshukprhoiunvp{mhisoqrmlofzqwpt`pxcrohuumsrijslnsryessdynnrmswrugu^lmvminolmmqslxipmoisp{rnrnokpr`opjrqp~bwnsrooqrypsrnymmvtipujnoxsomlgpnmqpomprhrportnqrmsompo~usrorovtojhotmmtjrttmmqqwssqpjx_qkywxouvqkssdapmnaopt}oqhxcglooopjrlngetwmpswusvosfrtkkwz`qm{iegrrqpulmtcqsgrkosmtojunlpsxmrttkqqgtrpkujqsnmit}atrcfhbsjfuqYutnu}rjsvnpeq[ut{l~umwlw\Yuk~xhtq`rnxvlss}s[zrronyhmqnlwuupghayxrrlqvznsrocolxmndfvluts|y}|quknqrcspopoppwsrqvpjqonqrpomsrnppooppsopooopppprnpqqtonppmrpumnpxqpnpctqu^plyrduowrwgvupntrqomYqlipkn`hpqVjx^qkfvhgp]arvRgn]wbmtvvdhri}sssesq{cte}qthUnyr}mdr|rpkiqzr}qmixxwgxp}pwsjjv[~sopywWrwwvsYuqhctysgoxvqpjwuxpt\yw{vvo`urwfwstt|fssufdwulfw_rd|tmhrmomomq|djhhxs``aivzfgpfclsskjmhrjfreozfieliifclitonizhw|~Itrl~ot}~tko^wtj~rpkzs{plll`olsqYlof~n~cvqwpcn{ng{eiyrphtomjzlnmg}poikzeqthilkpuhgthuwillgjfwlgmlj|tgkgwphklmahjt{mpnivlwtqwnyruxhxf\ssfvpwtmroyltuqi}ywwvtwtucxnnxoqqsnmsdoauvshPn{pihnnl[nrxY{eewpqykmxysppgjjtoghlwqwlotpi|xmrtsZ}upswqpvp{vsqrlsfptssqnlludxqmmegtolmqxwsipmhnjstmpqetsvzprriptqqqppuomqnprvmqpqpuooqnurrtpqpprrqpsrpiqpqpprvpppsqqpqqpsnqoqtqpqpclqppd{jqm|iksKrpkrxulxshmkqnmotjjlnkohitojcig}pijpyfhnvsmdixui^bcMmriwh`xy^ryydmqhWvqkgdb|ldxldsSjvg}}ubpm^~xS]uemopnrzvsetsDoxjlpy}rlstvwupsmpyuez}s}ql{n{punilrmjrrttktxurqytnsuqprnqmoqpionjlronmuowsvt}qolsqpttnkkqnkeqvqopomnwrwqpoorqoprproswZozvyqvnoryoqpijgtmrrqyoqtquqnkrilo|srrtmmgtlmkksiostkpsoruu[d\x{hqjqmvrerryqnrgniRmos{zpnnsxptmtuoil_mjvdZ`omqpjsVghmjtoomdmootiukZtpnnpvs^ti{wjgjqf{|eotlj{krzn{ttsag}|dijvssrvnbtwsqmsqsuqqtgsp|rqszejuevswiljd|qnnwookqrmbrfwlzp`vyurrnmtnpilnpqlzvqqouumjpuosrsplotdnkqjlttjmupworkvvqsltksmucmqktpvrojspqmynwkjposrunozsigurkqorqnpmnelhoomhontjivtuletrounnrmzwauytnkipxlqonzmtouxnmortwrokklmhxgwwm|yrvsrkonqpxouotnununmonzpsyqlqkyw|nqx{nywu_sugfsXwys{hcphyumqpnvqvowwr{oo[svumrlknmpnyt{pnrvtsrxm|tljnroqpuktk}kxrzjtghgqutr}sv{qmupisdorqptqompmrndrvjkcygjnkop[hbqaqoknijyiKmcjbgor\pmiqoy|micompthtqy][vuly]xjsnnq|nojm[^lpi~npkuwmkn}n}attzq{t{xsdrmr_mrutwk{infb{lqjpqmsmazrmolarqmnq|rsovybxqIp{qisjsojst|tkjjkips[nowkyozuozm|x^ulkzxjjqrovsarrtwaymXxtuuqmkmuurm_nsstustxsuut}ustlu}gswuvtu{}e`srpvtxZJ|cpwfarjgonniqomstSvo}moonvsz^q{civkwifal{njenjesxteqxTscjduitounsryxtsptnvuwkxzuixqv{pqltmoq|hkkpheollqrnziqg^tsdclqhjjq{aaksilcrfcgf[qredntfgt_ftgqeir[ml^ofty}icbfnixmovywntvonnnqlktqusoxp|}wcmjkwhouiqwr`ylkn}oyh\onskujroqnunfmwnrjIqvnTp}q{qtwpmnsrs{goorssq`zlxvrqobqrerhdop~znmk|q||ojuspqzd~rzl~hpt={zyqgpjsyppun}l"v|pyxhOqpomqoqmuik>|lvwrrqqnqsqqqpqnopnqpppqoprrqrqqqppoqsmqposqnsqqooqppoqrsprrprpoprvyuutnb{nt}pvwv!ucvjpius{mqmrjt|wt_wrrjowtrm{nstkmqux`YnwmjqEZx|upw{{UmJvBrmtf|cuuwarqvpMzzjxnywrr}n]}sWsf^}yWpXgnkxrnynqrrjmtpirpolnhqunorwyrvrlkrkjoomuprv}sompqppuqvqqhnlmxslqtngsotseh}skpnvmap\ykonmduploqkyvkappqlrjmutuhgm~vrjomrmotsnssrtufn~zpdpuyniunrqpu|rmolxvn^lutgmjqfmixpprokyejyh~wgg`pqxorZngkiyxozcepgkfoeoqevipjshrfkpYrmwvmxqdtmjhjnm]xjdzbczkw{jipnvhomlrrpqqvtrxlxyijwqvmj|lippnvwitrqiwtlswnmtqiuwsjxpvtqnvrxksplyznpjqgomrouxxqk|rpokpiotsiligvqtvlowjvjjtpomnqprxxlv{vrxnrtvuscuvbjomURtilsytrrevxzk{mtqcpg]qj_oyfqXowyh]qnrbelo~aaal`cnNsdi|rlcsnsirmonutnndnjnnofnzfizwiq^ct}qp[{tl|pk~pqvxzqsepfttlrrrrssppknqqqqqlqotrqtusnuprsplpoosrosopxrruprupsqvqooprrpqorzl|qrnvxtqhuuuyqktjhivl}vwms~twkpy{{_iruw{dzrhqtwpmjz~njqlfnulexZnmpmlljlovmoqopqqf~owgpnonngvfmpfuvnsbknuvkziekmtrovqpt{pslmspms|usrvklqq{tzhuoxngxpmptyyjubrnorrnnsvqvfntdnjtpwosprpqr{ppssropqqpoqqrnqqqqrrqqpnqqppqpqqrppqrqrrqosqosqppppprqpki{wwnosuqrunmqq~yr_rjflcpmuxszfuq`wsfpymmtxkephuywooqyuxwk{vtulukulpqrpjfadrksrr}~t|h||mxl`nsnlqpjktudpewj]wcvx{jn]knnjzttgp\euwumowk7|f~kvqtmsqv|rnpXv~hs{uporsnxgtupvtrrwiqomroirqvdquklowr}qoyqswXhgydio{me{danrroejhcvjuquksmupordzt}qrvjlqnfforsws{osnlpqfpikhldogsqsrvtolplusurswpvnznisxlrivsskkxxmgqosguqpjvivsk{rorpznspmolrwlrkkqsimkqqpsoolkkitmptmupnopnvjlptmopmkytsl_Wrok`fqvp[kskja~rd~|ltkvwnwnnuolm{ghpe|ii{ivzltvstw}vzutsqudhus~cpnslooxojpmrlsqplnxsmovpzrqool{{ovhuqqurqupglozunotreznstbksxicnj{rtu}|npuo]gs|sju~rivfpgnwrjdrvan}vponkppjtsnxzwiplnqj^`ykscxd{rk~iurloti{xpvkpZuioisrdolyhnqtxxjs{fdpfstrsnptpkauosgoolkrlmspnrxognspmloqnqrhmkslrqkplovjniksttjnvvpoidengsotpkwst~quvzhtsrlmclvmbf}nkf{urpj|runyjjpyysh}rwqpyuo~pssnrlopmqupynqsskrlogyyqgusnsdnqksokpmqrsxqposqh|mnhsimrnrpkrpilvskvdgmxoawdok{qulyplipiq}rqgrclrq|sdql~kodsopzxjhywrtf}ojlopmnhq\/fegeof+cpeqnt~UzXegkwzggqpudoe\ovnPznbvw|zpl_r`}t{i{jorultqtqtrwtla}synsmwer_rvrzqkln\rkmlqihqooz}kucnro_nlnv}nxoqrrrpqq{ppqpqqrptqpqotrrroqprprrprpqkqpqrqsrppprqspqrprqqqqsqqqqj|gek\zgIskq{zlvn|i}tsncdvnygryt^j~nqo~j\f_pkz{vwgonvjuKjrwufnrkr~Zjrwyfnzbxj{ksgpwekhkhmekitqoTyjejsltwzpfse|qndlroytpqqqsqurwktezqltfnwtjsgmutiusoxzs~znp{htsohiuyntqmoqmhdgynruxqtrforhxsqksunsom{rzujus|yrnpyrvtwriouwqwtrrvuqhqx}v{vuwfmqlkprpuluqmzs{Yqmszohkwfiewqgpkl|wmuykntqpyymyncusxnqnnv_tjnhnpirjvoXsqfpjqsqtrpyjvbrumunhJkntbinUmmfthfqfn{wDaoRximnv{vyhyeioigo]evZ}qmzwdvsZrtpro\|nsfmmu]vn~vmh}{rvuxgcoysrqlonsuqilpxposrxosrknkxh{qrfr{qqmtiuuugqynrkebhyqwtquovpvp_qjpmptrqxxpmlurusosimsmhlqftknnollinqnmyuplorpstistwpounqriojvqoqn}wqmtkyoinrttq{v{llhxrsolnqtvovnzrosuttpkrmmwpbxjntq]sol|ejisnqjzxzonwmtsvullrzzstrhqq|i|sngpytnahuuutkvyl{]ihhhmvpsojo_pbopqxsjnwsqvoivmqjsntj|xwdnrkrsuhzrqmfqwpkvtimlofskqkrposnmqcsohuwy]fsqgdmevqsmtzpwjn|ks~jokcjuvxjkilwfrmvuhirqxi]bkwuo|mrvptpuls{tfn}peqehtuivpx]qnw}^uj[rwj~{|{skmquyxsw|frpqutjmgpmmqxoqqwldttmnnimnmgkpixqtptqrnpeksmjgnpxmzlmtkpohqipsqppqqprssqotqrprppqpqqsqqqspqqprqppqqpqpqqqroqqpqptpqrorqrqqmqsrrpdropnunklmuuplkxsqsxlrk[lmvg{e}pupqkpnin~uxzlfmkktuws{tntrlnkn|pwohtp`upt={f~m~now|pshwsgjvrzdkwqh]|nri|ve}lp}ow`pswttoommonz{hyvrjethijmloprs`dyttsqtptsypnmhpdrwqy|rvc~lkjmuboqulsS\{uzmlsjnqjlpqrjot|btigVrt`eqcnssfhlxbRqjltgt\m{ohkwynToiedhwqqoqs|npprmqkmpqrztmmeqrivsrl{vuzxqypnhdrkknfmmtxc|tltvsqynprnebmuqpl}rokqvmyjomjmsznm|kolprogoklvNllrklpmlrfhovemniptjmg]owirlhyvowrwromitmkurtqvzt~pnp{pp}txpqygz}ntzpwmurvneymnyrlmxp`gkxtknmNmueuiv{y\vysrfsx`qwnM{phwrluhr|}okxqhw}yxtn{onh+jgsoqzttyurwvwr{sxsqlprovvpeilvzstr?zyowmtvqtvppgspltq|twTutqsqommnusqftuorqptt}bpomywpqnlpmnpjmsucjnoxvsgxpvrimppo~nplsovlgckqyrdw{lnotlutljrsounphoroodssrsurqxq}kqzmjutjmllskttoysfsvsmuezmtmyswnq;ownvx}muwwztpmyqjuweysvtuznxqv[j}e|{gptn~svwesu`hrtll|sfte[osiulpo^lfptudrym~lhodiruqhxjxsrsvp{gevzoGnogznlqmmpqovn}qzoppoqgnxsgl|qywlp}ptgujqtryvumliolthjkwnqm`txhojXmgbcyeklt\b{\~napkufjnnsyuqjjbwhzkqgesq}\Myvb\~fgroruupz{syumxrblonrupuvy[ejlmqyopqsjnb{ilo{ukmxufpduxwlprsetlsdwwjkyfbgskopzfxnqwvsjmovvfuud_ovsn`kkszplqubwvkytjoso}`nylqqrpjstoypm\{lzlssy{ym{mrrjmqtdoznonswpnxkjruknncmi{plerrpidorwtlggztqnll}i{nxk>urwydlflvxqxyfp{om~llXZhl|yipw{som}Zdrquz`p|lmpumrjtgrsxzimjxlkxsxlpcqwqsmuhmurwdrsmknsk|jqmqtqsq|nrnkpvovmrvnwohqqmsnkxp}suqjbnphktpitqpvfnowllqylwkwqotq^t~pyosrnuqw{tU{osjytwsgoujvlfskrqcktltmxkoimskjvplmdnornrcrsonraunrrm|rqophtrtorqrdtotvnsnolltrsgy~~rsenxzmirpqqns}qnmf{iqnqqrwqnqtrzpply}npursntjrrsvrsqrjjoptvyknwqsixsvkhtqxtxlnrxmrqvmprtswqnwlmsjpnqpk}tmvvn|rnnpoprmqwmsyqxgrnvwyv{qltlsunkqomsuzlkrsowns`gwphm{eervqtrqsynvronqorxruqo~nxltqqxntqoiopzpvpkpqnlstnpykrvlokoyoppoynlsnqtlswmqvfmqprvppxqppmoqrmpnronul~uvlg|onjrmnmvtrwwrmqpoi|kg{tgtv`z\|vwmqxqltrsp{uphpttrusepqwhjoslnmurtsgphpyhirqlqrcgllnhiyd~u}llpmkonf{htqehlcf{aviyt^fmlsduuhplfgrrYjrs_fskWhnjqprgivpnkYrnq}o}rmpnpomrpoviooqsqkhfhucjlplkjlrnfrpyhqmosvmpkwkomju}sirm}qkrrzjtsxsbpshnioonowenonrkxgxpordpgniu{`{gtpr_mqilmekn{ppUouqjpnjkkcorskmooincenmupw\pkvptz{ssqtm}nrpeuyrwpufquotvrnsmkripsf|qkpmvzvi\mljup|iurpwmp}jhluoqpnmlqshzckouqppvhptzlpdjmtojqnvjrxrqrosromsoshipopmisqqmtmolnuruqlpkrqulqkeulvnluuovjvTnuorvllphriujonppirpvolqrgbsmhos{jrqwnfsnusop|rqppzonpjmrtisvksryjroivpjlpsrsomwvsnypsvwspqoqssnpqwqptqo{qotprtttlqvtproxwplhuyeruof|gulskuqslnnotjouotqqwzphslbnfvduqpsoqmvnkrsprhrnyrxmprv~yjsvuottxmlrsosxvkqrnrpvjqlvvrosvxlqsfrpurvnamnfzsqoamln{Xymtnx}cpyhdzrysmnuksmooxpkupcuqjwshqm_rsufjbopqplsnh~n|{pm|lv_lthyv^|twsomgsrovnznkyosxr{vzypx{qpell]r{vrp~xwpppqpqqqqqsprsso`ojppnuqpqpoqroppsprqprqoopwrqorpprnrpmpnqrtotppixtmww^gnv^ltq}stjsggqwts}cozsuwBdsqluwoywspsvyzkdkcz{onuxqwlsqtwwnukou{wu}prqutpgieqtsoltooppijbrjtgnnssrxwqirgntfpp{vvnlsmyyosvspnql}rq{psnvpnvzgmorcroowps{atrcqiyqp^_jqocsitzxiqrsnnqmsvjolmnslorwr]twqs^ugzqkwpkmrqrwstmrrttr~nxyqjoomtivrpqlzlsvptpspiouwtqiz|pxoiozwtfscvlucupeylnoinu{vgogrxru~romhqqrkr{krxlpjtupltshpnrprr|vovtpqoeiouqsfomqpxpqsvyvo|srpoktptnnnyosltmoxqjonqxlhjmjqxmuynfrkrvsvsiyjprrrnym{jpqtkorztrpq{^xjtwkt}|gte~_xszbtkpxoxnxtqqnWqucslsq{lxrte}pzwsxom`px{mylmqsiux~qpmstaupyhx~nt}smmhmhksj~iore~jnqunochiypismtjjtopuhmtfktukrjsfnju>lytppgliwtxnpipiqxGrrrrxpSomljmhjoqscntjrotswcyrks_wlvzeiowttuzneefsivul}tnwqzpwxol`vrkyuhtfx|ootkmuzrwzn`XtuWmuzq{\rcsNL{wrzmsyukl}uiwro}wskfqzqyvlvakjvcjicicnfxpypjzgtpznmwohpjujsljhz|usltulskvrtynnirtmkkrkydsqtpkxopjnnvmzqropoprysppsolrpooorprnqpqpporrpqpqrpqpppqrtqprqooqpporqprozopoonissqjt}pomrkoztlnipqhxmoptvuwtuognq^uurymrrtoqqkkpjlsqprsqruilwxlZxmdqysYt~uh~{nh|djqnj||srqguyqlyzznrmmqs}p{gewtmmZpojp`n|mp\rp|tw|tQzrv~yqkgtnqr^uinqjiqrjtypf`sorlvkv}}qnz{qmoqropvloqmkwrqmWp|porkknnuudlmptjphtrmsnqsprirqinxlspidrymdpnpomrj|lbtooyfj~wgsxs|qnworhmwt{f`pvtn|uqqsgajqsj|qgxy|ws|pwuyjvd|vigipnlpdhtwjrcil`r}qxueh|m|iwlqolnuksuzyzp{kgjg`~||v~vwntmtjueqvvkqs|kp{pybfhqrtpynokwgmflrpjoiqupojjnihp{jrvUw{rlqpwnqprxh~skxrodsojspnvvwyruolidnsplywmjkfvruwqqs~omutqnsvutottqtspupmcmrptunjr`knptorqr}otpgwpo{zqsuomtvkkmlsrso_nqrtpopunmoqr`qs}r|omvsubtltjm{crwmnly}lrrojvbjpmvdsxkcmjnzjzevkerjplmsrlklalrpqmqqrewraqfwrlxfs}_n~qvkmgowlufvrrauoczlqph~ono}dvuqrsvoh}vkxvqslsp|srstkvkujtsrpyrmkfpvt{ptvprpr}rtjmksogkoqquypujqspvqozwtx|tcnz}h|`tknfr8qsknaoktuvflqmkoyWprrtum{mqzpxonttkh}pmixtxtmvssiqtrpnqtm\yqktrt~~|yuiqqxlqwufVttkfplomqjww}qlzgtqok{nmwmdlqolmuoppumlstrttskmrjzuxsopkloysnsofsxhpgkmhizsururmuq{lsnnlumnohonnnzwotgsippsttppaqomp|k|qgiwolrwq}dptgjrvtqkyjcmjv~vppq]htlxolnoqoln`ljamljsxktossqvsylxxskxkrlpqqugwvzzflup_cvjvpstuukyqxqxqsk{slzpnw}oojrv{otzttkrqoqikvqumvqqpmmqmtpvsqtoyqrnwkirlrppxptrskoksrpsprrwynobnnvunqwppsnn{ldytwjllrurq{onr{vrmpxqmnamomqnkskqv^uvjvjlgutzrnokglgrjktqtxoyrktpv{ipjxlrpnplfpreqwnr}ms|mjssuptKgvxrwpjnr{crmstkoMOszt}qxwrlsotwusvtqkpjvnrtmwom{kmnIfj^tpYmgljgforsrgmtv}wqsaspOrwquwtensZ}|opss{ekv{tosxsrnyqssuqorrhkbopnjwryblqrwsqrrtvtpusltnntqvrso{smlpmmwmssuunmtullskquy}oewopkmprspvlqxoqptprvpswprqlltjklvwnqoxsmqxsVxxshen:ivqfqHq~tvnzkrnmqijojb|xhiprlpqnnnpnpvurdqkqtq|v~ghrtpqopqurpqrrnrpsorrpnorppppppqoqoqqrqpqqqrrrprsqoqqpqqupqqtqppprstoqqxoqqrnpvpvdps~xwtxtkrpxjkprfswjruxuqslspsdvssnwvszqsjpgmvopsomurujpmsmlrrrimnranttqxvyohltrgvwpx~qtwsornxixqmukmltnkyzy}}~gi}vxowywpvsvzvq|vuwpxp~hgxxmhxmlutur^op{tx|k]tx{hvtuwyqtlznlrrxtzqw~ipnzfwpvqy|rytyrlw_fntjgzwxj}przthltmxnxzmol|k}vqcvseisPwtuqdpqvyxopvzguswsnn|nov{xznnwstizxl~xt~votnosv~nolwrpjnjssxrosoxrxscl_xqkqomewtcmjuoolb]~kyo{vnctknkrtcruipYokTrljliwplugpvjojunsktklbonqinmfqokomkhqimvtmxfumlrpkukoqunxrpqrurlriqxpssz|rsqkvitxowpqp]luvlvtjpsrokslkopotmqsnphjtqpthvpmrorqnpssrsroplrmntzvusksszostoxnwfnysrimrpsrlkywoopuln|~mpmuxpqorrlnsrmmrsplqzn{rpuperppvmngkvziqnkoposryspzr{nq`tosg{uwlpqhsnpprxrtipouvsqhsqtvy|nukqjsttrrthouvjrpnkpstnnwmrtpzkppvr]fpm`yvpt[qsoymmdosmwwpoplegsomaknUqo_ltfq^xWYpklgbipkv{nfsgxxmnwoxruzpynxsqoxsmsettnjsptzwu`tyitos}q{hlmqpsorbmvjptqsslwpX{rmzrnnnlr}fmvlp~jdplvnqtkqopuvnnynpwnomkkuxmomknwnmqrxljos|okmkjgmkvl.hnierZjhS{tlz_qcottjirypixy]}sowd^s~fzupwnqlnp`loztnusorulguqorwp}pgpnqzrjsjhoelknpnnpuzlozjtmppuunmmmlutuvonqqnlqqwqjposmoqnurnoqislnpzusxjrwwbywj~nrsssxnq|pupqumvvnrrlvrqelupzyniytzwpxronprzugwuxoblwnpjlspo^uquolur|syxxummpdrgat}yor{rsjmotjukqmqonuqhou{ppxjrlgxjy~xwcqnqkvasprrk~otiplpk{mkklor|key}pwo{sp]pzyltwyzovitpqxtpzojpoovewstvslvvuzx|rrsvtovGosyuvkrwoaspkllfpuvmjqtsnrsprsuwprnvfWtslnoq\uxsepqnnr{kpRUhdtkwpwrulosn9or{bsst?~mtunplxnovmmrvs}sby|rtpifszojp|rlsbsqxggnvrqhhrugupfzzkx{noq}rspokopyxjtuo[ssmt|tzpaks}ymdussrxzu{qoin^{osh_junqegpugdcufgtmcihnz~peiyxgku|y|Ykhmphuxvnyto{qrmprivprnjrkqpjbrrwzvuyns|rql{ppmvZkwmioywqoikmqdngsttpmrpwhit|kson}kssp|ynnulrmjrshrlurrrkxztuzst}i~qrtszt8ymp{{u|vyzj|vpWwA~p~A~4~zZwvu1{}Vc|ncq}_|~x}|vzsu|k}ydwv||zzt{~zy~u~~~u}~|zvq|jv~CToks}MSno|MjgX]z^MĐz~rtwqwke}zwyptURwk^poB|jw{+~g}^wgnp\{}oܴgyfkVzqrNw|s~~~rqsQ]myÜsuuO|cd]il3yTq[sowew|zZbz{{Xhx}tprYx|[wxi[XiqrbYhs}n}knv}`~y}zhhspyy{Qo~qds{rrqxbpLqpvbudztuYghlwvzgtndPoNjdmLx~pJpmz~snppdt1ZjzDž|rǡcz~^Mi~|pSotrkgmsztos_fLknv}l{b}_buH|ta=Gyx{zgppkyzz~w|f|p}hr|suS}bvuv|m~v|yxzx~y~}|_Jvwfc||WzqJv}eyeyv}xw{xyurztx~wt{t{{y|ts|~^xjx}g}qu|`y^^}u~udmscxhll[q:zjlFRppYgu{za`\hvvsh}RcNUb_j_qDlehX:Œx|ox~jsvedp.dVe__{}S^nTcyei[Yy{xfutfWg|oos{v|N}{ӉViEv{{ov~zduqpeqwvxs~ޘ{qlzkbyt}^{j{pk~w[vŲcv_xuzswYhZlrorpwg8_g\g{~lR]xpvkzogeqj`~vjm{SW|~u~n\Z{s}CF{|L|^Ygzg}kludKyzz\yzsRlNgU~}dǶrv{gr׌ljGLb{ln}Hbsuzpqxxiu{kmmy|ih{}~nvjyzuuzfrmrllyjtlxv|xojwwyp}W~sisaflp~YXEuxckiceu~Imf|tsw]h\No[Yotypąz`ypipye^ye}ykav|wzX^e}_l}qwl}fn}`VteP{e\Tiw]}aufcaum|pmRy|r|ts~zdvvS\_ғxy}{|Zbt[dyat{f`xH{ux:]l^c|tyvJ]WOZ[jiiho}}~__}{kavoqu|qqfg~rNuui|3slXujS_gRymzyztp}rf{sy\ljxfnp|{wskp~ptwKa|~yjЋpy~qxp^vvixw}xlzsd~pxzaytp~~ovt_|~{fvuk||~pHx{uyvtyx||re{~n\k~{`Dxssnzuot~ofpuhux~sju{z}|zhusu}}z}f}|g:gtYxqw}~y{[~~plr1x{hnk{|~}{~~}q}sw}zohegU}veMpl.ilq}%nVcŽo_k{rjhtw\epx}~|xmd~uXBol|{oyz_|q{tl{lwzu~}wvy~}y~~}|ty~}x|oKoGx?vrgr|~\bzchfUơɂWpxEn|}xv|y]pvpu|xtmclsuAltp}qYy_Ϧmsfg|z~{h~vw|uuw{f{tjsvN~tp_k{sj{1|x{rO}pf{w}hwt~z^yv}sOxpziRgty0kq`wÖWkna~]zb~`t}/zE]z~tnoɅi|}]asscfce|~v}MyfazvvqBg\j~ǁsbli{Kmw}l}uLnb`WW^t`ajր~hto6ioxUNu~x||}~zsv}z~z}}}~~z}t~~~~z~{{t}tw|{pwzy{}{yp~~}{xv~vw~{}}}{{zx}}yx~|~xz|ty~y}~|}}~}|~~wpr}nwyx}vw}v|z}l}vx~sm|z~y{{rw~z~|~p~|u{}{zyx}}}xquj~sxvq|{z{{|}}}~}~tuwk{~}x~|v{{m}w~s}zory|{xzqw}sww|~}~|||x|{|~zy~x~ysuw}wot|}u}{|~zru{~~|xy~}}y~~{~}v~vxs~gtr}z{~xs~zp~vw|r~q}zuu~|zuv|~zwv||}l|~xz~wwz|}z~y}uzy~sywy{|z~~}~|~}{~y}}z}uxw~x|k{}}~|x}yv{~}{oz~x}~~w{~w|y|~y|wvv}ztz}zyuw}~zvsvz~}}}|t~|}{}~~~~{~z~{vyysy}{}~|}x{twt{{}~}zz{~|u}}x|z|t~z{{~|{}}}|~|~}zv{{|x~{~{~{|w}~|zw|amy}z}z~~~~uz}u{x~xtwz{~{}}~|}{yyz}~v|yzxz}~z~|~}zywz{|u{~~~xw|wzr~{zvswsy|uu}zyzxq~{xy}|x}~|q~|}z~x~z|vux|{||vw|ysx||~xws~|~~pxz~{izq{{tz}x{~ty{~}~}|||}{zu}|r{vs~q~pyyzv~}zu{~|w{~w}}|}~yx}w{z||wikr}tox{|_x|~j~m{~v{}}~|~~lvv{ye~x}x}z}y{{y}~v}|~~w{ex{v~|}}}}|m}y~z~v}~zwv|zq~|wtv~{v}yw~x~~w}w{{|z~y}{~r{rwxz|~~zsxy}}y~}~{{|yy~}}~o{}~u~}t{~|y~y{}~{zxy||wy~tzxzt|}suz}}wz||przw~t}}}yx}~|~~~||~{|m{z|x}{|y}}{yx}}vvp~{x~zw~t}{z|wt}|twt}w~y}}|{zy~|v}z{rwu|{~zx~|~y|z~|z~zo~{}~{xy~||y|ywwpu}}yz}}k}~|~~w}zzzo|z~}|v|w{{}{|z}|}yvy|{|}z~~v|zvwzyv~wyu|x|~sq}}}}vxt}|x}xn|w}y|{~{xz~~|~x{}zrzz~}{v}~~}xyu{px}~|m~{|z{}{z}zzy~~||w~}q{zz~x~n|ui|zww{{v~rr}|}z{x}zu{{w|{|~wu~r|t|~~~z|u~wnzp~}zsmq}}s|y|}}xyyu}qy{zukuw~}r|}~{~x}{}|p}~~r}~~|r~}~~pwt~}x~o}~t}~~|}~xuyttu~|{w}zp}z}}y~v}|s}}|d~{w{}r~{ztv{t|z~vw~}mw}}||||||{x{{~v{~}v}~|}~{}w}~zx}~zl}zwty{yz~|xr~uz~wy~lsz}~v|x~}t|{~yv{~{}}|x{~y~{y|}wzw}{{wzuw|u}s{~~z~z{~t}}}}{z~|xz{|z|zxx~~|~{}wy|~{z~q|qy|}u|uuytp~{wuw{{}n}||{px~}y~}~}z~|}{{z}|}uy~|w}|}~y~y}}{{~~|~|~zz}~m{xxq|}~y|w}x~|~~qx{zxx~z|}}{y|yv|w{}yoz}y|z||~yyz|syu|{wz{~}px}x{~x~{}|t~vx}|~|z~w||}s~}}}~{vw}~~us~{{t{~y~zx{o}|~zw~yz|{{{u}|t~{~pzyu~x{{s{~{{u}y}xuy{}~y{w{~~~{y~rmy~~zyv}~vwxyx|}zx|}~j|~~~{ozzz{~|uz}~}yyy{}hvzu{}~z}~}~n|m~xr}~{uwx{{z~~vuy}~|x}~|{|}y|~||{|}}wzx}puqv~{z~w~s~}~z{zv~||}fyq|}wty}z~vz~|s|zzq|yx{wxu|zz|z{|~|s}|ywt{{z{zyvsu}k{~}yq~tyvzyxl|{~~uvt{q||}~}~z{}}}uxyx|~ox}~vwz~v}{u}w~vz~qt}xly}yx{}y{}~|zw}|t|zzx|}u~|{{|}xyyt}zz~wxwxz{~o~vwv~|~wz|w|mx}yx~px|{~tr~~ujr{v~a~}~y}}qz{v}~}|yv~~w}{z~~}h|uvwyyy{x}y~z}sz{sz{z{}}}~yx~iy~{zuyx}|}ys}|w~o}uv~ty~z{}|~~~~~}~|}w|v{||}{y~~~v|y|tz{w}y|{yz}{sryy||yts||~}{~w~zp|}~}{x|}ot~x}|~vuu|s{}{znvvwcyowyxr}}{v|vtz{{t}zo|ywx~vryys~xmu{yuzt|~x{{zpyy~zv}y~wy|ozu}~yoyq~|{||tv~~|x{z|y~uzu{r|x|{~s|wx~~~}}z|w~yjq{{z~{{~~{|nph|oz~zv~u}|z~mzxvt}|{~xw}~{}u{yu|{o|{x|z}xrz{zwn}~}~noxw~yxzwkv}||{w||}z}yv|xux|u~lw}~x}~z||mu}~}x~xo~yu~|{v~ttsxlzqvyr~~r{}x||zu}t}|yy||fyzuv}wg|~}wuqpu{u}|vw{tz}^tz~w{|~qxrt~rlhy}z}tz~x}|kxwrw~}q}ypz~~v{~{xi}twvxvbv{}zy}|vz~tsia~xzh|z}}~y|{r{}||yz||~u}xr|zuwz}x}uvwx~j{~~|{~}~|wv{u}zz}v~n}}z~wmy{w{}vx}}uxsvzys~y~owu|}zz~q~~{vxxw~{zxuz{p}xx|}r{ymy}|v~q}w}|w}|w~~}yzy|{|ww{||y}}|}|}}~~x}}}~yz~u~~|}zt|y{tu}mz||~{~~{z|smte~x~~y{{r}}ul}}t}y~r~ylf||}ty}x~|s}~}}u||zyx|w}|zz|}xe~{~}{i{~}~~~}}{x{ztxyqw}zfoqum|}k|v{{{}zv|~zt~zv{~uw{uzk{zo{y}woaqs{}s}~~wy}vsxt}y{kxp{[y{a~qzzwyzg{|s|~}x|w~{z~xwpo~w~vyuytu{s~gvx}e}y{|xntytwzxu{nuvxrq|~|t}avz}y|vzxxr}}y}owvzw|{~~u|}z}w{~p{~y~z{xy}~~}uw{|yt{j}~hxw~zopwvx|{xxyxz}wm~syz{x~}iz}~zlpz~~~}rszvw|bq|tx~{ets}{|wx|{qzz~xr|{{u~}tx|}v~pwv~|x|qzz~zx|~||z|v{|~|z}u|foyvzwx}{{zx|xzzq~}~|l~wz~}}~zyx}{zt{~y|gzy}~}{|{|yyx{}~yu~zoyyq||r{u|~ss{~x~z~~}zz||}wy{~o|{x{z{u~~~y~v~}{{qul|rxtnxy~x{~yz{{xx}y~u{v}{x|~s|y|}}k|xy|tuw{y|}zz~|~|wzwzw~~}zuv{~|{}t}p~x~py|z}z}~zxyu~{y{uy|xy}{xn|vhxu|v}uyyv|v~sr~{|~t}~{|yz~}}~vxyyt}p{|yo{s|z}{zq~zoz}~yz}~~}}~{~o|~{x~s~vt~~~r}uy{{u~ptx|~vzw||vp}{h}{}yo}oy~~ywx}|u~~u{vx|xny~{x~}~~l|~}~w}~~~||}~|||~}}|~}~|yy{zuz|}y~|y|}wyy|x~~}{}~}z~~{|v~~{~|{~}yw}{|{}~{}}~z|}|xy|y}x}}~zx~}z~w~||w~~{{}|~}{y~|x~x~|~~~z}}vuw~{|~~|s|~|~|}}x~}~~}y|z}y}|}{~|||}}~~~~{{{u}~}}z{{z~~w|w~u||txsy~z{zz|}z~~z}|}}}~|{x{|}|~~|}yv{}||t{~~||{}{~~~~{{|z|y~y}wxz|{}~~z{}x~|}|y~}zu}|v|}~{~{~}~~~|s{y}z}~~~|ex|}yy~}z~|y}w~|u~{|~~|{~y}}|}yu}~~}|~~z~x}~|{}}uy|yt~y}y}~x{xyvtyy{}x~|~}~{{~~y}~z~~~}z}~}}~|v|}}}~w{~w{}x~z|{~|}}~}~p~|}~{y}~}~~l~~~y~~}~{yw}z~~zwz|y|y{{~~q{z|{||||}~~|yu}}~}}z|~z}~z|||~|~~~|~}|z~|z~v|~t}~~~|}}}}|||u{{vz}~|}~~~z{|~{~{}}~~~{|{z}~wx}|~}~~~~}}u}~}~|}|w}~}yyx}~{y~~zy{zzw~|w|uy~}zzx}{{{~tx}|~|{s{~|{~~z~}y~|~}~|{z~}}}z~}uxzx{~~~~}t}}}}zy~~~~~~|~~~~v}x~}}~{|y~yz~}}~|}xy{{}}~~{}v}}vx|{~zwxw~|~}wz}}|~}}{}z{{y}~x}x~~u|{~|~||vy|~wz|y~|{z}}}{~}|~~|y~v}y~}}}~~~~}z|z||}~~~v|z}}r}}zy~|zz}}z|}z{z{|~}~}{z}~}}|}}yv}yyx{}}w|x~~|~}}}{~}~}{y~~{{}~x~~t~|w~~xz~m 3aU!{v1UO^Rjo-EP? `qFX_ 5isfeLd_[?`WNXgVToL&_VC!DJ+iQ!;>1I{q5kL*i1bEg~z?I{ln eX=^HJY1 ff=ff=aа= >a >а= Lff=ff=aа=@> Cü >= ffaа=`>; >bh> 33s=ff=33#>a Cа=bh>z^= >bh8> =ff=33C>aPа=bh>=/= >bhX> =ff=33c>ay<а=bh>=/= >bhx> >ff=>a|=а=bh>> >14> <>ff=>az^=а=bh>'> >14> \>ff=>az^=а=bh>G> >14> |>ff=>a=/>а=bh>g> >14> ff>ff=>a=/?>а=bh>˃> >14> ff>ff=>a=/_>а=14?˓> >14> ff>ff=>a=/>а=14?ˣ> >14> ff>ff=>a>а=14?˳> >14> ff>ff=?a>а=14?> >? ff>ff=?a>а=14 ?> >? ff>ff=?a>а=14(?> >? ff>ff=?a>а=140?> >? 33?ff= ?a>а=148?? >&? 33?ff=(?a>а=14@? ? >.? 33?ff=0?a>а=14H?? >6? 33?ff=8?a?а=14P?? >>? 33'?ff=@?a?а=14X?!? >F? 33/?ff=H?a?а=14`?)? >N? 337?ff=P?a?а=14h?1? >V? 33??ff=X?a'?а=14p?9? >^? 33G?ff=`?a/?а=14x?A? >f? 33O?ff=h?a7?а=?I? >n? 33W?ff=p?a??а=?Q? >v? 33_?ff=x?aG?а=?Y? >~? 33g?ff=ff?aO?а=?a? > ? 33o?ff=ff?aW?а=?i? > ?L ff=ff= Cü= >a@>а=LLff=ff= Cü=@> Cü@>=Lff Cü=`>;@>bh>L33s=ff=33#> Cü C=bh>z^=@>bh8>L=ff=33C> CüP=bh>=/=@>bhX>L=ff=33c> Cüy<=bh>=/=@>bhx>L>ff=> Cü|==bh>>@>14>L<>ff=> Cüz^==bh>'>@>14>L\>ff=> Cüz^==bh>G>@>14>L|>ff=> Cü=/>=bh>g>@>14>Lff>ff=> Cü=/?>=bh>˃>@>14>Lff>ff=> Cü=/_>=14?˓>@>14>Lff>ff=> Cü=/>=14?ˣ>@>14>Lff>ff=> Cü>=14?˳>@>14>Lff>ff=? Cü>=14?>@>?Lff>ff=? Cü>=14 ?>@>?Lff>ff=? Cü>=14(?>@>?Lff>ff=? Cü>=140?>@>?L33?ff= ? Cü>=148??@>&?L33?ff=(? Cü>=14@? ?@>.?L33?ff=0? Cü>=14H??@>6?L33?ff=8? Cü?=14P??@>>?L33'?ff=@? Cü?=14X?!?@>F?L33/?ff=H? Cü?=14`?)?@>N?L337?ff=P? Cü?=14h?1?@>V?L33??ff=X? Cü'?=14p?9?@>^?L33G?ff=`? Cü/?=14x?A?@>f?L33O?ff=h? Cü7?=?I?@>n?L33W?ff=p? Cü??=?Q?@>v?L33_?ff=x? CüG?=?Y?@>~?L33g?ff=ff? CüO?=?a?@> ?L33o?ff=ff? CüW?=?i?@> ?ff< 33>ff=;bh> >a`>а=ffff=;bh>@> Cü`>=ff33>;bh>`>;`>bh>ff<33s=33>33#>; Cbh>bh>z^=`>bh8>ff<=33>33C>;Pbh>bh>=/=`>bhX>ff<=33>33c>;ybh>=/=`>bhx>ff<>33>>;|=bh>bh>>`>14>ff<<>33>>;z^=bh>bh>'>`>14>ff<\>33>>;z^=bh>bh>G>`>14>ff<|>33>>;=/>bh>bh>g>`>14>ff33>>;=/?>bh>bh>˃>`>14>ff33>>;=/_>bh>14?˓>`>14>ff33>>;=/>bh>14?ˣ>`>14>ff33>>;>bh>14?˳>`>14>ff33>?;>bh>14?>`>?ff33>?;>bh>14 ?>`>?ff33>?;>bh>14(?>`>?ff33>?;>bh>140?>`>?ff<33?33> ?;>bh>148??`>&?ff<33?33>(?;>bh>14@? ?`>.?ff<33?33>0?;>bh>14H??`>6?ff<33?33>8?;?bh>14P??`>>?ff<33'?33>@?;?bh>14X?!?`>F?ff<33/?33>H?;?bh>14`?)?`>N?ff<337?33>P?;?bh>14h?1?`>V?ff<33??33>X?;'?bh>14p?9?`>^?ff<33G?33>`?;/?bh>14x?A?`>f?ff<33O?33>h?;7?bh>?I?`>n?ff<33W?33>p?;??bh>?Q?`>v?ff<33_?33>x?;G?bh>?Y?`>~?ff<33g?33>ff?;O?bh>?a?`> ?ff<33o?33>ff?;W?bh>?i?`> ?33s= 33#>ff=z^=bh8> > Cabh>а=33s=L33#>ff=z^=bh8>@> C Cübh>=33s=ff<33#>33>z^=bh8>`> C;bh>bh>33s=33s=33#>33#>z^= Cbh8>bh> Cz^=bh>bh8>33s==33#>33C>z^=Pbh8>bh> C=/=bh>bhX>33s==33#>33c>z^=ybh> C=/=bh>bhx>33s=>33#>>z^=|=bh8>bh> C>bh>14>33s=<>33#>>z^=z^=bh8>bh> C'>bh>14>33s=\>33#>>z^=z^=bh8>bh> CG>bh>14>33s=|>33#>>z^==/>bh8>bh> Cg>bh>14>33s=ff>33#>>z^==/?>bh8>bh> C˃>bh>14>33s=ff>33#>>z^==/_>bh8>14? C˓>bh>14>33s=ff>33#>>z^==/>bh8>14? Cˣ>bh>14>33s=ff>33#>>z^=>bh8>14? C˳>bh>14>33s=ff>33#>?z^=>bh8>14? C>bh>?33s=ff>33#>?z^=>bh8>14 ? C>bh>?33s=ff>33#>?z^=>bh8>14(? C>bh>?33s=ff>33#>?z^=>bh8>140? C>bh>?33s=33?33#> ?z^=>bh8>148? C?bh>&?33s=33?33#>(?z^=>bh8>14@? C ?bh>.?33s=33?33#>0?z^=>bh8>14H? C?bh>6?33s=33?33#>8?z^=?bh8>14P? C?bh>>?33s=33'?33#>@?z^=?bh8>14X? C!?bh>F?33s=33/?33#>H?z^=?bh8>14`? C)?bh>N?33s=337?33#>P?z^=?bh8>14h? C1?bh>V?33s=33??33#>X?z^='?bh8>14p? C9?bh>^?33s=33G?33#>`?z^=/?bh8>14x? CA?bh>f?33s=33O?33#>h?z^=7?bh8>? CI?bh>n?33s=33W?33#>p?z^=??bh8>? CQ?bh>v?33s=33_?33#>x?z^=G?bh8>? CY?bh>~?33s=33g?33#>ff?z^=O?bh8>? Ca?bh> ?33s=33o?33#>ff?z^=W?bh8>? Ci?bh> ?= 33C>ff==/=bhX> >Pabh>а==L33C>ff==/=bhX>@>P Cübh>==ff<33C>33>=/=bhX>`>P;bh>bh>=33s=33C>33#>=/= CbhX>bh>Pz^=bh>bh8>==33C>33C>=/=PbhX>bh>P=/=bh>bhX>==33C>33c>=/=ybh>P=/=bh>bhx>=>33C>>=/=|=bhX>bh>P>bh>14>=<>33C>>=/=z^=bhX>bh>P'>bh>14>=\>33C>>=/=z^=bhX>bh>PG>bh>14>=|>33C>>=/==/>bhX>bh>Pg>bh>14>=ff>33C>>=/==/?>bhX>bh>P˃>bh>14>=ff>33C>>=/==/_>bhX>14?P˓>bh>14>=ff>33C>>=/==/>bhX>14?Pˣ>bh>14>=ff>33C>>=/=>bhX>14?P˳>bh>14>=ff>33C>?=/=>bhX>14?P>bh>?=ff>33C>?=/=>bhX>14 ?P>bh>?=ff>33C>?=/=>bhX>14(?P>bh>?=ff>33C>?=/=>bhX>140?P>bh>?=33?33C> ?=/=>bhX>148?P?bh>&?=33?33C>(?=/=>bhX>14@?P ?bh>.?=33?33C>0?=/=>bhX>14H?P?bh>6?=33?33C>8?=/=?bhX>14P?P?bh>>?=33'?33C>@?=/=?bhX>14X?P!?bh>F?=33/?33C>H?=/=?bhX>14`?P)?bh>N?=337?33C>P?=/=?bhX>14h?P1?bh>V?=33??33C>X?=/='?bhX>14p?P9?bh>^?=33G?33C>`?=/=/?bhX>14x?PA?bh>f?=33O?33C>h?=/=7?bhX>?PI?bh>n?=33W?33C>p?=/=??bhX>?PQ?bh>v?=33_?33C>x?=/=G?bhX>?PY?bh>~?=33g?33C>ff?=/=O?bhX>?Pa?bh> ?=33o?33C>ff?=/=W?bhX>?Pi?bh> ?= 33c>ff==/=bhx> >yа==L33c>ff==/=bhx>@>y< Cübh>==ff<33c>33>=/=bhx>`>y<;bh>bh>=33s=33c>33#>=/= Cbhx>bh>ybh8>==33c>33C>=/=Pbhx>bh>y<=/=bh>bhX>==33c>33c>=/=ybh>y<=/=bh>bhx>=>33c>>=/=|=bhx>bh>y<>bh>14>=<>33c>>=/=z^=bhx>bh>y<'>bh>14>=\>33c>>=/=z^=bhx>bh>ybh>14>=|>33c>>=/==/>bhx>bh>ybh>14>=ff>33c>>=/==/?>bhx>bh>y<˃>bh>14>=ff>33c>>=/==/_>bhx>14?y<˓>bh>14>=ff>33c>>=/==/>bhx>14?y<ˣ>bh>14>=ff>33c>>=/=>bhx>14?y<˳>bh>14>=ff>33c>?=/=>bhx>14?y<>bh>?=ff>33c>?=/=>bhx>14 ?y<>bh>?=ff>33c>?=/=>bhx>14(?y<>bh>?=ff>33c>?=/=>bhx>140?y<>bh>?=33?33c> ?=/=>bhx>148?y<?bh>&?=33?33c>(?=/=>bhx>14@?y< ?bh>.?=33?33c>0?=/=>bhx>14H?y<?bh>6?=33?33c>8?=/=?bhx>14P?y<?bh>>?=33'?33c>@?=/=?bhx>14X?yF?=33/?33c>H?=/=?bhx>14`?y<)?bh>N?=337?33c>P?=/=?bhx>14h?y<1?bh>V?=33??33c>X?=/='?bhx>14p?y<9?bh>^?=33G?33c>`?=/=/?bhx>14x?yf?=33O?33c>h?=/=7?bhx>?yn?=33W?33c>p?=/=??bhx>?yv?=33_?33c>x?=/=G?bhx>?y~?=33g?33c>ff?=/=O?bhx>?y ?=33o?33c>ff?=/=W?bhx>?y ?> >ff=>14> >|=abh>а=>L>ff=>14>@>|= Cübh>=>ff<>33>>14>`>|=;bh>bh>>33s=>33#>> C14>bh>|=z^=bh>bh8>>=>33C>>P14>bh>|==/=bh>bhX>>=>33c>>y<14>bh>|==/=bh>bhx>>>>>>|=14>bh>|=>bh>14>><>>>>z^=14>bh>|='>bh>14>>\>>>>z^=14>bh>|=G>bh>14>>|>>>>=/>14>bh>|=g>bh>14>>ff>>>>=/?>14>bh>|=˃>bh>14>>ff>>>>=/_>14>14?|=˓>bh>14>>ff>>>>=/>14>14?|=ˣ>bh>14>>ff>>>>>14>14?|=˳>bh>14>>ff>>?>>14>14?|=>bh>?>ff>>?>>14>14 ?|=>bh>?>ff>>?>>14>14(?|=>bh>?>ff>>?>>14>140?|=>bh>?>33?> ?>>14>148?|=?bh>&?>33?>(?>>14>14@?|= ?bh>.?>33?>0?>>14>14H?|=?bh>6?>33?>8?>?14>14P?|=?bh>>?>33'?>@?>?14>14X?|=!?bh>F?>33/?>H?>?14>14`?|=)?bh>N?>337?>P?>?14>14h?|=1?bh>V?>33??>X?>'?14>14p?|=9?bh>^?>33G?>`?>/?14>14x?|=A?bh>f?>33O?>h?>7?14>?|=I?bh>n?>33W?>p?>??14>?|=Q?bh>v?>33_?>x?>G?14>?|=Y?bh>~?>33g?>ff?>O?14>?|=a?bh> ?>33o?>ff?>W?14>?|=i?bh> ?<> >ff='>14> >z^=abh>а=<>L>ff='>14>@>z^= Cübh>=<>ff<>33>'>14>`>z^=;bh>bh><>33s=>33#>'> C14>bh>z^=z^=bh>bh8><>=>33C>'>P14>bh>z^==/=bh>bhX><>=>33c>'>y<14>bh>z^==/=bh>bhx><>>>>'>|=14>bh>z^=>bh>14><><>>>'>z^=14>bh>z^='>bh>14><>\>>>'>z^=14>bh>z^=G>bh>14><>|>>>'>=/>14>bh>z^=g>bh>14><>ff>>>'>=/?>14>bh>z^=˃>bh>14><>ff>>>'>=/_>14>14?z^=˓>bh>14><>ff>>>'>=/>14>14?z^=ˣ>bh>14><>ff>>>'>>14>14?z^=˳>bh>14><>ff>>?'>>14>14?z^=>bh>?<>ff>>?'>>14>14 ?z^=>bh>?<>ff>>?'>>14>14(?z^=>bh>?<>ff>>?'>>14>140?z^=>bh>?<>33?> ?'>>14>148?z^=?bh>&?<>33?>(?'>>14>14@?z^= ?bh>.?<>33?>0?'>>14>14H?z^=?bh>6?<>33?>8?'>?14>14P?z^=?bh>>?<>33'?>@?'>?14>14X?z^=!?bh>F?<>33/?>H?'>?14>14`?z^=)?bh>N?<>337?>P?'>?14>14h?z^=1?bh>V?<>33??>X?'>'?14>14p?z^=9?bh>^?<>33G?>`?'>/?14>14x?z^=A?bh>f?<>33O?>h?'>7?14>?z^=I?bh>n?<>33W?>p?'>??14>?z^=Q?bh>v?<>33_?>x?'>G?14>?z^=Y?bh>~?<>33g?>ff?'>O?14>?z^=a?bh> ?<>33o?>ff?'>W?14>?z^=i?bh> ?\> >ff=G>14> >z^=abh>а=\>L>ff=G>14>@>z^= Cübh>=\>ff<>33>G>14>`>z^=;bh>bh>\>33s=>33#>G> C14>bh>z^=z^=bh>bh8>\>=>33C>G>P14>bh>z^==/=bh>bhX>\>=>33c>G>y<14>bh>z^==/=bh>bhx>\>>>>G>|=14>bh>z^=>bh>14>\><>>>G>z^=14>bh>z^='>bh>14>\>\>>>G>z^=14>bh>z^=G>bh>14>\>|>>>G>=/>14>bh>z^=g>bh>14>\>ff>>>G>=/?>14>bh>z^=˃>bh>14>\>ff>>>G>=/_>14>14?z^=˓>bh>14>\>ff>>>G>=/>14>14?z^=ˣ>bh>14>\>ff>>>G>>14>14?z^=˳>bh>14>\>ff>>?G>>14>14?z^=>bh>?\>ff>>?G>>14>14 ?z^=>bh>?\>ff>>?G>>14>14(?z^=>bh>?\>ff>>?G>>14>140?z^=>bh>?\>33?> ?G>>14>148?z^=?bh>&?\>33?>(?G>>14>14@?z^= ?bh>.?\>33?>0?G>>14>14H?z^=?bh>6?\>33?>8?G>?14>14P?z^=?bh>>?\>33'?>@?G>?14>14X?z^=!?bh>F?\>33/?>H?G>?14>14`?z^=)?bh>N?\>337?>P?G>?14>14h?z^=1?bh>V?\>33??>X?G>'?14>14p?z^=9?bh>^?\>33G?>`?G>/?14>14x?z^=A?bh>f?\>33O?>h?G>7?14>?z^=I?bh>n?\>33W?>p?G>??14>?z^=Q?bh>v?\>33_?>x?G>G?14>?z^=Y?bh>~?\>33g?>ff?G>O?14>?z^=a?bh> ?\>33o?>ff?G>W?14>?z^=i?bh> ?|> >ff=g>14> >=/>abh>а=|>L>ff=g>14>@>=/> Cübh>=|>ff<>33>g>14>`>=/>;bh>bh>|>33s=>33#>g> C14>bh>=/>z^=bh>bh8>|>=>33C>g>P14>bh>=/>=/=bh>bhX>|>=>33c>g>y<14>bh>=/>=/=bh>bhx>|>>>>g>|=14>bh>=/>>bh>14>|><>>>g>z^=14>bh>=/>'>bh>14>|>\>>>g>z^=14>bh>=/>G>bh>14>|>|>>>g>=/>14>bh>=/>g>bh>14>|>ff>>>g>=/?>14>bh>=/>˃>bh>14>|>ff>>>g>=/_>14>14?=/>˓>bh>14>|>ff>>>g>=/>14>14?=/>ˣ>bh>14>|>ff>>>g>>14>14?=/>˳>bh>14>|>ff>>?g>>14>14?=/>>bh>?|>ff>>?g>>14>14 ?=/>>bh>?|>ff>>?g>>14>14(?=/>>bh>?|>ff>>?g>>14>140?=/>>bh>?|>33?> ?g>>14>148?=/>?bh>&?|>33?>(?g>>14>14@?=/> ?bh>.?|>33?>0?g>>14>14H?=/>?bh>6?|>33?>8?g>?14>14P?=/>?bh>>?|>33'?>@?g>?14>14X?=/>!?bh>F?|>33/?>H?g>?14>14`?=/>)?bh>N?|>337?>P?g>?14>14h?=/>1?bh>V?|>33??>X?g>'?14>14p?=/>9?bh>^?|>33G?>`?g>/?14>14x?=/>A?bh>f?|>33O?>h?g>7?14>?=/>I?bh>n?|>33W?>p?g>??14>?=/>Q?bh>v?|>33_?>x?g>G?14>?=/>Y?bh>~?|>33g?>ff?g>O?14>?=/>a?bh> ?|>33o?>ff?g>W?14>?=/>i?bh> ?ff> >ff=˃>14> >=/?>abh>а=ff>L>ff=˃>14>@>=/?> Cübh>=ff>ff<>33>˃>14>`>=/?>;bh>bh>ff>33s=>33#>˃> C14>bh>=/?>z^=bh>bh8>ff>=>33C>˃>P14>bh>=/?>=/=bh>bhX>ff>=>33c>˃>y<14>bh>=/?>=/=bh>bhx>ff>>>>˃>|=14>bh>=/?>>bh>14>ff><>>>˃>z^=14>bh>=/?>'>bh>14>ff>\>>>˃>z^=14>bh>=/?>G>bh>14>ff>|>>>˃>=/>14>bh>=/?>g>bh>14>ff>ff>>>˃>=/?>14>bh>=/?>˃>bh>14>ff>ff>>>˃>=/_>14>14?=/?>˓>bh>14>ff>ff>>>˃>=/>14>14?=/?>ˣ>bh>14>ff>ff>>>˃>>14>14?=/?>˳>bh>14>ff>ff>>?˃>>14>14?=/?>>bh>?ff>ff>>?˃>>14>14 ?=/?>>bh>?ff>ff>>?˃>>14>14(?=/?>>bh>?ff>ff>>?˃>>14>140?=/?>>bh>?ff>33?> ?˃>>14>148?=/?>?bh>&?ff>33?>(?˃>>14>14@?=/?> ?bh>.?ff>33?>0?˃>>14>14H?=/?>?bh>6?ff>33?>8?˃>?14>14P?=/?>?bh>>?ff>33'?>@?˃>?14>14X?=/?>!?bh>F?ff>33/?>H?˃>?14>14`?=/?>)?bh>N?ff>337?>P?˃>?14>14h?=/?>1?bh>V?ff>33??>X?˃>'?14>14p?=/?>9?bh>^?ff>33G?>`?˃>/?14>14x?=/?>A?bh>f?ff>33O?>h?˃>7?14>?=/?>I?bh>n?ff>33W?>p?˃>??14>?=/?>Q?bh>v?ff>33_?>x?˃>G?14>?=/?>Y?bh>~?ff>33g?>ff?˃>O?14>?=/?>a?bh> ?ff>33o?>ff?˃>W?14>?=/?>i?bh> ?ff> >ff=˓>14> >=/_>a14?а=ff>L>ff=˓>14>@>=/_> Cü14?=ff>ff<>33>˓>14>`>=/_>;14?bh>ff>33s=>33#>˓> C14>bh>=/_>z^=14?bh8>ff>=>33C>˓>P14>bh>=/_>=/=14?bhX>ff>=>33c>˓>y<14>bh>=/_>=/=14?bhx>ff>>>>˓>|=14>bh>=/_>>14?14>ff><>>>˓>z^=14>bh>=/_>'>14?14>ff>\>>>˓>z^=14>bh>=/_>G>14?14>ff>|>>>˓>=/>14>bh>=/_>g>14?14>ff>ff>>>˓>=/?>14>bh>=/_>˃>14?14>ff>ff>>>˓>=/_>14>14?=/_>˓>14?14>ff>ff>>>˓>=/>14>14?=/_>ˣ>14?14>ff>ff>>>˓>>14>14?=/_>˳>14?14>ff>ff>>?˓>>14>14?=/_>>14??ff>ff>>?˓>>14>14 ?=/_>>14??ff>ff>>?˓>>14>14(?=/_>>14??ff>ff>>?˓>>14>140?=/_>>14??ff>33?> ?˓>>14>148?=/_>?14?&?ff>33?>(?˓>>14>14@?=/_> ?14?.?ff>33?>0?˓>>14>14H?=/_>?14?6?ff>33?>8?˓>?14>14P?=/_>?14?>?ff>33'?>@?˓>?14>14X?=/_>!?14?F?ff>33/?>H?˓>?14>14`?=/_>)?14?N?ff>337?>P?˓>?14>14h?=/_>1?14?V?ff>33??>X?˓>'?14>14p?=/_>9?14?^?ff>33G?>`?˓>/?14>14x?=/_>A?14?f?ff>33O?>h?˓>7?14>?=/_>I?14?n?ff>33W?>p?˓>??14>?=/_>Q?14?v?ff>33_?>x?˓>G?14>?=/_>Y?14?~?ff>33g?>ff?˓>O?14>?=/_>a?14? ?ff>33o?>ff?˓>W?14>?=/_>i?14? ?ff> >ff=ˣ>14> >=/>a14?а=ff>L>ff=ˣ>14>@>=/> Cü14?=ff>ff<>33>ˣ>14>`>=/>;14?bh>ff>33s=>33#>ˣ> C14>bh>=/>z^=14?bh8>ff>=>33C>ˣ>P14>bh>=/>=/=14?bhX>ff>=>33c>ˣ>y<14>bh>=/>=/=14?bhx>ff>>>>ˣ>|=14>bh>=/>>14?14>ff><>>>ˣ>z^=14>bh>=/>'>14?14>ff>\>>>ˣ>z^=14>bh>=/>G>14?14>ff>|>>>ˣ>=/>14>bh>=/>g>14?14>ff>ff>>>ˣ>=/?>14>bh>=/>˃>14?14>ff>ff>>>ˣ>=/_>14>14?=/>˓>14?14>ff>ff>>>ˣ>=/>14>14?=/>ˣ>14?14>ff>ff>>>ˣ>>14>14?=/>˳>14?14>ff>ff>>?ˣ>>14>14?=/>>14??ff>ff>>?ˣ>>14>14 ?=/>>14??ff>ff>>?ˣ>>14>14(?=/>>14??ff>ff>>?ˣ>>14>140?=/>>14??ff>33?> ?ˣ>>14>148?=/>?14?&?ff>33?>(?ˣ>>14>14@?=/> ?14?.?ff>33?>0?ˣ>>14>14H?=/>?14?6?ff>33?>8?ˣ>?14>14P?=/>?14?>?ff>33'?>@?ˣ>?14>14X?=/>!?14?F?ff>33/?>H?ˣ>?14>14`?=/>)?14?N?ff>337?>P?ˣ>?14>14h?=/>1?14?V?ff>33??>X?ˣ>'?14>14p?=/>9?14?^?ff>33G?>`?ˣ>/?14>14x?=/>A?14?f?ff>33O?>h?ˣ>7?14>?=/>I?14?n?ff>33W?>p?ˣ>??14>?=/>Q?14?v?ff>33_?>x?ˣ>G?14>?=/>Y?14?~?ff>33g?>ff?ˣ>O?14>?=/>a?14? ?ff>33o?>ff?ˣ>W?14>?=/>i?14? ?ff> >ff=˳>14> >>a14?а=ff>L>ff=˳>14>@>> Cü14?=ff>ff<>33>˳>14>`>>;14?bh>ff>33s=>33#>˳> C14>bh>>z^=14?bh8>ff>=>33C>˳>P14>bh>>=/=14?bhX>ff>=>33c>˳>y<14>bh>>=/=14?bhx>ff>>>>˳>|=14>bh>>>14?14>ff><>>>˳>z^=14>bh>>'>14?14>ff>\>>>˳>z^=14>bh>>G>14?14>ff>|>>>˳>=/>14>bh>>g>14?14>ff>ff>>>˳>=/?>14>bh>>˃>14?14>ff>ff>>>˳>=/_>14>14?>˓>14?14>ff>ff>>>˳>=/>14>14?>ˣ>14?14>ff>ff>>>˳>>14>14?>˳>14?14>ff>ff>>?˳>>14>14?>>14??ff>ff>>?˳>>14>14 ?>>14??ff>ff>>?˳>>14>14(?>>14??ff>ff>>?˳>>14>140?>>14??ff>33?> ?˳>>14>148?>?14?&?ff>33?>(?˳>>14>14@?> ?14?.?ff>33?>0?˳>>14>14H?>?14?6?ff>33?>8?˳>?14>14P?>?14?>?ff>33'?>@?˳>?14>14X?>!?14?F?ff>33/?>H?˳>?14>14`?>)?14?N?ff>337?>P?˳>?14>14h?>1?14?V?ff>33??>X?˳>'?14>14p?>9?14?^?ff>33G?>`?˳>/?14>14x?>A?14?f?ff>33O?>h?˳>7?14>?>I?14?n?ff>33W?>p?˳>??14>?>Q?14?v?ff>33_?>x?˳>G?14>?>Y?14?~?ff>33g?>ff?˳>O?14>?>a?14? ?ff>33o?>ff?˳>W?14>?>i?14? ?ff> ?ff=>? >>a14?а=ff>L?ff=>?@>> Cü14?=ff>ff<?33>>?`>>;14?bh>ff>33s=?33#>> C?bh>>z^=14?bh8>ff>=?33C>>P?bh>>=/=14?bhX>ff>=?33c>>y<?bh>>=/=14?bhx>ff>>?>>|=?bh>>>14?14>ff><>?>>z^=?bh>>'>14?14>ff>\>?>>z^=?bh>>G>14?14>ff>|>?>>=/>?bh>>g>14?14>ff>ff>?>>=/?>?bh>>˃>14?14>ff>ff>?>>=/_>?14?>˓>14?14>ff>ff>?>>=/>?14?>ˣ>14?14>ff>ff>?>>>?14?>˳>14?14>ff>ff>??>>?14?>>14??ff>ff>??>>?14 ?>>14??ff>ff>??>>?14(?>>14??ff>ff>??>>?140?>>14??ff>33?? ?>>?148?>?14?&?ff>33??(?>>?14@?> ?14?.?ff>33??0?>>?14H?>?14?6?ff>33??8?>??14P?>?14?>?ff>33'??@?>??14X?>!?14?F?ff>33/??H?>??14`?>)?14?N?ff>337??P?>??14h?>1?14?V?ff>33???X?>'??14p?>9?14?^?ff>33G??`?>/??14x?>A?14?f?ff>33O??h?>7???>I?14?n?ff>33W??p?>????>Q?14?v?ff>33_??x?>G???>Y?14?~?ff>33g??ff?>O???>a?14? ?ff>33o??ff?>W???>i?14? ?ff> ?ff=>? >>a14 ?а=ff>L?ff=>?@>> Cü14 ?=ff>ff<?33>>?`>>;14 ?bh>ff>33s=?33#>> C?bh>>z^=14 ?bh8>ff>=?33C>>P?bh>>=/=14 ?bhX>ff>=?33c>>y<?bh>>=/=14 ?bhx>ff>>?>>|=?bh>>>14 ?14>ff><>?>>z^=?bh>>'>14 ?14>ff>\>?>>z^=?bh>>G>14 ?14>ff>|>?>>=/>?bh>>g>14 ?14>ff>ff>?>>=/?>?bh>>˃>14 ?14>ff>ff>?>>=/_>?14?>˓>14 ?14>ff>ff>?>>=/>?14?>ˣ>14 ?14>ff>ff>?>>>?14?>˳>14 ?14>ff>ff>??>>?14?>>14 ??ff>ff>??>>?14 ?>>14 ??ff>ff>??>>?14(?>>14 ??ff>ff>??>>?140?>>14 ??ff>33?? ?>>?148?>?14 ?&?ff>33??(?>>?14@?> ?14 ?.?ff>33??0?>>?14H?>?14 ?6?ff>33??8?>??14P?>?14 ?>?ff>33'??@?>??14X?>!?14 ?F?ff>33/??H?>??14`?>)?14 ?N?ff>337??P?>??14h?>1?14 ?V?ff>33???X?>'??14p?>9?14 ?^?ff>33G??`?>/??14x?>A?14 ?f?ff>33O??h?>7???>I?14 ?n?ff>33W??p?>????>Q?14 ?v?ff>33_??x?>G???>Y?14 ?~?ff>33g??ff?>O???>a?14 ? ?ff>33o??ff?>W???>i?14 ? ?ff> ?ff=>? >>a14(?а=ff>L?ff=>?@>> Cü14(?=ff>ff<?33>>?`>>;14(?bh>ff>33s=?33#>> C?bh>>z^=14(?bh8>ff>=?33C>>P?bh>>=/=14(?bhX>ff>=?33c>>y<?bh>>=/=14(?bhx>ff>>?>>|=?bh>>>14(?14>ff><>?>>z^=?bh>>'>14(?14>ff>\>?>>z^=?bh>>G>14(?14>ff>|>?>>=/>?bh>>g>14(?14>ff>ff>?>>=/?>?bh>>˃>14(?14>ff>ff>?>>=/_>?14?>˓>14(?14>ff>ff>?>>=/>?14?>ˣ>14(?14>ff>ff>?>>>?14?>˳>14(?14>ff>ff>??>>?14?>>14(??ff>ff>??>>?14 ?>>14(??ff>ff>??>>?14(?>>14(??ff>ff>??>>?140?>>14(??ff>33?? ?>>?148?>?14(?&?ff>33??(?>>?14@?> ?14(?.?ff>33??0?>>?14H?>?14(?6?ff>33??8?>??14P?>?14(?>?ff>33'??@?>??14X?>!?14(?F?ff>33/??H?>??14`?>)?14(?N?ff>337??P?>??14h?>1?14(?V?ff>33???X?>'??14p?>9?14(?^?ff>33G??`?>/??14x?>A?14(?f?ff>33O??h?>7???>I?14(?n?ff>33W??p?>????>Q?14(?v?ff>33_??x?>G???>Y?14(?~?ff>33g??ff?>O???>a?14(? ?ff>33o??ff?>W???>i?14(? ?ff> ?ff=>? >>a140?а=ff>L?ff=>?@>> Cü140?=ff>ff<?33>>?`>>;140?bh>ff>33s=?33#>> C?bh>>z^=140?bh8>ff>=?33C>>P?bh>>=/=140?bhX>ff>=?33c>>y<?bh>>=/=140?bhx>ff>>?>>|=?bh>>>140?14>ff><>?>>z^=?bh>>'>140?14>ff>\>?>>z^=?bh>>G>140?14>ff>|>?>>=/>?bh>>g>140?14>ff>ff>?>>=/?>?bh>>˃>140?14>ff>ff>?>>=/_>?14?>˓>140?14>ff>ff>?>>=/>?14?>ˣ>140?14>ff>ff>?>>>?14?>˳>140?14>ff>ff>??>>?14?>>140??ff>ff>??>>?14 ?>>140??ff>ff>??>>?14(?>>140??ff>ff>??>>?140?>>140??ff>33?? ?>>?148?>?140?&?ff>33??(?>>?14@?> ?140?.?ff>33??0?>>?14H?>?140?6?ff>33??8?>??14P?>?140?>?ff>33'??@?>??14X?>!?140?F?ff>33/??H?>??14`?>)?140?N?ff>337??P?>??14h?>1?140?V?ff>33???X?>'??14p?>9?140?^?ff>33G??`?>/??14x?>A?140?f?ff>33O??h?>7???>I?140?n?ff>33W??p?>????>Q?140?v?ff>33_??x?>G???>Y?140?~?ff>33g??ff?>O???>a?140? ?ff>33o??ff?>W???>i?140? ?33? ?ff=?&? >>a148?а=33?L ?ff=?&?@>> Cü148?=33?ff< ?33>?&?`>>;148?bh>33?33s= ?33#>? C&?bh>>z^=148?bh8>33?= ?33C>?P&?bh>>=/=148?bhX>33?= ?33c>?y<&?bh>>=/=148?bhx>33?> ?>?|=&?bh>>>148?14>33?<> ?>?z^=&?bh>>'>148?14>33?\> ?>?z^=&?bh>>G>148?14>33?|> ?>?=/>&?bh>>g>148?14>33?ff> ?>?=/?>&?bh>>˃>148?14>33?ff> ?>?=/_>&?14?>˓>148?14>33?ff> ?>?=/>&?14?>ˣ>148?14>33?ff> ?>?>&?14?>˳>148?14>33?ff> ???>&?14?>>148??33?ff> ???>&?14 ?>>148??33?ff> ???>&?14(?>>148??33?ff> ???>&?140?>>148??33?33? ? ??>&?148?>?148?&?33?33? ?(??>&?14@?> ?148?.?33?33? ?0??>&?14H?>?148?6?33?33? ?8???&?14P?>?148?>?33?33'? ?@???&?14X?>!?148?F?33?33/? ?H???&?14`?>)?148?N?33?337? ?P???&?14h?>1?148?V?33?33?? ?X??'?&?14p?>9?148?^?33?33G? ?`??/?&?14x?>A?148?f?33?33O? ?h??7?&??>I?148?n?33?33W? ?p????&??>Q?148?v?33?33_? ?x??G?&??>Y?148?~?33?33g? ?ff??O?&??>a?148? ?33?33o? ?ff??W?&??>i?148? ?33? (?ff= ?.? >>a14@?а=33?L(?ff= ?.?@>> Cü14@?=33?ff<(?33> ?.?`>>;14@?bh>33?33s=(?33#> ? C.?bh>>z^=14@?bh8>33?=(?33C> ?P.?bh>>=/=14@?bhX>33?=(?33c> ?y<.?bh>>=/=14@?bhx>33?>(?> ?|=.?bh>>>14@?14>33?<>(?> ?z^=.?bh>>'>14@?14>33?\>(?> ?z^=.?bh>>G>14@?14>33?|>(?> ?=/>.?bh>>g>14@?14>33?ff>(?> ?=/?>.?bh>>˃>14@?14>33?ff>(?> ?=/_>.?14?>˓>14@?14>33?ff>(?> ?=/>.?14?>ˣ>14@?14>33?ff>(?> ?>.?14?>˳>14@?14>33?ff>(?? ?>.?14?>>14@??33?ff>(?? ?>.?14 ?>>14@??33?ff>(?? ?>.?14(?>>14@??33?ff>(?? ?>.?140?>>14@??33?33?(? ? ?>.?148?>?14@?&?33?33?(?(? ?>.?14@?> ?14@?.?33?33?(?0? ?>.?14H?>?14@?6?33?33?(?8? ??.?14P?>?14@?>?33?33'?(?@? ??.?14X?>!?14@?F?33?33/?(?H? ??.?14`?>)?14@?N?33?337?(?P? ??.?14h?>1?14@?V?33?33??(?X? ?'?.?14p?>9?14@?^?33?33G?(?`? ?/?.?14x?>A?14@?f?33?33O?(?h? ?7?.??>I?14@?n?33?33W?(?p? ???.??>Q?14@?v?33?33_?(?x? ?G?.??>Y?14@?~?33?33g?(?ff? ?O?.??>a?14@? ?33?33o?(?ff? ?W?.??>i?14@? ?33? 0?ff=?6? >>a14H?а=33?L0?ff=?6?@>> Cü14H?=33?ff<0?33>?6?`>>;14H?bh>33?33s=0?33#>? C6?bh>>z^=14H?bh8>33?=0?33C>?P6?bh>>=/=14H?bhX>33?=0?33c>?y<6?bh>>=/=14H?bhx>33?>0?>?|=6?bh>>>14H?14>33?<>0?>?z^=6?bh>>'>14H?14>33?\>0?>?z^=6?bh>>G>14H?14>33?|>0?>?=/>6?bh>>g>14H?14>33?ff>0?>?=/?>6?bh>>˃>14H?14>33?ff>0?>?=/_>6?14?>˓>14H?14>33?ff>0?>?=/>6?14?>ˣ>14H?14>33?ff>0?>?>6?14?>˳>14H?14>33?ff>0???>6?14?>>14H??33?ff>0???>6?14 ?>>14H??33?ff>0???>6?14(?>>14H??33?ff>0???>6?140?>>14H??33?33?0? ??>6?148?>?14H?&?33?33?0?(??>6?14@?> ?14H?.?33?33?0?0??>6?14H?>?14H?6?33?33?0?8???6?14P?>?14H?>?33?33'?0?@???6?14X?>!?14H?F?33?33/?0?H???6?14`?>)?14H?N?33?337?0?P???6?14h?>1?14H?V?33?33??0?X??'?6?14p?>9?14H?^?33?33G?0?`??/?6?14x?>A?14H?f?33?33O?0?h??7?6??>I?14H?n?33?33W?0?p????6??>Q?14H?v?33?33_?0?x??G?6??>Y?14H?~?33?33g?0?ff??O?6??>a?14H? ?33?33o?0?ff??W?6??>i?14H? ?33? 8?ff=?>? >?a14P?а=33?L8?ff=?>?@>? Cü14P?=33?ff<8?33>?>?`>?;14P?bh>33?33s=8?33#>? C>?bh>?z^=14P?bh8>33?=8?33C>?P>?bh>?=/=14P?bhX>33?=8?33c>?y<>?bh>?=/=14P?bhx>33?>8?>?|=>?bh>?>14P?14>33?<>8?>?z^=>?bh>?'>14P?14>33?\>8?>?z^=>?bh>?G>14P?14>33?|>8?>?=/>>?bh>?g>14P?14>33?ff>8?>?=/?>>?bh>?˃>14P?14>33?ff>8?>?=/_>>?14??˓>14P?14>33?ff>8?>?=/>>?14??ˣ>14P?14>33?ff>8?>?>>?14??˳>14P?14>33?ff>8???>>?14??>14P??33?ff>8???>>?14 ??>14P??33?ff>8???>>?14(??>14P??33?ff>8???>>?140??>14P??33?33?8? ??>>?148???14P?&?33?33?8?(??>>?14@?? ?14P?.?33?33?8?0??>>?14H???14P?6?33?33?8?8???>?14P???14P?>?33?33'?8?@???>?14X??!?14P?F?33?33/?8?H???>?14`??)?14P?N?33?337?8?P???>?14h??1?14P?V?33?33??8?X??'?>?14p??9?14P?^?33?33G?8?`??/?>?14x??A?14P?f?33?33O?8?h??7?>???I?14P?n?33?33W?8?p????>???Q?14P?v?33?33_?8?x??G?>???Y?14P?~?33?33g?8?ff??O?>???a?14P? ?33?33o?8?ff??W?>???i?14P? ?33'? @?ff=!?F? >?a14X?а=33'?L@?ff=!?F?@>? Cü14X?=33'?ff<@?33>!?F?`>?;14X?bh>33'?33s=@?33#>!? CF?bh>?z^=14X?bh8>33'?=@?33C>!?PF?bh>?=/=14X?bhX>33'?=@?33c>!?y<F?bh>?=/=14X?bhx>33'?>@?>!?|=F?bh>?>14X?14>33'?<>@?>!?z^=F?bh>?'>14X?14>33'?\>@?>!?z^=F?bh>?G>14X?14>33'?|>@?>!?=/>F?bh>?g>14X?14>33'?ff>@?>!?=/?>F?bh>?˃>14X?14>33'?ff>@?>!?=/_>F?14??˓>14X?14>33'?ff>@?>!?=/>F?14??ˣ>14X?14>33'?ff>@?>!?>F?14??˳>14X?14>33'?ff>@??!?>F?14??>14X??33'?ff>@??!?>F?14 ??>14X??33'?ff>@??!?>F?14(??>14X??33'?ff>@??!?>F?140??>14X??33'?33?@? ?!?>F?148???14X?&?33'?33?@?(?!?>F?14@?? ?14X?.?33'?33?@?0?!?>F?14H???14X?6?33'?33?@?8?!??F?14P???14X?>?33'?33'?@?@?!??F?14X??!?14X?F?33'?33/?@?H?!??F?14`??)?14X?N?33'?337?@?P?!??F?14h??1?14X?V?33'?33??@?X?!?'?F?14p??9?14X?^?33'?33G?@?`?!?/?F?14x??A?14X?f?33'?33O?@?h?!?7?F???I?14X?n?33'?33W?@?p?!???F???Q?14X?v?33'?33_?@?x?!?G?F???Y?14X?~?33'?33g?@?ff?!?O?F???a?14X? ?33'?33o?@?ff?!?W?F???i?14X? ?33/? H?ff=)?N? >?a14`?а=33/?LH?ff=)?N?@>? Cü14`?=33/?ff)?N?`>?;14`?bh>33/?33s=H?33#>)? CN?bh>?z^=14`?bh8>33/?=H?33C>)?PN?bh>?=/=14`?bhX>33/?=H?33c>)?y<N?bh>?=/=14`?bhx>33/?>H?>)?|=N?bh>?>14`?14>33/?<>H?>)?z^=N?bh>?'>14`?14>33/?\>H?>)?z^=N?bh>?G>14`?14>33/?|>H?>)?=/>N?bh>?g>14`?14>33/?ff>H?>)?=/?>N?bh>?˃>14`?14>33/?ff>H?>)?=/_>N?14??˓>14`?14>33/?ff>H?>)?=/>N?14??ˣ>14`?14>33/?ff>H?>)?>N?14??˳>14`?14>33/?ff>H??)?>N?14??>14`??33/?ff>H??)?>N?14 ??>14`??33/?ff>H??)?>N?14(??>14`??33/?ff>H??)?>N?140??>14`??33/?33?H? ?)?>N?148???14`?&?33/?33?H?(?)?>N?14@?? ?14`?.?33/?33?H?0?)?>N?14H???14`?6?33/?33?H?8?)??N?14P???14`?>?33/?33'?H?@?)??N?14X??!?14`?F?33/?33/?H?H?)??N?14`??)?14`?N?33/?337?H?P?)??N?14h??1?14`?V?33/?33??H?X?)?'?N?14p??9?14`?^?33/?33G?H?`?)?/?N?14x??A?14`?f?33/?33O?H?h?)?7?N???I?14`?n?33/?33W?H?p?)???N???Q?14`?v?33/?33_?H?x?)?G?N???Y?14`?~?33/?33g?H?ff?)?O?N???a?14`? ?33/?33o?H?ff?)?W?N???i?14`? ?337? P?ff=1?V? >?a14h?а=337?LP?ff=1?V?@>? Cü14h?=337?ff1?V?`>?;14h?bh>337?33s=P?33#>1? CV?bh>?z^=14h?bh8>337?=P?33C>1?PV?bh>?=/=14h?bhX>337?=P?33c>1?y<V?bh>?=/=14h?bhx>337?>P?>1?|=V?bh>?>14h?14>337?<>P?>1?z^=V?bh>?'>14h?14>337?\>P?>1?z^=V?bh>?G>14h?14>337?|>P?>1?=/>V?bh>?g>14h?14>337?ff>P?>1?=/?>V?bh>?˃>14h?14>337?ff>P?>1?=/_>V?14??˓>14h?14>337?ff>P?>1?=/>V?14??ˣ>14h?14>337?ff>P?>1?>V?14??˳>14h?14>337?ff>P??1?>V?14??>14h??337?ff>P??1?>V?14 ??>14h??337?ff>P??1?>V?14(??>14h??337?ff>P??1?>V?140??>14h??337?33?P? ?1?>V?148???14h?&?337?33?P?(?1?>V?14@?? ?14h?.?337?33?P?0?1?>V?14H???14h?6?337?33?P?8?1??V?14P???14h?>?337?33'?P?@?1??V?14X??!?14h?F?337?33/?P?H?1??V?14`??)?14h?N?337?337?P?P?1??V?14h??1?14h?V?337?33??P?X?1?'?V?14p??9?14h?^?337?33G?P?`?1?/?V?14x??A?14h?f?337?33O?P?h?1?7?V???I?14h?n?337?33W?P?p?1???V???Q?14h?v?337?33_?P?x?1?G?V???Y?14h?~?337?33g?P?ff?1?O?V???a?14h? ?337?33o?P?ff?1?W?V???i?14h? ?33?? X?ff=9?^? >'?a14p?а=33??LX?ff=9?^?@>'? Cü14p?=33??ff9?^?`>'?;14p?bh>33??33s=X?33#>9? C^?bh>'?z^=14p?bh8>33??=X?33C>9?P^?bh>'?=/=14p?bhX>33??=X?33c>9?y<^?bh>'?=/=14p?bhx>33??>X?>9?|=^?bh>'?>14p?14>33??<>X?>9?z^=^?bh>'?'>14p?14>33??\>X?>9?z^=^?bh>'?G>14p?14>33??|>X?>9?=/>^?bh>'?g>14p?14>33??ff>X?>9?=/?>^?bh>'?˃>14p?14>33??ff>X?>9?=/_>^?14?'?˓>14p?14>33??ff>X?>9?=/>^?14?'?ˣ>14p?14>33??ff>X?>9?>^?14?'?˳>14p?14>33??ff>X??9?>^?14?'?>14p??33??ff>X??9?>^?14 ?'?>14p??33??ff>X??9?>^?14(?'?>14p??33??ff>X??9?>^?140?'?>14p??33??33?X? ?9?>^?148?'??14p?&?33??33?X?(?9?>^?14@?'? ?14p?.?33??33?X?0?9?>^?14H?'??14p?6?33??33?X?8?9??^?14P?'??14p?>?33??33'?X?@?9??^?14X?'?!?14p?F?33??33/?X?H?9??^?14`?'?)?14p?N?33??337?X?P?9??^?14h?'?1?14p?V?33??33??X?X?9?'?^?14p?'?9?14p?^?33??33G?X?`?9?/?^?14x?'?A?14p?f?33??33O?X?h?9?7?^??'?I?14p?n?33??33W?X?p?9???^??'?Q?14p?v?33??33_?X?x?9?G?^??'?Y?14p?~?33??33g?X?ff?9?O?^??'?a?14p? ?33??33o?X?ff?9?W?^??'?i?14p? ?33G? `?ff=A?f? >/?a14x?а=33G?L`?ff=A?f?@>/? Cü14x?=33G?ff<`?33>A?f?`>/?;14x?bh>33G?33s=`?33#>A? Cf?bh>/?z^=14x?bh8>33G?=`?33C>A?Pf?bh>/?=/=14x?bhX>33G?=`?33c>A?y<f?bh>/?=/=14x?bhx>33G?>`?>A?|=f?bh>/?>14x?14>33G?<>`?>A?z^=f?bh>/?'>14x?14>33G?\>`?>A?z^=f?bh>/?G>14x?14>33G?|>`?>A?=/>f?bh>/?g>14x?14>33G?ff>`?>A?=/?>f?bh>/?˃>14x?14>33G?ff>`?>A?=/_>f?14?/?˓>14x?14>33G?ff>`?>A?=/>f?14?/?ˣ>14x?14>33G?ff>`?>A?>f?14?/?˳>14x?14>33G?ff>`??A?>f?14?/?>14x??33G?ff>`??A?>f?14 ?/?>14x??33G?ff>`??A?>f?14(?/?>14x??33G?ff>`??A?>f?140?/?>14x??33G?33?`? ?A?>f?148?/??14x?&?33G?33?`?(?A?>f?14@?/? ?14x?.?33G?33?`?0?A?>f?14H?/??14x?6?33G?33?`?8?A??f?14P?/??14x?>?33G?33'?`?@?A??f?14X?/?!?14x?F?33G?33/?`?H?A??f?14`?/?)?14x?N?33G?337?`?P?A??f?14h?/?1?14x?V?33G?33??`?X?A?'?f?14p?/?9?14x?^?33G?33G?`?`?A?/?f?14x?/?A?14x?f?33G?33O?`?h?A?7?f??/?I?14x?n?33G?33W?`?p?A???f??/?Q?14x?v?33G?33_?`?x?A?G?f??/?Y?14x?~?33G?33g?`?ff?A?O?f??/?a?14x? ?33G?33o?`?ff?A?W?f??/?i?14x? ?33O? h?ff=I?n? >7?a?а=33O?Lh?ff=I?n?@>7? Cü?=33O?ffI?n?`>7?;?bh>33O?33s=h?33#>I? Cn?bh>7?z^=?bh8>33O?=h?33C>I?Pn?bh>7?=/=?bhX>33O?=h?33c>I?y<n?bh>7?=/=?bhx>33O?>h?>I?|=n?bh>7?>?14>33O?<>h?>I?z^=n?bh>7?'>?14>33O?\>h?>I?z^=n?bh>7?G>?14>33O?|>h?>I?=/>n?bh>7?g>?14>33O?ff>h?>I?=/?>n?bh>7?˃>?14>33O?ff>h?>I?=/_>n?14?7?˓>?14>33O?ff>h?>I?=/>n?14?7?ˣ>?14>33O?ff>h?>I?>n?14?7?˳>?14>33O?ff>h??I?>n?14?7?>??33O?ff>h??I?>n?14 ?7?>??33O?ff>h??I?>n?14(?7?>??33O?ff>h??I?>n?140?7?>??33O?33?h? ?I?>n?148?7???&?33O?33?h?(?I?>n?14@?7? ??.?33O?33?h?0?I?>n?14H?7???6?33O?33?h?8?I??n?14P?7???>?33O?33'?h?@?I??n?14X?7?!??F?33O?33/?h?H?I??n?14`?7?)??N?33O?337?h?P?I??n?14h?7?1??V?33O?33??h?X?I?'?n?14p?7?9??^?33O?33G?h?`?I?/?n?14x?7?A??f?33O?33O?h?h?I?7?n??7?I??n?33O?33W?h?p?I???n??7?Q??v?33O?33_?h?x?I?G?n??7?Y??~?33O?33g?h?ff?I?O?n??7?a?? ?33O?33o?h?ff?I?W?n??7?i?? ?33W? p?ff=Q?v? >??a?а=33W?Lp?ff=Q?v?@>?? Cü?=33W?ffQ?v?`>??;?bh>33W?33s=p?33#>Q? Cv?bh>??z^=?bh8>33W?=p?33C>Q?Pv?bh>??=/=?bhX>33W?=p?33c>Q?y<v?bh>??=/=?bhx>33W?>p?>Q?|=v?bh>??>?14>33W?<>p?>Q?z^=v?bh>??'>?14>33W?\>p?>Q?z^=v?bh>??G>?14>33W?|>p?>Q?=/>v?bh>??g>?14>33W?ff>p?>Q?=/?>v?bh>??˃>?14>33W?ff>p?>Q?=/_>v?14???˓>?14>33W?ff>p?>Q?=/>v?14???ˣ>?14>33W?ff>p?>Q?>v?14???˳>?14>33W?ff>p??Q?>v?14???>??33W?ff>p??Q?>v?14 ???>??33W?ff>p??Q?>v?14(???>??33W?ff>p??Q?>v?140???>??33W?33?p? ?Q?>v?148?????&?33W?33?p?(?Q?>v?14@??? ??.?33W?33?p?0?Q?>v?14H?????6?33W?33?p?8?Q??v?14P?????>?33W?33'?p?@?Q??v?14X???!??F?33W?33/?p?H?Q??v?14`???)??N?33W?337?p?P?Q??v?14h???1??V?33W?33??p?X?Q?'?v?14p???9??^?33W?33G?p?`?Q?/?v?14x???A??f?33W?33O?p?h?Q?7?v????I??n?33W?33W?p?p?Q???v????Q??v?33W?33_?p?x?Q?G?v????Y??~?33W?33g?p?ff?Q?O?v????a?? ?33W?33o?p?ff?Q?W?v????i?? ?33_? x?ff=Y?~? >G?a?а=33_?Lx?ff=Y?~?@>G? Cü?=33_?ffY?~?`>G?;?bh>33_?33s=x?33#>Y? C~?bh>G?z^=?bh8>33_?=x?33C>Y?P~?bh>G?=/=?bhX>33_?=x?33c>Y?y<~?bh>G?=/=?bhx>33_?>x?>Y?|=~?bh>G?>?14>33_?<>x?>Y?z^=~?bh>G?'>?14>33_?\>x?>Y?z^=~?bh>G?G>?14>33_?|>x?>Y?=/>~?bh>G?g>?14>33_?ff>x?>Y?=/?>~?bh>G?˃>?14>33_?ff>x?>Y?=/_>~?14?G?˓>?14>33_?ff>x?>Y?=/>~?14?G?ˣ>?14>33_?ff>x?>Y?>~?14?G?˳>?14>33_?ff>x??Y?>~?14?G?>??33_?ff>x??Y?>~?14 ?G?>??33_?ff>x??Y?>~?14(?G?>??33_?ff>x??Y?>~?140?G?>??33_?33?x? ?Y?>~?148?G???&?33_?33?x?(?Y?>~?14@?G? ??.?33_?33?x?0?Y?>~?14H?G???6?33_?33?x?8?Y??~?14P?G???>?33_?33'?x?@?Y??~?14X?G?!??F?33_?33/?x?H?Y??~?14`?G?)??N?33_?337?x?P?Y??~?14h?G?1??V?33_?33??x?X?Y?'?~?14p?G?9??^?33_?33G?x?`?Y?/?~?14x?G?A??f?33_?33O?x?h?Y?7?~??G?I??n?33_?33W?x?p?Y???~??G?Q??v?33_?33_?x?x?Y?G?~??G?Y??~?33_?33g?x?ff?Y?O?~??G?a?? ?33_?33o?x?ff?Y?W?~??G?i?? ?33g? ff?ff=a? ? >O?a?а=33g?Lff?ff=a? ?@>O? Cü?=33g?ffa? ?`>O?;?bh>33g?33s=ff?33#>a? C ?bh>O?z^=?bh8>33g?=ff?33C>a?P ?bh>O?=/=?bhX>33g?=ff?33c>a?y< ?bh>O?=/=?bhx>33g?>ff?>a?|= ?bh>O?>?14>33g?<>ff?>a?z^= ?bh>O?'>?14>33g?\>ff?>a?z^= ?bh>O?G>?14>33g?|>ff?>a?=/> ?bh>O?g>?14>33g?ff>ff?>a?=/?> ?bh>O?˃>?14>33g?ff>ff?>a?=/_> ?14?O?˓>?14>33g?ff>ff?>a?=/> ?14?O?ˣ>?14>33g?ff>ff?>a?> ?14?O?˳>?14>33g?ff>ff??a?> ?14?O?>??33g?ff>ff??a?> ?14 ?O?>??33g?ff>ff??a?> ?14(?O?>??33g?ff>ff??a?> ?140?O?>??33g?33?ff? ?a?> ?148?O???&?33g?33?ff?(?a?> ?14@?O? ??.?33g?33?ff?0?a?> ?14H?O???6?33g?33?ff?8?a?? ?14P?O???>?33g?33'?ff?@?a?? ?14X?O?!??F?33g?33/?ff?H?a?? ?14`?O?)??N?33g?337?ff?P?a?? ?14h?O?1??V?33g?33??ff?X?a?'? ?14p?O?9??^?33g?33G?ff?`?a?/? ?14x?O?A??f?33g?33O?ff?h?a?7? ??O?I??n?33g?33W?ff?p?a??? ??O?Q??v?33g?33_?ff?x?a?G? ??O?Y??~?33g?33g?ff?ff?a?O? ??O?a?? ?33g?33o?ff?ff?a?W? ??O?i?? ?33o? ff?ff=i? ? >W?a?а=33o?Lff?ff=i? ?@>W? Cü?=33o?ffi? ?`>W?;?bh>33o?33s=ff?33#>i? C ?bh>W?z^=?bh8>33o?=ff?33C>i?P ?bh>W?=/=?bhX>33o?=ff?33c>i?y< ?bh>W?=/=?bhx>33o?>ff?>i?|= ?bh>W?>?14>33o?<>ff?>i?z^= ?bh>W?'>?14>33o?\>ff?>i?z^= ?bh>W?G>?14>33o?|>ff?>i?=/> ?bh>W?g>?14>33o?ff>ff?>i?=/?> ?bh>W?˃>?14>33o?ff>ff?>i?=/_> ?14?W?˓>?14>33o?ff>ff?>i?=/> ?14?W?ˣ>?14>33o?ff>ff?>i?> ?14?W?˳>?14>33o?ff>ff??i?> ?14?W?>??33o?ff>ff??i?> ?14 ?W?>??33o?ff>ff??i?> ?14(?W?>??33o?ff>ff??i?> ?140?W?>??33o?33?ff? ?i?> ?148?W???&?33o?33?ff?(?i?> ?14@?W? ??.?33o?33?ff?0?i?> ?14H?W???6?33o?33?ff?8?i?? ?14P?W???>?33o?33'?ff?@?i?? ?14X?W?!??F?33o?33/?ff?H?i?? ?14`?W?)??N?33o?337?ff?P?i?? ?14h?W?1??V?33o?33??ff?X?i?'? ?14p?W?9??^?33o?33G?ff?`?i?/? ?14x?W?A??f?33o?33O?ff?h?i?7? ??W?I??n?33o?33W?ff?p?i??? ??W?Q??v?33o?33_?ff?x?i?G? ??W?Y??~?33o?33g?ff?ff?i?O? ??W?a?? ?33o?33o?ff?ff?i?W? ??W?i?? ?432343S>23S>[/6Y/6[/v>Y/v>VmSm]>>Vm]Sm>>쎽1v>1>3x鎽3>t>43df43S>>[/6^[/v>>VmSm>>Vm]L>^>쎽,bVv>1>33>tG>4343S>>[/6dX[/v>>Vmں>>Vm]Z%=>U[>쎽,bv>1>3-b=3>^>43833=43S>>[/6p +<[/v>>Vmj뼫>>Vm]=>U[>쎽XĬv>?3=3>^>43=43S>>[/6N=[/v>>VmJ +=>U[?Vm]VI!>>U[>쎽`v>?3D8>3>^>43,>43S>?[/6 >[/v>֋ ?VmZ%=>U[?Vm]VIa>>U[>쎽Pw&=v>%?3Dx>3>^>43l>43S>?[/6I>[/v>֋?Vm">>U['?Vm]>>?쎽;=v>5?3E>3>/?43gf>43S>$?[/6T>[/v>֋-?Vmb>>U[7?Vm]>>?쎽ԝ)>v>E?3E>3>/?43gf>43S>4?[/6T>[/v>֋=?VmVI>>U[G?Vm]>>'?쎽ԝi>v>U?3E>3>/!?43gf>43S>D?[/6T>[/v>֋M?VmVI>>U[W?Vm]>>7?쎽Δ>v>e?3E>3>/1?43gf>43S>T?[/6T>[/v>֋]?VmVI>>U[g?Vm]VR?>G?쎽δ>v>u?3"?3>/A?4343 ?43S>d?[/6*t?[/v>֋m?VmVI>>U[w?Vm]VR?>W?쎽>v>F̂?3"?3>/Q?4343?43S>t?[/6*t?[/v>֋}?Vm?>?Vm]VR(?>g?쎽>v>F̊?3".?3>/a?4343+?43S>ff?[/6*t"?[/v>ņ?Vm?>?Vm]VR8?>w?쎽ug +?v>F̒?3">?3>/q?4343;?43S>ff?[/6*t2?[/v>Ŏ?Vm(?>?Vm]VRH?>փ?쎽ug?v>F̚?3"N?3>?4343K?43S>ff?[/6*tB?[/v>Ŗ?Vm8?>?Vm]VRX?>֋?쎽ug*?v>F̢?3"^?3>?hf23>23S>^Y/6>Y/v>XSm]^>>VmSm>>1vG>1>&fVx鎽3>t>hfdf>>^콲^콮>>XSm^>>VmL>^>,bVvG>1>&fV3>tG>hf>>^dX>>Xں^>>VmZ%=>U[>,bvG>1>&fV-b=3>^>hf833=>>^p +<>>Xj뼫^>>Vm=>U[>XĬvG>?&fV=3>^>hf=>>^N=>>XJ +=^>U[?VmVI!>>U[>`vG>?&fVD8>3>^>hf,>>?^콧 >>֋ ?XZ%=^>U[?VmVIa>>U[>Pw&=vG>%?&fVDx>3>^>hfl>>?^콧I>>֋?X">^>U['?Vm>>?;=vG>5?&fVE>3>/?hfgf>>$?^T>>֋-?Xb>^>U[7?Vm>>?ԝ)>vG>E?&fVE>3>/?hfgf>>4?^T>>֋=?XVI>^>U[G?Vm>>'?ԝi>vG>U?&fVE>3>/!?hfgf>>D?^T>>֋M?XVI>^>U[W?Vm>>7?Δ>vG>e?&fVE>3>/1?hfgf>>T?^T>>֋]?XVI>^>U[g?VmVR?>G?δ>vG>u?&fV"?3>/A?hf43 ?>d?^*t?>֋m?XVI>^>U[w?VmVR?>W?>vG>F̂?&fV"?3>/Q?hf43?>t?^*t?>֋}?X?^>?VmVR(?>g?>vG>F̊?&fV".?3>/a?hf43+?>ff?^*t"?>ņ?X?^>?VmVR8?>w?ug +?vG>F̒?&fV">?3>/q?hf43;?>ff?^*t2?>Ŏ?X(?^>?VmVRH?>փ?ug?vG>F̚?&fV"N?3>?hf43K?>ff?^*tB?>Ŗ?X8?^>?VmVRX?>֋?ug*?vG>F̢?&fV"^?3>?23>23S>lXY/6>Y/v>T%=Sm]V[>>ںSm>>'b=1>1>&fx鎽3>t>df>>lX^콮>>T%=SmV[>>ںL>^>'b=,bV>1>&f3>tG>>>lXdX>>T%=ںV[>>ںZ%=>U[>'b=,b>1>&f-b=3>^>833=>>lXp +<>>T%=jV[>>ں=>U[>'b=XĬ>?&f=3>^>=>>lXN=>>T%=J +=V[>U[?ںVI!>>U[>'b=`>?&fD8>3>^>,>>?lX >>֋ ?T%=Z%=V[>U[?ںVIa>>U[>'b=Pw&=>%?&fDx>3>^>l>>?lXI>>֋?T%=">V[>U['?ں>>?'b=;=>5?&fE>3>/?gf>>$?lXT>>֋-?T%=b>V[>U[7?ں>>?'b=ԝ)>>E?&fE>3>/?gf>>4?lXT>>֋=?T%=VI>V[>U[G?ں>>'?'b=ԝi>>U?&fE>3>/!?gf>>D?lXT>>֋M?T%=VI>V[>U[W?ں>>7?'b=Δ>>e?&fE>3>/1?gf>>T?lXT>>֋]?T%=VI>V[>U[g?ںVR?>G?'b=δ>>u?&f"?3>/A?43 ?>d?lX*t?>֋m?T%=VI>V[>U[w?ںVR?>W?'b=>>F̂?&f"?3>/Q?43?>t?lX*t?>֋}?T%=?V[>?ںVR(?>g?'b=>>F̊?&f".?3>/a?43+?>ff?lX*t"?>ņ?T%=?V[>?ںVR8?>w?'b=ug +?>F̒?&f">?3>/q?43;?>ff?lX*t2?>Ŏ?T%=(?V[>?ںVRH?>փ?'b=ug?>F̚?&f"N?3>?43K?>ff?lX*tB?>Ŗ?T%=8?V[>?ںVRX?>֋?'b=ug*?>F̢?&f"^?3>?033=23>23S>P +Y/v>=Sm]V[>>jSm>>=1>1>L̬x鎽?t>033=df>>P +<^콮>>=SmV[>>jL>^>=,bV>1>L̬?tG>033=>>P +>=ںV[>>jZ%=>U[>=,b>1>L̬-b=?^>033=833=>>P +

>=jV[>>j뼭=>U[>=XĬ>?L̬=?^>033==>>P +>=J +=V[>U[?jVI!>>U[>=`>?L̬D8>?^>033=,>>?P +< >>֋ ?=Z%=V[>U[?jVIa>>U[>=Pw&=>%?L̬Dx>?^>033=l>>?P +>֋?=">V[>U['?j뼫>>?=;=>5?L̬E>?/?033=gf>>$?P +>֋-?=b>V[>U[7?j뼫>>?=ԝ)>>E?L̬E>?/?033=gf>>4?P +>֋=?=VI>V[>U[G?j뼫>>'?=ԝi>>U?L̬E>?/!?033=gf>>D?P +>֋M?=VI>V[>U[W?j뼫>>7?=Δ>>e?L̬E>?/1?033=gf>>T?P +>֋]?=VI>V[>U[g?jVR?>G?=δ>>u?L̬"??/A?033=43 ?>d?P +<*t?>֋m?=VI>V[>U[w?jVR?>W?=>>F̂?L̬"??/Q?033=43?>t?P +<*t?>֋}?=?V[>?jVR(?>g?=>>F̊?L̬".??/a?033=43+?>ff?P +<*t"?>ņ?=?V[>?jVR8?>w?=ug +?>F̒?L̬">??/q?033=43;?>ff?P +<*t2?>Ŏ?=(?V[>?jVRH?>փ?=ug?>F̚?L̬"N???033=43K?>ff?P +<*tB?>Ŗ?=8?V[>?jVRX?>֋?=ug*?>F̢?L̬"^???=23>23S>J=Y/6>Y/v>UI!>Sm]V[>>J +=SmV[?>8>1>1>01x鎽?t>=df>>J=^콮>>UI!>SmV[>>J +=LV[?^>8>,bV>1>01?tG>=>>J=dX>>UI!>ںV[>>J +=Z%=V[?U[>8>,b>1>01-b=?^>=833=>>J=p +<>>UI!>jV[>>J +==V[?U[>8>XĬ>?01=?^>==>>J=N=>>UI!>J +=V[>U[?J +=VI!>V[?U[>8>`>?01D8>?^>=,>>?J= >>֋ ?UI!>Z%=V[>U[?J +=VIa>V[?U[>8>Pw&=>%?01Dx>?^>=l>>?J=I>>֋?UI!>">V[>U['?J +=>V[??8>;=>5?01E>?/?=gf>>$?J=T>>֋-?UI!>b>V[>U[7?J +=>V[??8>ԝ)>>E?01E>?/?=gf>>4?J=T>>֋=?UI!>VI>V[>U[G?J +=>V[?'?8>ԝi>>U?01E>?/!?=gf>>D?J=T>>֋M?UI!>VI>V[>U[W?J +=>V[?7?8>Δ>>e?01E>?/1?=gf>>T?J=T>>֋]?UI!>VI>V[>U[g?J +=VR?V[?G?8>δ>>u?01"??/A?=43 ?>d?J=*t?>֋m?UI!>VI>V[>U[w?J +=VR?V[?W?8>>>F̂?01"??/Q?=43?>t?J=*t?>֋}?UI!>?V[>?J +=VR(?V[?g?8>>>F̊?01".??/a?=43+?>ff?J=*t"?>ņ?UI!>?V[>?J +=VR8?V[?w?8>ug +?>F̒?01">??/q?=43;?>ff?J=*t2?>Ŏ?UI!>(?V[>?J +=VRH?V[?փ?8>ug?>F̚?01"N???=43K?>ff?J=*tB?>Ŗ?UI!>8?V[>?J +=VRX?V[?֋?8>ug*?>F̢?01"^???,>23?23S> >Y/6׋ ?Y/v>UIa>Sm]V[>>T%=SmV[?>x>1>1>hg&=x鎽%?t>,>df?> >^׋ ?>UIa>SmV[>>T%=LV[?^>x>,bV>1>hg&=%?tG>,>?> >dX׋ ?>UIa>ںV[>>T%=Z%=V[?U[>x>,b>1>hg&=-b=%?^>,>833=?> >p +<׋ ?>UIa>jV[>>T%==V[?U[>x>XĬ>?hg&==%?^>,>=?> >N=׋ ?>UIa>J +=V[>U[?T%=VI!>V[?U[>x>`>?hg&=D8>%?^>,>,>?? > >׋ ?֋ ?UIa>Z%=V[>U[?T%=VIa>V[?U[>x>Pw&=>%?hg&=Dx>%?^>,>l>?? >I>׋ ?֋?UIa>">V[>U['?T%=>V[??x>;=>5?hg&=E>%?/?,>gf>?$? >T>׋ ?֋-?UIa>b>V[>U[7?T%=>V[??x>ԝ)>>E?hg&=E>%?/?,>gf>?4? >T>׋ ?֋=?UIa>VI>V[>U[G?T%=>V[?'?x>ԝi>>U?hg&=E>%?/!?,>gf>?D? >T>׋ ?֋M?UIa>VI>V[>U[W?T%=>V[?7?x>Δ>>e?hg&=E>%?/1?,>gf>?T? >T>׋ ?֋]?UIa>VI>V[>U[g?T%=VR?V[?G?x>δ>>u?hg&="?%?/A?,>43 ??d? >*t?׋ ?֋m?UIa>VI>V[>U[w?T%=VR?V[?W?x>>>F̂?hg&="?%?/Q?,>43??t? >*t?׋ ?֋}?UIa>?V[>?T%=VR(?V[?g?x>>>F̊?hg&=".?%?/a?,>43+??ff? >*t"?׋ ?ņ?UIa>?V[>?T%=VR8?V[?w?x>ug +?>F̒?hg&=">?%?/q?,>43;??ff? >*t2?׋ ?Ŏ?UIa>(?V[>?T%=VRH?V[?փ?x>ug?>F̚?hg&="N?%??,>43K??ff? >*tB?׋ ?Ŗ?UIa>8?V[>?T%=VRX?V[?֋?x>ug*?>F̢?hg&="^?%??l>23?23S>I>Y/6׋?Y/v>>Sm]?>">SmV['?>D>1?1>3=x鎽5?t>l>df?>I>^׋?>>Sm?>">LV['?^>D>,bV?1>3=5?tG>l>?>I>dX׋?>>ں?>">Z%=V['?U[>D>,b?1>3=-b=5?^>l>833=?>I>p +<׋?>>j뼫?>">=V['?U[>D>XĬ??3==5?^>l>=?>I>N=׋?>>J +=?U[?">VI!>V['?U[>D>`??3=D8>5?^>l>,>??I> >׋?֋ ?>Z%=?U[?">VIa>V['?U[>D>Pw&=?%?3=Dx>5?^>l>l>??I>I>׋?֋?>">?U['?">>V['??D>;=?5?3=E>5?/?l>gf>?$?I>T>׋?֋-?>b>?U[7?">>V['??D>ԝ)>?E?3=E>5?/?l>gf>?4?I>T>׋?֋=?>VI>?U[G?">>V['?'?D>ԝi>?U?3=E>5?/!?l>gf>?D?I>T>׋?֋M?>VI>?U[W?">>V['?7?D>Δ>?e?3=E>5?/1?l>gf>?T?I>T>׋?֋]?>VI>?U[g?">VR?V['?G?D>δ>?u?3="?5?/A?l>43 ??d?I>*t?׋?֋m?>VI>?U[w?">VR?V['?W?D>>?F̂?3="?5?/Q?l>43??t?I>*t?׋?֋}?>???">VR(?V['?g?D>>?F̊?3=".?5?/a?l>43+??ff?I>*t"?׋?ņ?>???">VR8?V['?w?D>ug +??F̒?3=">?5?/q?l>43;??ff?I>*t2?׋?Ŏ?>(???">VRH?V['?փ?D>ug??F̚?3="N?5??l>43K??ff?I>*tB?׋?Ŗ?>8???">VRX?V['?֋?D>ug*??F̢?3="^?5??ff>23$?23S>R>Y/6׋-?Y/v>>Sm]?>b>SmV[7?>D>1?1>ڙ)>x鎽E?t>ff>df$?>R>^׋-?>>Sm?>b>LV[7?^>D>,bV?1>ڙ)>E?tG>ff>$?>R>dX׋-?>>ں?>b>Z%=V[7?U[>D>,b?1>ڙ)>-b=E?^>ff>833=$?>R>p +<׋-?>>j뼫?>b>=V[7?U[>D>XĬ??ڙ)>=E?^>ff>=$?>R>N=׋-?>>J +=?U[?b>VI!>V[7?U[>D>`??ڙ)>D8>E?^>ff>,>$??R> >׋-?֋ ?>Z%=?U[?b>VIa>V[7?U[>D>Pw&=?%?ڙ)>Dx>E?^>ff>l>$??R>I>׋-?֋?>">?U['?b>>V[7??D>;=?5?ڙ)>E>E?/?ff>gf>$?$?R>T>׋-?֋-?>b>?U[7?b>>V[7??D>ԝ)>?E?ڙ)>E>E?/?ff>gf>$?4?R>T>׋-?֋=?>VI>?U[G?b>>V[7?'?D>ԝi>?U?ڙ)>E>E?/!?ff>gf>$?D?R>T>׋-?֋M?>VI>?U[W?b>>V[7?7?D>Δ>?e?ڙ)>E>E?/1?ff>gf>$?T?R>T>׋-?֋]?>VI>?U[g?b>VR?V[7?G?D>δ>?u?ڙ)>"?E?/A?ff>43 ?$?d?R>*t?׋-?֋m?>VI>?U[w?b>VR?V[7?W?D>>?F̂?ڙ)>"?E?/Q?ff>43?$?t?R>*t?׋-?֋}?>???b>VR(?V[7?g?D>>?F̊?ڙ)>".?E?/a?ff>43+?$?ff?R>*t"?׋-?ņ?>???b>VR8?V[7?w?D>ug +??F̒?ڙ)>">?E?/q?ff>43;?$?ff?R>*t2?׋-?Ŏ?>(???b>VRH?V[7?փ?D>ug??F̚?ڙ)>"N?E??ff>43K?$?ff?R>*tB?׋-?Ŗ?>8???b>VRX?V[7?֋?D>ug*??F̢?ڙ)>"^?E??ff>234?23S>R>Y/6׋=?Y/v>>Sm]'?>UI>SmV[G?>D>1!?1>ڙi>x鎽U?t>ff>df4?>R>^׋=?>>Sm'?>UI>LV[G?^>D>,bV!?1>ڙi>U?tG>ff>4?>R>dX׋=?>>ں'?>UI>Z%=V[G?U[>D>,b!?1>ڙi>-b=U?^>ff>833=4?>R>p +<׋=?>>j뼫'?>UI>=V[G?U[>D>XĬ!??ڙi>=U?^>ff>=4?>R>N=׋=?>>J +='?U[?UI>VI!>V[G?U[>D>`!??ڙi>D8>U?^>ff>,>4??R> >׋=?֋ ?>Z%='?U[?UI>VIa>V[G?U[>D>Pw&=!?%?ڙi>Dx>U?^>ff>l>4??R>I>׋=?֋?>">'?U['?UI>>V[G??D>;=!?5?ڙi>E>U?/?ff>gf>4?$?R>T>׋=?֋-?>b>'?U[7?UI>>V[G??D>ԝ)>!?E?ڙi>E>U?/?ff>gf>4?4?R>T>׋=?֋=?>VI>'?U[G?UI>>V[G?'?D>ԝi>!?U?ڙi>E>U?/!?ff>gf>4?D?R>T>׋=?֋M?>VI>'?U[W?UI>>V[G?7?D>Δ>!?e?ڙi>E>U?/1?ff>gf>4?T?R>T>׋=?֋]?>VI>'?U[g?UI>VR?V[G?G?D>δ>!?u?ڙi>"?U?/A?ff>43 ?4?d?R>*t?׋=?֋m?>VI>'?U[w?UI>VR?V[G?W?D>>!?F̂?ڙi>"?U?/Q?ff>43?4?t?R>*t?׋=?֋}?>?'??UI>VR(?V[G?g?D>>!?F̊?ڙi>".?U?/a?ff>43+?4?ff?R>*t"?׋=?ņ?>?'??UI>VR8?V[G?w?D>ug +?!?F̒?ڙi>">?U?/q?ff>43;?4?ff?R>*t2?׋=?Ŏ?>(?'??UI>VRH?V[G?փ?D>ug?!?F̚?ڙi>"N?U??ff>43K?4?ff?R>*tB?׋=?Ŗ?>8?'??UI>VRX?V[G?֋?D>ug*?!?F̢?ڙi>"^?U??ff>23D?23S>R>Y/6׋M?Y/v>>Sm]7?>UI>SmV[W?>D>11?1>̔>x鎽e?t>ff>dfD?>R>^׋M?>>Sm7?>UI>LV[W?^>D>,bV1?1>̔>e?tG>ff>D?>R>dX׋M?>>ں7?>UI>Z%=V[W?U[>D>,b1?1>̔>-b=e?^>ff>833=D?>R>p +<׋M?>>j뼫7?>UI>=V[W?U[>D>XĬ1??̔>=e?^>ff>=D?>R>N=׋M?>>J +=7?U[?UI>VI!>V[W?U[>D>`1??̔>D8>e?^>ff>,>D??R> >׋M?֋ ?>Z%=7?U[?UI>VIa>V[W?U[>D>Pw&=1?%?̔>Dx>e?^>ff>l>D??R>I>׋M?֋?>">7?U['?UI>>V[W??D>;=1?5?̔>E>e?/?ff>gf>D?$?R>T>׋M?֋-?>b>7?U[7?UI>>V[W??D>ԝ)>1?E?̔>E>e?/?ff>gf>D?4?R>T>׋M?֋=?>VI>7?U[G?UI>>V[W?'?D>ԝi>1?U?̔>E>e?/!?ff>gf>D?D?R>T>׋M?֋M?>VI>7?U[W?UI>>V[W?7?D>Δ>1?e?̔>E>e?/1?ff>gf>D?T?R>T>׋M?֋]?>VI>7?U[g?UI>VR?V[W?G?D>δ>1?u?̔>"?e?/A?ff>43 ?D?d?R>*t?׋M?֋m?>VI>7?U[w?UI>VR?V[W?W?D>>1?F̂?̔>"?e?/Q?ff>43?D?t?R>*t?׋M?֋}?>?7??UI>VR(?V[W?g?D>>1?F̊?̔>".?e?/a?ff>43+?D?ff?R>*t"?׋M?ņ?>?7??UI>VR8?V[W?w?D>ug +?1?F̒?̔>">?e?/q?ff>43;?D?ff?R>*t2?׋M?Ŏ?>(?7??UI>VRH?V[W?փ?D>ug?1?F̚?̔>"N?e??ff>43K?D?ff?R>*tB?׋M?Ŗ?>8?7??UI>VRX?V[W?֋?D>ug*?1?F̢?̔>"^?e??ff>23T?23S>R>Y/6׋]?Y/v>UR?Sm]G?>UI>SmV[g?>|"?1A?1>̴>x鎽u?t>ff>dfT?>R>^׋]?>UR?SmG?>UI>LV[g?^>|"?,bVA?1>̴>u?tG>ff>T?>R>dX׋]?>UR?ںG?>UI>Z%=V[g?U[>|"?,bA?1>̴>-b=u?^>ff>833=T?>R>p +<׋]?>UR?j뼫G?>UI>=V[g?U[>|"?XĬA??̴>=u?^>ff>=T?>R>N=׋]?>UR?J +=G?U[?UI>VI!>V[g?U[>|"?`A??̴>D8>u?^>ff>,>T??R> >׋]?֋ ?UR?Z%=G?U[?UI>VIa>V[g?U[>|"?Pw&=A?%?̴>Dx>u?^>ff>l>T??R>I>׋]?֋?UR?">G?U['?UI>>V[g??|"?;=A?5?̴>E>u?/?ff>gf>T?$?R>T>׋]?֋-?UR?b>G?U[7?UI>>V[g??|"?ԝ)>A?E?̴>E>u?/?ff>gf>T?4?R>T>׋]?֋=?UR?VI>G?U[G?UI>>V[g?'?|"?ԝi>A?U?̴>E>u?/!?ff>gf>T?D?R>T>׋]?֋M?UR?VI>G?U[W?UI>>V[g?7?|"?Δ>A?e?̴>E>u?/1?ff>gf>T?T?R>T>׋]?֋]?UR?VI>G?U[g?UI>VR?V[g?G?|"?δ>A?u?̴>"?u?/A?ff>43 ?T?d?R>*t?׋]?֋m?UR?VI>G?U[w?UI>VR?V[g?W?|"?>A?F̂?̴>"?u?/Q?ff>43?T?t?R>*t?׋]?֋}?UR??G??UI>VR(?V[g?g?|"?>A?F̊?̴>".?u?/a?ff>43+?T?ff?R>*t"?׋]?ņ?UR??G??UI>VR8?V[g?w?|"?ug +?A?F̒?̴>">?u?/q?ff>43;?T?ff?R>*t2?׋]?Ŏ?UR?(?G??UI>VRH?V[g?փ?|"?ug?A?F̚?̴>"N?u??ff>43K?T?ff?R>*tB?׋]?Ŗ?UR?8?G??UI>VRX?V[g?֋?|"?ug*?A?F̢?̴>"^?u??33 ?23d?23S>)t?Y/6׋m?Y/v>UR?Sm]W?>UI>SmV[w?>|"?1Q?1>>x鎽̂?t>33 ?dfd?>)t?^׋m?>UR?SmW?>UI>LV[w?^>|"?,bVQ?1>>̂?tG>33 ?d?>)t?dX׋m?>UR?ںW?>UI>Z%=V[w?U[>|"?,bQ?1>>-b=̂?^>33 ?833=d?>)t?p +<׋m?>UR?j뼫W?>UI>=V[w?U[>|"?XĬQ??>=̂?^>33 ?=d?>)t?N=׋m?>UR?J +=W?U[?UI>VI!>V[w?U[>|"?`Q??>D8>̂?^>33 ?,>d??)t? >׋m?֋ ?UR?Z%=W?U[?UI>VIa>V[w?U[>|"?Pw&=Q?%?>Dx>̂?^>33 ?l>d??)t?I>׋m?֋?UR?">W?U['?UI>>V[w??|"?;=Q?5?>E>̂?/?33 ?gf>d?$?)t?T>׋m?֋-?UR?b>W?U[7?UI>>V[w??|"?ԝ)>Q?E?>E>̂?/?33 ?gf>d?4?)t?T>׋m?֋=?UR?VI>W?U[G?UI>>V[w?'?|"?ԝi>Q?U?>E>̂?/!?33 ?gf>d?D?)t?T>׋m?֋M?UR?VI>W?U[W?UI>>V[w?7?|"?Δ>Q?e?>E>̂?/1?33 ?gf>d?T?)t?T>׋m?֋]?UR?VI>W?U[g?UI>VR?V[w?G?|"?δ>Q?u?>"?̂?/A?33 ?43 ?d?d?)t?*t?׋m?֋m?UR?VI>W?U[w?UI>VR?V[w?W?|"?>Q?F̂?>"?̂?/Q?33 ?43?d?t?)t?*t?׋m?֋}?UR??W??UI>VR(?V[w?g?|"?>Q?F̊?>".?̂?/a?33 ?43+?d?ff?)t?*t"?׋m?ņ?UR??W??UI>VR8?V[w?w?|"?ug +?Q?F̒?>">?̂?/q?33 ?43;?d?ff?)t?*t2?׋m?Ŏ?UR?(?W??UI>VRH?V[w?փ?|"?ug?Q?F̚?>"N?̂??33 ?43K?d?ff?)t?*tB?׋m?Ŗ?UR?8?W??UI>VRX?V[w?֋?|"?ug*?Q?F̢?>"^?̂??33?23t?23S>)t?Y/6׋}?Y/v>UR(?Sm]g?>?Sm?>|".?1a?1>>x鎽̊?t>33?dft?>)t?^׋}?>UR(?Smg?>?L?^>|".?,bVa?1>>̊?tG>33?t?>)t?dX׋}?>UR(?ںg?>?Z%=?U[>|".?,ba?1>>-b=̊?^>33?833=t?>)t?p +<׋}?>UR(?j뼫g?>?=?U[>|".?XĬa??>=̊?^>33?=t?>)t?N=׋}?>UR(?J +=g?U[??VI!>?U[>|".?`a??>D8>̊?^>33?,>t??)t? >׋}?֋ ?UR(?Z%=g?U[??VIa>?U[>|".?Pw&=a?%?>Dx>̊?^>33?l>t??)t?I>׋}?֋?UR(?">g?U['??>??|".?;=a?5?>E>̊?/?33?gf>t?$?)t?T>׋}?֋-?UR(?b>g?U[7??>??|".?ԝ)>a?E?>E>̊?/?33?gf>t?4?)t?T>׋}?֋=?UR(?VI>g?U[G??>?'?|".?ԝi>a?U?>E>̊?/!?33?gf>t?D?)t?T>׋}?֋M?UR(?VI>g?U[W??>?7?|".?Δ>a?e?>E>̊?/1?33?gf>t?T?)t?T>׋}?֋]?UR(?VI>g?U[g??VR??G?|".?δ>a?u?>"?̊?/A?33?43 ?t?d?)t?*t?׋}?֋m?UR(?VI>g?U[w??VR??W?|".?>a?F̂?>"?̊?/Q?33?43?t?t?)t?*t?׋}?֋}?UR(??g???VR(??g?|".?>a?F̊?>".?̊?/a?33?43+?t?ff?)t?*t"?׋}?ņ?UR(??g???VR8??w?|".?ug +?a?F̒?>">?̊?/q?33?43;?t?ff?)t?*t2?׋}?Ŏ?UR(?(?g???VRH??փ?|".?ug?a?F̚?>"N?̊??33?43K?t?ff?)t?*tB?׋}?Ŗ?UR(?8?g???VRX??֋?|".?ug*?a?F̢?>"^?̊??33+?23ff?23S>)t"?Y/6ņ?Y/v>UR8?Sm]w?>?Sm?>|">?1q?1>vf +?x鎽̒?t>33+?dfff?>)t"?^ņ?>UR8?Smw?>?L?^>|">?,bVq?1>vf +?̒?tG>33+?ff?>)t"?dXņ?>UR8?ںw?>?Z%=?U[>|">?,bq?1>vf +?-b=̒?^>33+?833=ff?>)t"?p +<ņ?>UR8?j뼫w?>?=?U[>|">?XĬq??vf +?=̒?^>33+?=ff?>)t"?N=ņ?>UR8?J +=w?U[??VI!>?U[>|">?`q??vf +?D8>̒?^>33+?,>ff??)t"? >ņ?֋ ?UR8?Z%=w?U[??VIa>?U[>|">?Pw&=q?%?vf +?Dx>̒?^>33+?l>ff??)t"?I>ņ?֋?UR8?">w?U['??>??|">?;=q?5?vf +?E>̒?/?33+?gf>ff?$?)t"?T>ņ?֋-?UR8?b>w?U[7??>??|">?ԝ)>q?E?vf +?E>̒?/?33+?gf>ff?4?)t"?T>ņ?֋=?UR8?VI>w?U[G??>?'?|">?ԝi>q?U?vf +?E>̒?/!?33+?gf>ff?D?)t"?T>ņ?֋M?UR8?VI>w?U[W??>?7?|">?Δ>q?e?vf +?E>̒?/1?33+?gf>ff?T?)t"?T>ņ?֋]?UR8?VI>w?U[g??VR??G?|">?δ>q?u?vf +?"?̒?/A?33+?43 ?ff?d?)t"?*t?ņ?֋m?UR8?VI>w?U[w??VR??W?|">?>q?F̂?vf +?"?̒?/Q?33+?43?ff?t?)t"?*t?ņ?֋}?UR8??w???VR(??g?|">?>q?F̊?vf +?".?̒?/a?33+?43+?ff?ff?)t"?*t"?ņ?ņ?UR8??w???VR8??w?|">?ug +?q?F̒?vf +?">?̒?/q?33+?43;?ff?ff?)t"?*t2?ņ?Ŏ?UR8?(?w???VRH??փ?|">?ug?q?F̚?vf +?"N?̒??33+?43K?ff?ff?)t"?*tB?ņ?Ŗ?UR8?8?w???VRX??֋?|">?ug*?q?F̢?vf +?"^?̒??33;?23ff?23S>)t2?Y/6Ŏ?Y/v>URH?Sm]փ?>(?Sm?>|"N?1?1>vf?x鎽̚?t>33;?dfff?>)t2?^Ŏ?>URH?Smփ?>(?L?^>|"N?,bV?1>vf?̚?tG>33;?ff?>)t2?dXŎ?>URH?ںփ?>(?Z%=?U[>|"N?,b?1>vf?-b=̚?^>33;?833=ff?>)t2?p +<Ŏ?>URH?jփ?>(?=?U[>|"N?XĬ??vf?=̚?^>33;?=ff?>)t2?N=Ŏ?>URH?J +=փ?U[?(?VI!>?U[>|"N?`??vf?D8>̚?^>33;?,>ff??)t2? >Ŏ?֋ ?URH?Z%=փ?U[?(?VIa>?U[>|"N?Pw&=?%?vf?Dx>̚?^>33;?l>ff??)t2?I>Ŏ?֋?URH?">փ?U['?(?>??|"N?;=?5?vf?E>̚?/?33;?gf>ff?$?)t2?T>Ŏ?֋-?URH?b>փ?U[7?(?>??|"N?ԝ)>?E?vf?E>̚?/?33;?gf>ff?4?)t2?T>Ŏ?֋=?URH?VI>փ?U[G?(?>?'?|"N?ԝi>?U?vf?E>̚?/!?33;?gf>ff?D?)t2?T>Ŏ?֋M?URH?VI>փ?U[W?(?>?7?|"N?Δ>?e?vf?E>̚?/1?33;?gf>ff?T?)t2?T>Ŏ?֋]?URH?VI>փ?U[g?(?VR??G?|"N?δ>?u?vf?"?̚?/A?33;?43 ?ff?d?)t2?*t?Ŏ?֋m?URH?VI>փ?U[w?(?VR??W?|"N?>?F̂?vf?"?̚?/Q?33;?43?ff?t?)t2?*t?Ŏ?֋}?URH??փ??(?VR(??g?|"N?>?F̊?vf?".?̚?/a?33;?43+?ff?ff?)t2?*t"?Ŏ?ņ?URH??փ??(?VR8??w?|"N?ug +??F̒?vf?">?̚?/q?33;?43;?ff?ff?)t2?*t2?Ŏ?Ŏ?URH?(?փ??(?VRH??փ?|"N?ug??F̚?vf?"N?̚??33;?43K?ff?ff?)t2?*tB?Ŏ?Ŗ?URH?8?փ??(?VRX??֋?|"N?ug*??F̢?vf?"^?̚??33K?23ff?23S>)tB?Y/6Ŗ?Y/v>URX?Sm]֋?>8?Sm?>|"^?1?1>vf*?x鎽̢?t>33K?dfff?>)tB?^Ŗ?>URX?Sm֋?>8?L?^>|"^?,bV?1>vf*?̢?tG>33K?ff?>)tB?dXŖ?>URX?ں֋?>8?Z%=?U[>|"^?,b?1>vf*?-b=̢?^>33K?833=ff?>)tB?p +<Ŗ?>URX?j֋?>8?=?U[>|"^?XĬ??vf*?=̢?^>33K?=ff?>)tB?N=Ŗ?>URX?J +=֋?U[?8?VI!>?U[>|"^?`??vf*?D8>̢?^>33K?,>ff??)tB? >Ŗ?֋ ?URX?Z%=֋?U[?8?VIa>?U[>|"^?Pw&=?%?vf*?Dx>̢?^>33K?l>ff??)tB?I>Ŗ?֋?URX?">֋?U['?8?>??|"^?;=?5?vf*?E>̢?/?33K?gf>ff?$?)tB?T>Ŗ?֋-?URX?b>֋?U[7?8?>??|"^?ԝ)>?E?vf*?E>̢?/?33K?gf>ff?4?)tB?T>Ŗ?֋=?URX?VI>֋?U[G?8?>?'?|"^?ԝi>?U?vf*?E>̢?/!?33K?gf>ff?D?)tB?T>Ŗ?֋M?URX?VI>֋?U[W?8?>?7?|"^?Δ>?e?vf*?E>̢?/1?33K?gf>ff?T?)tB?T>Ŗ?֋]?URX?VI>֋?U[g?8?VR??G?|"^?δ>?u?vf*?"?̢?/A?33K?43 ?ff?d?)tB?*t?Ŗ?֋m?URX?VI>֋?U[w?8?VR??W?|"^?>?F̂?vf*?"?̢?/Q?33K?43?ff?t?)tB?*t?Ŗ?֋}?URX??֋??8?VR(??g?|"^?>?F̊?vf*?".?̢?/a?33K?43+?ff?ff?)tB?*t"?Ŗ?ņ?URX??֋??8?VR8??w?|"^?ug +??F̒?vf*?">?̢?/q?33K?43;?ff?ff?)tB?*t2?Ŗ?Ŏ?URX?(?֋??8?VRH??փ?|"^?ug??F̚?vf*?"N?̢??33K?43K?ff?ff?)tB?*tB?Ŗ?Ŗ?URX?8?֋??8?VRX??֋?|"^?ug*??F̢?vf*?"^?̢??@?>>ccF>D> u>> >u>t׳:S>׳>>VS>@>>cǽF>D> *u>y +?/<>y>tg{:S>?0=>>@=>?c? 꽐'(u>y*? +>>y>t\:S>>?4,>>>@@>>0?cx>F>8? 8=u>yJ?}>>^?U>>?@>>P?c>F>X? U>u>yj?}>>:S>~?U>>4?@>>p?c>F>x? >u>:S>l?* ?>T?@?>?c^?F>Q|? >u>:S>l?* +?>t?@0?>?c^'?F>Q|? 꽇}?u>?t&?:S>l?* K?>ky??>>ǽcF>D>/<z>> * z +?u>0=׳>׳>\m{W?VS>>>ǽǽF>D>/< *z>y +? */0=g{>?\m{0=W?>=>?ǽ?/<'(z>y*? * +>z +?y>0=\>>?\m{4,>W?>@>>0?ǽx>F>8?/<8=z>yJ? *}>z +?^?\m{U>W??>>P?ǽ>F>X?/<U>z>yj? *}>z +?>~?\m{U>W?4?>>p?ǽ>F>x?/<>z>>l?\m{* ?W?T??>?ǽ^?F>Q|?/<>z>>l?\m{* +?W?t?0?>?ǽ^'?F>Q|?/<}?z>l?\m{* K?W?ky?=??> +>z>>'( z*?u>2,>׳>׳>W>?VS>=?><ǽ?D> +> *z>y +?'(/2,>g{>?0=W>?>==??<<?? +>'(z>y*?'( +>z*?y>2,>\>>?4,>W>?>=@>?0??8? +>8=z>yJ?'(}>z*?@ +;>^?U>W>??=>?P?<>?X? +>U>z>yj?'(}>z*?R>>~?U>W>?4?=>?p?<>?x? +>>z>)L>>l?* ?W>?T?=???<^??Q|? +>>z>)L>>l?* +?W>?t?=0???<^'??Q|? +>}?z>&?>l?* K?W>?ky??>?0?>t>c8?D>}>=A?>0= zJ?u>c>׳N?׳>T;W^?VS>?>0?>t>ǽ8?D>}> *=A?y +?0=/c>g{N??T;0=W^?>?>=0??t><8??}>'(=A?y*?0= +>zJ?y>c>\N?>?T;4,>W^?>?>@>0?0?t>x>8?8?}>8==A?yJ?0=}>zJ?@ +;N?^?T;U>W^???>>0?P?t>>8?X?}>U>=A?yj?0=}>zJ?R>N?~?T;U>W^?4??>>0?p?t>>8?x?}>>=A?)L>N?l?T;* ?W^?T??>?0??t>^?8?Q|?}>>=A?)L>N?l?T;* +?W^?t??>0?0??t>^'?8?Q|?}>}?=A?&?N?l?T;* K?W^?ky?>?P?>>cX?D>}>=A=?>U> zj?u>c>׳N4?׳>>W~?VS>>P?>>ǽX?D>}> *=A=?y +?U>/c>g{N4??>0=W~?>>=P??>'(=A=?y*?U> +>zj?y>c>\N4?>?>4,>W~?>>@>P?0?>x>X?8?}>8==A=?yJ?U>}>zj?@ +;N4?^?>U>W~??>>P?P?>>X?X?}>U>=A=?yj?U>}>zj?R>N4?~?>U>W~?4?>>P?p?>>X?x?}>>=A=?ľ?zj?)L>N4?l?>* ?W~?T?>?P??>^?X?Q|?}>>=A=?ľ"?zj?)L>N4?l?>* +?W~?t?>0?P??>^'?X?Q|?}>}?=A=?ľB?zj??c>&?N4?l?>* K?W~?ky?>?p?>>cx?D>þ?=A]?> > =A?u> ?׳NT?׳>RI>m?VS>>p?>>ǽx?D>þ? *=A]?y +? >/<=A?y> ?g{NT??RI>0=m?>>=p??> +>=A?y> ?\NT?>?RI>4,>m?>>@>p?0?>x>x?8?þ?8==A]?yJ? >}>=A?U>m??>>p?P?>>x?X?þ?U>=A]?yj? >}>=A?NT?~?RI>U>m?4?>>p?p?>>x?x?þ?>=A]?ľ?=A?NT?l?RI>* ?m?T?>?p??>^?x?Q|?þ?>=A]?ľ"?=A?NT?l?RI>* +?m?t?>0?p??>^'?x?Q|?þ?}?=A]?ľB?=A?? ?&?NT?l?RI>* K?m?ky????>]?cR|?D>þ"?=A}?> > =A?u> +?׳Nt?׳>RI>m?VS>??>]?ǽR|?D>þ"? *=A}?y +? >/<=A?y> +?g{Nt??RI>0=m?>?=??]? +>=A?y> +?\Nt?>?RI>4,>m?>?@>?0?]?x>R|?8?þ"?8==A}?yJ? >}>=A?U>m???>?P?]?>R|?X?þ"?U>=A}?yj? >}>=A?Nt?~?RI>U>m?4??>?p?]?>R|?x?þ"?>=A}?ľ?=A?Nt?l?RI>* ?m?T?????]?^?R|?Q|?þ"?>=A}?ľ"?=A?Nt?l?RI>* +?m?t??0???]?^'?R|?Q|?þ"?}?=A}?ľB?=A?? +?&?Nt?l?RI>* K?m?ky?0???>]'?cR|?D>þB??>}? =A?u> K?׳y?׳>$?m?VS>0??>]'?ǽR|?D>þB? *?y +?}?/<=A?y> K?g{y??$?0=m?>0?=??]'?=A?y> K?\y?>?$?4,>m?>0?@>?0?]'?x>R|?8?þB?8=?yJ?}?}>=A?m??0?>?P?]'?>R|?X?þB?U>?yj?}?}>=A?y?~?$?U>m?4?0?>?p?]'?>R|?x?þB?>?y?l?$?* ?m?T?0????]'?^?R|?Q|?þB?>?y?l?$?* +?m?t?0?0???]'?^'?R|?Q|?þB?}??ef>^5qZ5q>>zֽ:S>?=Stֽ?>H62>K0?H:C$0?>LL=gf>233?^5q`l<>VMU?=SƬ>??H,m@2>Kp?H:?>$0?|?L>gf>23s?^5qSe>>VM|?zֽY)>>Ԋ?=ScV>?Z?HPK~=2> ?H:>$0?|P?L ?gf>?^5q?>&?zֽƬ>>Ԫ?=S2+%??gj?Hjɟ>2> ?H:྄/?$0?>?L=L433?ef> lì>:S??LtֽU?>?>6 ?K0?t@C$p?>L=L=433?233? l<`lL?U?LƬ>U???>,m@ ?Kp?t@?>$p?|?L=>433?23s? lXMY)>?Ԋ?LcV>U?Z??>PK~= ? ?t@>$p?|P?L= ?433?? l<?XMƬ>?Ԫ?L2+%?U?gj??>jɟ> ? ?t@/?$p?>?>L43s?ef>Qe>Z5qXM|?>bV>:SZ??Y)>tֽԊ?>>6 P?K0?-~=C?>>L=43s?233?Qe>`lLZ?U?Y)>Ƭ>Ԋ??>,m@ P?Kp?-~=?>?|?>>43s?23s?Qe>Se>XM|?VM|?bV>Y)>Z?Ԋ?Y)>cV>Ԋ?Z?>PK~= P? ?-~=>?|P?> ?43s??Qe>?XM|?&?bV>Ƭ>Z?Ԫ?Y)>2+%?Ԋ?gj?>jɟ> P? ?-~=/??>? ?L?ef>?Z5q&?>1+%?:Shj??ì>tֽԪ?>/?6ྍ?K0?ş>C?> ?L=?233??`l<&?VMƬ>Ԫ??/?,m@?Kp?ş>?>?|? ?>?23s??Se>&?VM|?1+%?Y)>hj?Ԋ?ì>cV>Ԫ?Z?/?PK~=? ?ş>>?|P? ? ?????&?&?1+%?Ƭ>hj?Ԫ?ì>2+%?Ԫ?gj?/?jɟ>? ?ş>/??>?gf&?ff&?Y>Y>|/?z/? bh?P?P?ah?x#\q?⾰;<^q?E<>43>gf&?33?Y> Ӡ>|/?=˗? <>bh?ah?>/>P?04?x#<@5j==>V??^q?"{?23>43?ff&? Ӡ>Y>>˗?z/?14?P?<>bh?ah??X{?\q?j=;23>43>43?33? Ӡ> Ӡ>>˗?=˗?<>14?ah?<>>/>bh?04??@5j={?V?j=?x?"{?</U??/4(>?U?D-g><4F?O?|A0g>_P?3F? \ No newline at end of file diff --git a/src/server/public/models/ssd_mobilenetv1_model-weights_manifest.json b/src/server/public/models/ssd_mobilenetv1_model-weights_manifest.json new file mode 100644 index 000000000..204e0d13c --- /dev/null +++ b/src/server/public/models/ssd_mobilenetv1_model-weights_manifest.json @@ -0,0 +1 @@ +[{"paths":["ssd_mobilenetv1_model-shard1","ssd_mobilenetv1_model-shard2"],"weights":[{"dtype":"float32","shape":[1,1,512,9],"quantization":{"scale":0.0026856216729856004,"min":-0.34107395246917127,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/ClassPredictor/weights"},{"dtype":"float32","shape":[9],"quantization":{"scale":0.00198518248165355,"min":-0.32159956202787515,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,1024,18],"quantization":{"scale":0.003060340296988394,"min":-0.489654447518143,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.0008040678851744708,"min":-0.12221831854651957,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,512,18],"quantization":{"scale":0.0012513800578958848,"min":-0.16017664741067325,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.000338070518245884,"min":-0.05510549447407909,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,256,18],"quantization":{"scale":0.0011819932975021064,"min":-0.1453851755927591,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.00015985782386041154,"min":-0.026536398760828316,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,256,18],"quantization":{"scale":0.0007035591438704846,"min":-0.08513065640832863,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.00008793946574716008,"min":-0.013190919862074012,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,128,18],"quantization":{"scale":0.00081320781918133,"min":-0.11059626340866088,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.0000980533805547976,"min":-0.014609953702664841,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/ClassPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":3,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/stack_1/2"},{"dtype":"int32","shape":[3],"quantization":{"scale":0.00392156862745098,"min":0,"dtype":"uint8"},"name":"Postprocessor/Slice/begin"},{"dtype":"int32","shape":[3],"quantization":{"scale":1,"min":-1,"dtype":"uint8"},"name":"Postprocessor/Slice/size"},{"dtype":"float32","shape":[1,1,512,12],"quantization":{"scale":0.003730384859384275,"min":-0.4327246436885759,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[12],"quantization":{"scale":0.0018744708568442102,"min":-0.3917644090804399,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":3072,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/stack_1/1"},{"dtype":"float32","shape":[1,1,1024,24],"quantization":{"scale":0.00157488017689948,"min":-0.20000978246623397,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.0002823906713256649,"min":-0.043488163384152394,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":1536,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/stack_1/1"},{"dtype":"float32","shape":[1,1,512,24],"quantization":{"scale":0.0007974451663447361,"min":-0.11004743295557358,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.0001350417988849621,"min":-0.02039131163162928,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":384,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/stack_1/1"},{"dtype":"float32","shape":[1,1,256,24],"quantization":{"scale":0.0007113990246080885,"min":-0.0860792819775787,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.000050115815418608046,"min":-0.007617603943628423,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":96,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/stack_1/1"},{"dtype":"float32","shape":[1,1,256,24],"quantization":{"scale":0.000590049314732645,"min":-0.06903576982371946,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.00003513663861097074,"min":-0.006359731588585704,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":24,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/stack_1/1"},{"dtype":"float32","shape":[1,1,128,24],"quantization":{"scale":0.0005990567744946948,"min":-0.07907549423329971,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.00003392884288640583,"min":-0.006039334033780238,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/BoxEncodingPredictor/biases"},{"dtype":"float32","shape":[],"quantization":{"scale":1,"min":0.007843137718737125,"dtype":"uint8"},"name":"Preprocessor/mul/x"},{"dtype":"int32","shape":[2],"quantization":{"scale":1,"min":512,"dtype":"uint8"},"name":"Preprocessor/ResizeImage/size"},{"dtype":"float32","shape":[],"quantization":{"scale":1,"min":1,"dtype":"uint8"},"name":"Preprocessor/sub/y"},{"dtype":"float32","shape":[3,3,3,32],"quantization":{"scale":0.03948551065781537,"min":-5.014659853542552,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_0_pointwise/weights"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.0498106133704092,"min":-7.371970778820562,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_0_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,32,1],"quantization":{"scale":0.036833542468501075,"min":-4.714693435968138,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/depthwise_weights"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.012173276705046495,"min":-0.012173276705046495,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.032182769214405736,"min":-2.4780732295092416,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.028287527607936486,"min":-3.366215785344442,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.04716738532571232,"min":3.9071404665769224e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,32,64],"quantization":{"scale":0.04010109433940812,"min":-4.290817094316669,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_pointwise/weights"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.2212210038129021,"min":-34.51047659481273,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,64,1],"quantization":{"scale":0.010024750933927648,"min":-1.343316625146305,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/depthwise_weights"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.006120916675118839,"min":0.5227176547050476,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.02317035385206634,"min":-0.7646216771181892,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.04980821422502106,"min":-5.8275610643274645,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.051751047022202436,"min":3.916113799002297e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,64,128],"quantization":{"scale":0.021979344124887504,"min":-2.1319963801140878,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.09958663267247816,"min":-11.054116226645077,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,128,1],"quantization":{"scale":0.01943492702409333,"min":-2.6237151482525993,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/depthwise_weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.017852897737540452,"min":0.40204083919525146,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.029888209174661076,"min":-1.972621805527631,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.029319268581913967,"min":-5.130872001834945,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.014018708584355373,"min":3.9083178263362604e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,128,128],"quantization":{"scale":0.020776657964669022,"min":-2.5347522716896207,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.14383157094319662,"min":-9.636715253194174,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,128,1],"quantization":{"scale":0.004463558571011412,"min":-0.5981168485155293,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/depthwise_weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.006487431245691636,"min":0.47910428047180176,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.026542164297664865,"min":-1.2209395576925839,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.05119945675719018,"min":-8.60150873520795,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.03081628388049556,"min":3.911508751095344e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,128,256],"quantization":{"scale":0.010758659886378868,"min":-1.0328313490923713,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.08058219610476026,"min":-9.34753474815219,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,256,1],"quantization":{"scale":0.01145936741548426,"min":-1.3292866201961742,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/depthwise_weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.0083988838336047,"min":0.36280909180641174,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.02858148649627087,"min":-3.6584302715226715,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.03988401375564874,"min":-7.099354448505476,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.009090481683904049,"min":0.020878996700048447,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,256,256],"quantization":{"scale":0.008951201625898773,"min":-1.1189002032373465,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.051758006974762565,"min":-5.745138774198645,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,256,1],"quantization":{"scale":0.004110433190476661,"min":-0.6042336790000691,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/depthwise_weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.013170199768216002,"min":0.3386639356613159,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.03599378548416437,"min":-3.70735990486893,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.026967673208199296,"min":-3.748506575939702,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.012615410486857097,"min":3.9111388979838637e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,256,512],"quantization":{"scale":0.00822840648538926,"min":-1.1848905338960536,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.06608965817619772,"min":-7.468131373910342,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.008801074355256323,"min":-0.9593171047229393,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.030577416513480393,"min":0.3285980224609375,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04778536441279393,"min":-8.935863145192464,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04331884945140165,"min":-9.660103427662568,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04126455444367785,"min":0.000604183878749609,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.009305818408143287,"min":-1.1446156642016243,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04640720217835669,"min":-4.733534622192383,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.008138792655047248,"min":-0.9766551186056698,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.027351748358969596,"min":0.34030041098594666,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04415061053107767,"min":-7.019947074441349,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.02476683784933651,"min":-2.9224868662217083,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.02547598832684076,"min":0.00026032101595774293,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.01083052625843123,"min":-1.2563410459780227,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.06360894371481503,"min":-7.951117964351878,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.006704086883395326,"min":-0.8648272079579971,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.015343831567203297,"min":0.2711026668548584,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.03378283930759804,"min":-4.797163181678922,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.021910778213949763,"min":-3.987761634938857,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.009284070410007296,"min":0.000021581046894425526,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.012783036979974485,"min":-1.9046725100161983,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.07273082733154297,"min":-9.52773838043213,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.006126228033327589,"min":-0.7351473639993107,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.029703759212119908,"min":0.28687000274658203,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04394429898729511,"min":-6.3279790541704966,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.016566915605582443,"min":-2.7501079905266854,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.012152872833551145,"min":3.913338286370366e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.01354524388032801,"min":-1.7473364605623134,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.08566816367355047,"min":-9.937506986131854,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.006012305558896532,"min":-0.7876120282154457,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.01469323155926723,"min":0.29223933815956116,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.030889174517463234,"min":-3.2433633243336395,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.014836942448335536,"min":-2.047498057870304,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.007234466105343445,"min":0.00013165915152058005,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.016261722527298274,"min":-1.4798167499841428,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.091437328563017,"min":-14.172785927267636,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.004750356487199372,"min":-0.650798838746314,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.008174965545242907,"min":0.3120670020580292,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.030133422215779623,"min":-2.41067377726237,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.006088157261119169,"min":-0.7853722866843729,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.003668997334498985,"min":3.9124486300013356e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,1024],"quantization":{"scale":0.010959514449624454,"min":-1.4028178495519301,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_pointwise/weights"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.10896045834410424,"min":-14.818622334798176,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,1024,1],"quantization":{"scale":0.004633033509347953,"min":-0.5652300881404502,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/depthwise_weights"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.022285057224479377,"min":0.23505790531635284,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.0324854850769043,"min":-3.9957146644592285,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.014760061806323482,"min":-2.125448900110581,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.0036057423142825855,"min":3.9067056828997994e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,1024,1024],"quantization":{"scale":0.017311988157384536,"min":-2.094750567043529,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_pointwise/weights"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.16447528764313343,"min":-25.658144872328815,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[1,1,1024,256],"quantization":{"scale":0.0026493051472832175,"min":-0.36825341547236723,"dtype":"uint8"},"name":"Prediction/Conv2d_0_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.012474596734140433,"min":-2.3078003958159803,"dtype":"uint8"},"name":"Prediction/Conv2d_0_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,256,512],"quantization":{"scale":0.014533351449405445,"min":-1.8166689311756807,"dtype":"uint8"},"name":"Prediction/Conv2d_1_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.024268776762719248,"min":-2.4754152297973633,"dtype":"uint8"},"name":"Prediction/Conv2d_1_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[1,1,512,128],"quantization":{"scale":0.002208403746287028,"min":-0.28709248701731366,"dtype":"uint8"},"name":"Prediction/Conv2d_2_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.012451349052728392,"min":-1.5937726787492341,"dtype":"uint8"},"name":"Prediction/Conv2d_2_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,128,256],"quantization":{"scale":0.026334229637594783,"min":-2.8967652601354263,"dtype":"uint8"},"name":"Prediction/Conv2d_3_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.02509917792151956,"min":-1.4055539636050953,"dtype":"uint8"},"name":"Prediction/Conv2d_3_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[1,1,256,128],"quantization":{"scale":0.004565340046789132,"min":-0.3971845840706545,"dtype":"uint8"},"name":"Prediction/Conv2d_4_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.017302456556581983,"min":-2.5953684834872974,"dtype":"uint8"},"name":"Prediction/Conv2d_4_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,128,256],"quantization":{"scale":0.025347338470758176,"min":-3.8527954475552426,"dtype":"uint8"},"name":"Prediction/Conv2d_5_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.033134659598855414,"min":-2.9158500446992766,"dtype":"uint8"},"name":"Prediction/Conv2d_5_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[1,1,256,64],"quantization":{"scale":0.002493104397081861,"min":-0.2817207968702503,"dtype":"uint8"},"name":"Prediction/Conv2d_6_pointwise/weights"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.011383360974928912,"min":-1.2749364291920382,"dtype":"uint8"},"name":"Prediction/Conv2d_6_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,64,128],"quantization":{"scale":0.020821522731407017,"min":-2.7484410005457263,"dtype":"uint8"},"name":"Prediction/Conv2d_7_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.052144218893612135,"min":-3.5979511036592373,"dtype":"uint8"},"name":"Prediction/Conv2d_7_pointwise/convolution_bn_offset"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":6,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/stack_1/1"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":1,"dtype":"uint8"},"name":"concat_1/axis"},{"dtype":"int32","shape":[1],"quantization":{"scale":1,"min":0,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/strided_slice/stack"},{"dtype":"int32","shape":[1],"quantization":{"scale":1,"min":1,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/strided_slice/stack_1"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":5118,"dtype":"uint8"},"name":"Postprocessor/stack/1"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":4,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/stack/3"},{"dtype":"float32","shape":[1, 5118, 4],"name":"Output/extra_dim"}]}] \ No newline at end of file diff --git a/src/server/public/models/tiny_face_detector_model-shard1 b/src/server/public/models/tiny_face_detector_model-shard1 new file mode 100644 index 000000000..a3f113a54 Binary files /dev/null and b/src/server/public/models/tiny_face_detector_model-shard1 differ diff --git a/src/server/public/models/tiny_face_detector_model-weights_manifest.json b/src/server/public/models/tiny_face_detector_model-weights_manifest.json new file mode 100644 index 000000000..7d3b222d0 --- /dev/null +++ b/src/server/public/models/tiny_face_detector_model-weights_manifest.json @@ -0,0 +1 @@ +[{"weights":[{"name":"conv0/filters","shape":[3,3,3,16],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009007044399485869,"min":-1.2069439495311063}},{"name":"conv0/bias","shape":[16],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005263455241334205,"min":-0.9211046672334858}},{"name":"conv1/depthwise_filter","shape":[3,3,16,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004001977630690033,"min":-0.5042491814669441}},{"name":"conv1/pointwise_filter","shape":[1,1,16,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.013836609615999109,"min":-1.411334180831909}},{"name":"conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0015159862590771096,"min":-0.30926119685173037}},{"name":"conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002666276225856706,"min":-0.317286870876948}},{"name":"conv2/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015265831292844286,"min":-1.6792414422128714}},{"name":"conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0020280554598453,"min":-0.37113414915168985}},{"name":"conv3/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006100742489683862,"min":-0.8907084034938438}},{"name":"conv3/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.016276211832083907,"min":-2.0508026908425725}},{"name":"conv3/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003394414279975143,"min":-0.7637432129944072}},{"name":"conv4/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006716050119961009,"min":-0.8059260143953211}},{"name":"conv4/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.021875603993733724,"min":-2.8875797271728514}},{"name":"conv4/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0041141652009066415,"min":-0.8187188749804216}},{"name":"conv5/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008423839597141042,"min":-0.9013508368940915}},{"name":"conv5/pointwise_filter","shape":[1,1,256,512],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.030007277283014035,"min":-3.8709387695088107}},{"name":"conv5/bias","shape":[512],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008402082966823203,"min":-1.4871686851277068}},{"name":"conv8/filters","shape":[1,1,512,25],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.028336129469030042,"min":-4.675461362389957}},{"name":"conv8/bias","shape":[25],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002268134028303857,"min":-0.41053225912299807}}],"paths":["tiny_face_detector_model-shard1"]}] \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 9e03f9333641c818ed9c711282f27f7213cbe3c1 Mon Sep 17 00:00:00 2001 From: IEatChili Date: Fri, 2 Aug 2024 14:11:41 -0400 Subject: feat: integrated face recognition code with image documents --- src/client/util/DocumentManager.ts | 6 +- src/client/views/search/FaceRecognitionHandler.tsx | 86 +++++++++++++++------- 2 files changed, 65 insertions(+), 27 deletions(-) diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 8ad6ddf47..7d4684f41 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -6,11 +6,12 @@ import { Id } from '../../fields/FieldSymbols'; import { listSpec } from '../../fields/Schema'; import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; import { AudioField } from '../../fields/URLField'; -import { CollectionViewType } from '../documents/DocumentTypes'; +import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; import { DocumentView, DocumentViewInternal } from '../views/nodes/DocumentView'; import { FocusViewOptions } from '../views/nodes/FocusViewOptions'; import { OpenWhere } from '../views/nodes/OpenWhere'; import { PresBox } from '../views/nodes/trails'; +import { FaceRecognitionHandler } from '../views/search/FaceRecognitionHandler'; type childIterator = { viewSpec: Opt; childDocView: Opt; focused: boolean; contextPath: Doc[] }; export class DocumentManager { @@ -96,6 +97,9 @@ export class DocumentManager { @action public AddView = (view: DocumentView) => { + if (view.Document.type === DocumentType.IMG && view.Document.embedContainer) { + FaceRecognitionHandler.Instance.findMatches(view.Document); + } this.AddDocumentView(view); this.callAddViewFuncs(view); }; diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 86619b2d1..fcd38c42f 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -4,51 +4,84 @@ import { Doc, DocListCast, NumListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; -import { StrCast } from '../../../fields/Types'; +import { ImageCast, StrCast } from '../../../fields/Types'; +import { DocUtils } from '../../documents/DocUtils'; +import { Deserializable } from '../../util/SerializationHelper'; +import { DocumentView } from '../nodes/DocumentView'; export class FaceRecognitionHandler { static _instance: FaceRecognitionHandler; + private loadedModels: boolean = false; + examinedDocs: Set = new Set(); + processingDocs: Set = new Set(); constructor() { FaceRecognitionHandler._instance = this; this.loadModels(); - if (!Doc.ActiveDashboard![DocData].faceDocuments) { - Doc.ActiveDashboard![DocData].faceDocuments = new List(); - } } async loadModels() { const MODEL_URL = `/models`; - await faceapi.loadTinyFaceDetectorModel(MODEL_URL); - await faceapi.loadFaceLandmarkTinyModel(MODEL_URL); + await faceapi.loadFaceDetectionModel(MODEL_URL); + await faceapi.loadFaceLandmarkModel(MODEL_URL); await faceapi.loadFaceRecognitionModel(MODEL_URL); + this.loadedModels = true; } public static get Instance() { return FaceRecognitionHandler._instance ?? new FaceRecognitionHandler(); } - public async findMatches(doc: Doc, imageURL: string) { - const img = await this.loadImage(imageURL); - - const fullFaceDescriptions = await faceapi.detectAllFaces(img, new TinyFaceDetectorOptions()).withFaceLandmarks(true).withFaceDescriptors(); - - fullFaceDescriptions.forEach(fd => { - const match = this.findMatch(fd.descriptor); - if (match) { - match[DocData].associatedDocs = new List([...DocListCast(match[DocData].associatedDocs), doc]); - match[DocData].faceDescriptors = new List>([...(match[DocData].faceDescriptors as List>), Array.from(fd.descriptor) as List]); - } else { - const newFaceDocument = new Doc(); - const converted_array = Array.from(fd.descriptor); - newFaceDocument[DocData].faceDescriptors = new List>(); - (newFaceDocument[DocData].faceDescriptors as List>).push(converted_array as List); - newFaceDocument[DocData].label = `Person ${DocListCast(Doc.ActiveDashboard![DocData].faceDocuments).length + 1}`; - newFaceDocument[DocData].associatedDocs = new List([doc]); - - Doc.ActiveDashboard![DocData].faceDocuments = new List([...DocListCast(Doc.ActiveDashboard![DocData].faceDocuments), newFaceDocument]); + public async findMatches(doc: Doc) { + if (this.loadedModels) { + if (!Doc.ActiveDashboard![DocData].faceDocuments) { + Doc.ActiveDashboard![DocData].faceDocuments = new List(); } - }); + + if (this.examinedDocs.has(doc) || this.processingDocs.has(doc)) { + return; + } + + this.processingDocs.add(doc); + + try { + const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); + const imageURL = `${name}_o.${type}`; + + const img = await this.loadImage(imageURL); + + const fullFaceDescriptions = await faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors(); + + for (const fd of fullFaceDescriptions) { + const match = this.findMatch(fd.descriptor); + if (match) { + const converted_array = Array.from(fd.descriptor); + const converted_list = new List(converted_array); + match[DocData].associatedDocs = new List([...DocListCast(match[DocData].associatedDocs), doc]); + match[DocData].faceDescriptors = new List>([...(match[DocData].faceDescriptors as List>), converted_list]); + } else { + const newFaceDocument = new Doc(); + const converted_array = Array.from(fd.descriptor); + const converted_list = new List(converted_array); + newFaceDocument[DocData].faceDescriptors = new List>(); + (newFaceDocument[DocData].faceDescriptors as List>).push(converted_list); + newFaceDocument[DocData].label = `Person ${DocListCast(Doc.ActiveDashboard![DocData].faceDocuments).length + 1}`; + newFaceDocument[DocData].associatedDocs = new List([doc]); + + Doc.ActiveDashboard![DocData].faceDocuments = new List([...DocListCast(Doc.ActiveDashboard![DocData].faceDocuments), newFaceDocument]); + } + } + + this.examinedDocs.add(doc); + console.log(this.examinedDocs); + + DocListCast(Doc.ActiveDashboard![DocData].faceDocuments).forEach(doc => console.log(DocListCast(doc[DocData].associatedDocs))); + } catch (error) { + console.error('Error processing document:', error); + } finally { + this.processingDocs.delete(doc); + } + } } private findMatch(cur_descriptor: Float32Array) { @@ -68,6 +101,7 @@ export class FaceRecognitionHandler { } else { for (const doc of DocListCast(Doc.ActiveDashboard![DocData].faceDocuments)) { if (doc[DocData].label === match.label) { + console.log(match.label); return doc; } } -- cgit v1.2.3-70-g09d2 From 4574b7f03ccc85c4bebdbfd9475788456086704f Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 8 Aug 2024 12:27:40 -0400 Subject: many changes to add typing in place of 'any's etc --- package-lock.json | 4932 ++++++++++---------- package.json | 3 + src/ClientUtils.ts | 75 +- src/JSZipUtils.js | 10 +- src/client/DocServer.ts | 263 +- src/client/Network.ts | 27 +- src/client/documents/DocUtils.ts | 64 +- src/client/documents/DocumentTypes.ts | 1 - src/client/documents/Documents.ts | 33 +- src/client/util/CalendarManager.tsx | 44 +- src/client/util/CaptureManager.tsx | 10 +- src/client/util/CurrentUserUtils.ts | 80 +- src/client/util/DictationManager.ts | 43 +- src/client/util/DocumentManager.ts | 39 +- src/client/util/DragManager.ts | 103 +- src/client/util/DropConverter.ts | 13 +- src/client/util/GroupManager.tsx | 22 +- src/client/util/GroupMemberView.tsx | 2 - src/client/util/History.ts | 7 +- src/client/util/Import & Export/ImageUtils.ts | 1 + .../util/Import & Export/ImportMetadataEntry.tsx | 2 - src/client/util/InteractionUtils.tsx | 22 +- src/client/util/LinkFollower.ts | 4 +- src/client/util/LinkManager.ts | 43 +- src/client/util/ProsemirrorCopy/prompt.js | 179 - src/client/util/RTFMarkup.tsx | 4 +- src/client/util/ReplayMovements.ts | 15 +- src/client/util/Scripting.ts | 34 +- src/client/util/ScriptingGlobals.ts | 42 +- src/client/util/SearchUtil.ts | 2 + src/client/util/SelectionManager.ts | 2 +- src/client/util/SerializationHelper.ts | 36 +- src/client/util/ServerStats.tsx | 19 +- src/client/util/SettingsManager.tsx | 2 - src/client/util/SharingManager.tsx | 23 +- src/client/util/SnappingManager.ts | 2 +- src/client/util/TrackMovements.ts | 8 +- src/client/util/TypedEvent.ts | 2 +- src/client/util/UndoManager.ts | 34 +- src/client/util/reportManager/ReportManager.tsx | 6 +- .../util/reportManager/ReportManagerComponents.tsx | 11 +- .../util/reportManager/reportManagerSchema.ts | 40 +- .../util/reportManager/reportManagerUtils.ts | 16 +- src/client/util/request-image-size.ts | 36 +- src/client/views/AntimodeMenu.tsx | 2 +- src/client/views/ContextMenu.tsx | 33 +- src/client/views/ContextMenuItem.tsx | 10 +- src/client/views/DashboardView.tsx | 6 +- src/client/views/FilterPanel.tsx | 12 +- src/client/views/GestureOverlay.tsx | 26 +- src/client/views/InkTranscription.tsx | 3 +- src/client/views/InkingStroke.tsx | 22 +- src/client/views/LightboxView.tsx | 22 +- src/client/views/Main.tsx | 18 +- src/client/views/MainView.tsx | 53 +- src/client/views/OverlayView.tsx | 21 +- src/client/views/ScriptingRepl.tsx | 54 +- src/client/views/StyleProvider.tsx | 6 +- src/client/views/ViewBoxInterface.ts | 3 + .../views/collections/CollectionCalendarView.tsx | 4 +- .../views/collections/CollectionCardDeckView.tsx | 13 +- .../views/collections/CollectionCarouselView.tsx | 16 +- .../views/collections/CollectionDockingView.tsx | 68 +- .../collections/CollectionMasonryViewFieldRow.tsx | 20 +- src/client/views/collections/CollectionMenu.tsx | 4 - .../views/collections/CollectionNoteTakingView.tsx | 29 +- .../collections/CollectionNoteTakingViewColumn.tsx | 15 +- .../views/collections/CollectionPileView.tsx | 10 +- .../collections/CollectionStackedTimeline.tsx | 21 +- .../views/collections/CollectionStackingView.tsx | 27 +- src/client/views/collections/CollectionSubView.tsx | 23 +- .../views/collections/CollectionTimeView.tsx | 8 +- .../views/collections/CollectionTreeView.tsx | 43 +- src/client/views/collections/TabDocView.tsx | 28 +- src/client/views/collections/TreeView.tsx | 86 +- .../CollectionFreeFormInfoState.tsx | 12 +- .../CollectionFreeFormPannableContents.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 65 +- .../collectionLinear/CollectionLinearView.tsx | 10 +- src/client/views/nodes/AudioBox.tsx | 57 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 24 +- src/client/views/nodes/ComparisonBox.tsx | 7 +- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 8 +- .../views/nodes/DataVizBox/SchemaCSVPopUp.tsx | 2 - .../views/nodes/DataVizBox/components/TableBox.tsx | 56 +- src/client/views/nodes/DocumentContentsView.tsx | 46 +- src/client/views/nodes/DocumentLinksButton.tsx | 4 +- src/client/views/nodes/DocumentView.tsx | 39 +- src/client/views/nodes/EquationBox.tsx | 11 +- src/client/views/nodes/FieldView.tsx | 3 +- .../views/nodes/FontIconBox/ButtonInterface.ts | 12 - src/client/views/nodes/FontIconBox/FontIconBox.tsx | 46 +- src/client/views/nodes/ImageBox.tsx | 9 +- src/client/views/nodes/KeyValueBox.tsx | 14 +- src/client/views/nodes/KeyValuePair.tsx | 9 +- src/client/views/nodes/LinkBox.tsx | 14 +- src/client/views/nodes/LinkDocPreview.tsx | 6 +- src/client/views/nodes/LoadingBox.tsx | 2 +- src/client/views/nodes/MapBox/MapBox.tsx | 8 +- src/client/views/nodes/PDFBox.tsx | 18 +- .../nodes/PhysicsBox/PhysicsSimulationBox.tsx | 15 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 5 +- src/client/views/nodes/ScreenshotBox.tsx | 35 +- src/client/views/nodes/ScriptingBox.tsx | 96 +- src/client/views/nodes/VideoBox.tsx | 18 +- src/client/views/nodes/WebBox.tsx | 47 +- src/client/views/nodes/WebBoxRenderer.js | 18 +- src/client/views/nodes/audio/AudioWaveform.tsx | 2 +- .../nodes/formattedText/DashDocCommentView.tsx | 38 +- .../views/nodes/formattedText/DashDocView.tsx | 29 +- .../views/nodes/formattedText/DashFieldView.tsx | 34 +- .../views/nodes/formattedText/EquationEditor.tsx | 17 +- .../views/nodes/formattedText/EquationView.tsx | 22 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 89 +- .../formattedText/FormattedTextBoxComment.tsx | 4 +- .../views/nodes/formattedText/ParagraphNodeSpec.ts | 36 +- .../views/nodes/formattedText/RichTextMenu.tsx | 42 +- .../views/nodes/formattedText/RichTextRules.ts | 56 +- src/client/views/nodes/formattedText/marks_rts.ts | 40 +- src/client/views/nodes/formattedText/nodes_rts.ts | 91 +- src/client/views/pdf/GPTPopup/GPTPopup.tsx | 7 +- src/client/views/pdf/PDFViewer.tsx | 12 +- src/fields/Doc.ts | 160 +- src/fields/List.ts | 104 +- src/fields/ObjectField.ts | 21 +- src/fields/Proxy.ts | 31 +- src/fields/RefField.ts | 2 +- src/fields/ScriptField.ts | 28 +- src/fields/util.ts | 132 +- src/mobile/ImageUpload.tsx | 3 +- src/mobile/MobileInterface.tsx | 1 - src/pen-gestures/GestureUtils.ts | 5 +- src/server/ApiManagers/GooglePhotosManager.ts | 6 +- src/server/ApiManagers/UploadManager.ts | 14 +- src/server/DashStats.ts | 1 + src/server/DashUploadUtils.ts | 65 +- src/server/SharedMediaTypes.ts | 4 +- src/server/index.ts | 1 - src/server/websocket.ts | 5 +- webpack.config.js | 3 +- 140 files changed, 4387 insertions(+), 4500 deletions(-) delete mode 100644 src/client/util/ProsemirrorCopy/prompt.js delete mode 100644 src/client/views/nodes/FontIconBox/ButtonInterface.ts diff --git a/package-lock.json b/package-lock.json index 168c6d087..328110401 100644 --- a/package-lock.json +++ b/package-lock.json @@ -258,6 +258,7 @@ "@types/cookie-parser": "^1.4.6", "@types/cookie-session": "^2.0.48", "@types/d3": "^7.4.3", + "@types/dom-mediacapture-record": "^1.0.19", "@types/exif": "^0.6.5", "@types/express": "^4.17.21", "@types/express-session": "^1.17.10", @@ -285,10 +286,12 @@ "@types/request": "^2.48.12", "@types/request-promise": "^4.1.51", "@types/shelljs": "^0.8.15", + "@types/textarea-caret": "^3.0.3", "@types/textfit": "^2.4.4", "@types/uuid": "^10.0.0", "@types/valid-url": "^1.0.7", "@types/webpack": "^5.28.5", + "@types/webscopeio__react-textarea-autocomplete": "^4.7.5", "@types/youtube": "0.0.50", "chai": "^5.0.0", "cross-env": "^7.0.3", @@ -320,91 +323,91 @@ } }, "node_modules/@adobe/react-spectrum": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.35.1.tgz", - "integrity": "sha512-QNhsaEHv5S5Vqsk7b8aCV9F7qAnWw8VJ/Nep/SOjeiJ7vK993jEOetEhSsUIQ8VHsMKs6qkTtZr0/DKoV+Z/9w==", + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.36.1.tgz", + "integrity": "sha512-ZDxbCjFBYU3S8iEbsrKoJS5fIf91lpM44nWyY1rKwqD7Lu6Lo0cNX8g44x5pXi+PcMr2KxZOPTj4khfCqMOCvg==", "dependencies": { "@internationalized/string": "^3.2.3", - "@react-aria/i18n": "^3.11.1", - "@react-aria/ssr": "^3.9.4", - "@react-aria/utils": "^3.24.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-spectrum/actionbar": "^3.4.5", - "@react-spectrum/actiongroup": "^3.10.5", - "@react-spectrum/avatar": "^3.0.12", - "@react-spectrum/badge": "^3.1.13", - "@react-spectrum/breadcrumbs": "^3.9.7", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/buttongroup": "^3.6.13", - "@react-spectrum/calendar": "^3.4.9", - "@react-spectrum/checkbox": "^3.9.6", - "@react-spectrum/combobox": "^3.12.5", - "@react-spectrum/contextualhelp": "^3.6.11", - "@react-spectrum/datepicker": "^3.9.6", - "@react-spectrum/dialog": "^3.8.11", - "@react-spectrum/divider": "^3.5.13", - "@react-spectrum/dnd": "^3.3.10", - "@react-spectrum/dropzone": "^3.0.1", - "@react-spectrum/filetrigger": "^3.0.1", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/icon": "^3.7.13", - "@react-spectrum/illustratedmessage": "^3.5.1", - "@react-spectrum/image": "^3.5.1", - "@react-spectrum/inlinealert": "^3.2.5", - "@react-spectrum/labeledvalue": "^3.1.14", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/link": "^3.6.7", - "@react-spectrum/list": "^3.7.10", - "@react-spectrum/listbox": "^3.12.9", - "@react-spectrum/menu": "^3.19.1", - "@react-spectrum/meter": "^3.5.1", - "@react-spectrum/numberfield": "^3.9.3", - "@react-spectrum/overlays": "^5.6.1", - "@react-spectrum/picker": "^3.14.5", - "@react-spectrum/progress": "^3.7.7", - "@react-spectrum/provider": "^3.9.7", - "@react-spectrum/radio": "^3.7.6", - "@react-spectrum/searchfield": "^3.8.6", - "@react-spectrum/slider": "^3.6.9", - "@react-spectrum/statuslight": "^3.5.13", - "@react-spectrum/switch": "^3.5.5", - "@react-spectrum/table": "^3.12.10", - "@react-spectrum/tabs": "^3.8.10", - "@react-spectrum/tag": "^3.2.6", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/textfield": "^3.12.1", - "@react-spectrum/theme-dark": "^3.5.10", - "@react-spectrum/theme-default": "^3.5.10", - "@react-spectrum/theme-light": "^3.4.10", - "@react-spectrum/tooltip": "^3.6.7", - "@react-spectrum/view": "^3.6.10", - "@react-spectrum/well": "^3.4.13", - "@react-stately/collections": "^3.10.7", - "@react-stately/data": "^3.11.4", - "@react-types/shared": "^3.23.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/ssr": "^3.9.5", + "@react-aria/utils": "^3.25.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-spectrum/actionbar": "^3.5.1", + "@react-spectrum/actiongroup": "^3.10.7", + "@react-spectrum/avatar": "^3.0.14", + "@react-spectrum/badge": "^3.1.15", + "@react-spectrum/breadcrumbs": "^3.9.9", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/buttongroup": "^3.6.15", + "@react-spectrum/calendar": "^3.4.11", + "@react-spectrum/checkbox": "^3.9.8", + "@react-spectrum/combobox": "^3.13.1", + "@react-spectrum/contextualhelp": "^3.6.13", + "@react-spectrum/datepicker": "^3.10.1", + "@react-spectrum/dialog": "^3.8.13", + "@react-spectrum/divider": "^3.5.15", + "@react-spectrum/dnd": "^3.4.1", + "@react-spectrum/dropzone": "^3.0.3", + "@react-spectrum/filetrigger": "^3.0.3", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/icon": "^3.7.15", + "@react-spectrum/illustratedmessage": "^3.5.3", + "@react-spectrum/image": "^3.5.3", + "@react-spectrum/inlinealert": "^3.2.7", + "@react-spectrum/labeledvalue": "^3.1.16", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/link": "^3.6.9", + "@react-spectrum/list": "^3.8.1", + "@react-spectrum/listbox": "^3.13.1", + "@react-spectrum/menu": "^3.20.1", + "@react-spectrum/meter": "^3.5.3", + "@react-spectrum/numberfield": "^3.9.5", + "@react-spectrum/overlays": "^5.6.3", + "@react-spectrum/picker": "^3.15.1", + "@react-spectrum/progress": "^3.7.9", + "@react-spectrum/provider": "^3.9.9", + "@react-spectrum/radio": "^3.7.8", + "@react-spectrum/searchfield": "^3.8.8", + "@react-spectrum/slider": "^3.6.11", + "@react-spectrum/statuslight": "^3.5.15", + "@react-spectrum/switch": "^3.5.7", + "@react-spectrum/table": "^3.13.1", + "@react-spectrum/tabs": "^3.8.12", + "@react-spectrum/tag": "^3.2.8", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/textfield": "^3.12.3", + "@react-spectrum/theme-dark": "^3.5.12", + "@react-spectrum/theme-default": "^3.5.12", + "@react-spectrum/theme-light": "^3.4.12", + "@react-spectrum/tooltip": "^3.6.9", + "@react-spectrum/view": "^3.6.12", + "@react-spectrum/well": "^3.4.15", + "@react-stately/collections": "^3.10.9", + "@react-stately/data": "^3.11.6", + "@react-types/shared": "^3.24.1", "client-only": "^0.0.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@adobe/react-spectrum-ui": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-ui/-/react-spectrum-ui-1.2.0.tgz", - "integrity": "sha512-os3EdjfyJbrukLcZ5uYtdFRiDlLB3zq2JoXp19J/IDpZ8btibJeRZYSwjL+LscEiT2pOYaF2McMQdkZTIwnllw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-ui/-/react-spectrum-ui-1.2.1.tgz", + "integrity": "sha512-wcrbEE2O/9WnEn6avBnaVRRx88S5PLFsPLr4wffzlbMfXeQsy+RMQwaJd3cbzrn18/j04Isit7f7Emfn0dhrJA==", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@adobe/react-spectrum-workflow": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-workflow/-/react-spectrum-workflow-2.3.4.tgz", - "integrity": "sha512-XPLzIBl58HdLF9WIPB7RDAvVXvCE3SjG+HaWQhW2P9MnxSz1DEA9O7mlTlYblJkMbfk10T/+RFaSupc1yoN+TA==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-workflow/-/react-spectrum-workflow-2.3.5.tgz", + "integrity": "sha512-b53VIPwPWKb/T5gzE3qs+QlGP5gVrw/LnWV3xMksDU+CRl3rzOKUwxIGiZO8ICyYh1WiyqY4myGlPU/nAynBUg==", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@ampproject/remapping": { @@ -544,9 +547,9 @@ } }, "node_modules/@azure/core-rest-pipeline": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.2.tgz", - "integrity": "sha512-Hnhm/PG9/SQ07JJyLDv3l9Qr8V3xgAe1hFoBYzt6LaalMxfL/ZqFaZf/bz5VN3pMcleCPwl8ivlS2Fjxq/iC8Q==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.3.tgz", + "integrity": "sha512-VxLk4AHLyqcHsfKe4MZ6IQ+D+ShuByy+RfStKfSjxJoL3WBWq17VNmrz8aT8etKzqc2nAeIyLxScjpzsS4fz8w==", "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-auth": "^1.4.0", @@ -584,9 +587,9 @@ } }, "node_modules/@azure/core-util": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.1.tgz", - "integrity": "sha512-OLsq0etbHO1MA7j6FouXFghuHrAFGk+5C1imcpQ2e+0oZhYF07WLA+NW2Vqs70R7d+zOAWiWM3tbE1sXcDN66g==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.2.tgz", + "integrity": "sha512-l1Qrqhi4x1aekkV+OlcqsJa4AnAkj5p0JV8omgwjaV9OAbP41lvrMvs+CptfetKkeEaGRGSzby7sjPZEX7+kkQ==", "dependencies": { "@azure/abort-controller": "^2.0.0", "tslib": "^2.6.2" @@ -607,9 +610,9 @@ } }, "node_modules/@azure/core-xml": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.4.2.tgz", - "integrity": "sha512-CW3MZhApe/S4iikbYKE7s83fjDBPIr2kpidX+hlGRwh7N4o1nIpQ/PfJTeioqhfqdMvRtheEl+ft64fyTaLNaA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.4.3.tgz", + "integrity": "sha512-D6G7FEmDiTctPKuWegX2WTrS1enKZwqYwdKTO6ZN6JMigcCehlT0/CYl+zWpI9vQ9frwwp7GQT3/owaEXgnOsA==", "dependencies": { "fast-xml-parser": "^4.3.2", "tslib": "^2.6.2" @@ -619,9 +622,9 @@ } }, "node_modules/@azure/logger": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.3.tgz", - "integrity": "sha512-J8/cIKNQB1Fc9fuYqBVnrppiUtW+5WWJPCj/tAokC5LdSTwkWWttN+jsRgw9BLYD7JDBx7PceiqOBxJJ1tQz3Q==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz", + "integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==", "dependencies": { "tslib": "^2.6.2" }, @@ -630,9 +633,9 @@ } }, "node_modules/@azure/storage-blob": { - "version": "12.23.0", - "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.23.0.tgz", - "integrity": "sha512-c1KJ5R5hqR/HtvmFtTn/Y1BNMq45NUBp0LZH7yF8WFMET+wmESgEr0FVTu/Z5NonmfUjbgJZG5Nh8xHc5RdWGQ==", + "version": "12.24.0", + "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.24.0.tgz", + "integrity": "sha512-l8cmWM4C7RoNCBOImoFMxhTXe1Lr+8uQ/IgnhRNMpfoA9bAFWoLG4XrWm6O5rKXortreVQuD+fc1hbzWklOZbw==", "dependencies": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.4.0", @@ -641,7 +644,7 @@ "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.1.1", "@azure/core-rest-pipeline": "^1.10.1", - "@azure/core-tracing": "^1.0.0", + "@azure/core-tracing": "^1.1.2", "@azure/core-util": "^1.6.1", "@azure/core-xml": "^1.3.2", "@azure/logger": "^1.0.0", @@ -665,29 +668,29 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", - "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", + "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", - "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.9", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-module-transforms": "^7.24.9", - "@babel/helpers": "^7.24.8", - "@babel/parser": "^7.24.8", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.9", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -703,11 +706,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", - "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", "dependencies": { - "@babel/types": "^7.24.9", + "@babel/types": "^7.25.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -740,11 +743,11 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", - "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dependencies": { - "@babel/compat-data": "^7.24.8", + "@babel/compat-data": "^7.25.2", "@babel/helper-validator-option": "^7.24.8", "browserslist": "^4.23.1", "lru-cache": "^5.1.1", @@ -755,18 +758,16 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.8.tgz", - "integrity": "sha512-4f6Oqnmyp2PP3olgUMmOwC3akxSm5aBYraQ6YDdKy7NcAMkDECHWG0DEnV6M2UAkERgIBhYt8S27rURPg7SxWA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", + "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", "@babel/helper-member-expression-to-functions": "^7.24.8", "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/traverse": "^7.25.0", "semver": "^6.3.1" }, "engines": { @@ -777,9 +778,9 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", + "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "regexpu-core": "^5.3.1", @@ -807,40 +808,6 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", @@ -866,15 +833,14 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", - "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -903,13 +869,13 @@ } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -919,13 +885,13 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -958,17 +924,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", @@ -994,27 +949,26 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", - "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", + "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", "peer": true, "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.8" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -1035,9 +989,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", - "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", + "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "dependencies": { + "@babel/types": "^7.25.2" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -1046,12 +1003,26 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", - "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", + "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1061,11 +1032,11 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1091,12 +1062,12 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", - "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -1362,14 +1333,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", + "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -1409,11 +1380,11 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1454,17 +1425,15 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.8.tgz", - "integrity": "sha512-VXy91c47uujj758ud9wx+OMgheXm4qJfyhj1P18YvlrQkNOSrwsteHk+EFS3OMGfhMhpZa0A+81eE7G4QC+3CA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz", + "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.0", "globals": "^11.1.0" }, "engines": { @@ -1540,6 +1509,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", @@ -1601,13 +1585,13 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" }, "engines": { "node": ">=6.9.0" @@ -1632,11 +1616,11 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", + "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1706,14 +1690,14 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -1934,15 +1918,15 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", - "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz", + "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -2140,18 +2124,19 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.8.tgz", - "integrity": "sha512-vObvMZB6hNWuDxhSaEPTKCwcqkAIuDtE+bQGn4XMXne1DSLzFVY8Vmj1bm+mUQXYNN8NmaQEO+r8MMbzPr1jBQ==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz", + "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==", "dependencies": { - "@babel/compat-data": "^7.24.8", - "@babel/helper-compilation-targets": "^7.24.8", + "@babel/compat-data": "^7.25.2", + "@babel/helper-compilation-targets": "^7.25.2", "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-validator-option": "^7.24.8", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -2172,29 +2157,30 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.0", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", "@babel/plugin-transform-class-properties": "^7.24.7", "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.8", + "@babel/plugin-transform-classes": "^7.25.0", "@babel/plugin-transform-computed-properties": "^7.24.7", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-dotall-regex": "^7.24.7", "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", "@babel/plugin-transform-dynamic-import": "^7.24.7", "@babel/plugin-transform-exponentiation-operator": "^7.24.7", "@babel/plugin-transform-export-namespace-from": "^7.24.7", "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", "@babel/plugin-transform-member-expression-literals": "^7.24.7", "@babel/plugin-transform-modules-amd": "^7.24.7", "@babel/plugin-transform-modules-commonjs": "^7.24.8", - "@babel/plugin-transform-modules-systemjs": "^7.24.7", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", "@babel/plugin-transform-modules-umd": "^7.24.7", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", "@babel/plugin-transform-new-target": "^7.24.7", @@ -2271,9 +2257,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", - "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2282,9 +2268,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.8.tgz", - "integrity": "sha512-DXG/BhegtMHhnN7YPIvxWd303/9aXvYFD1TjNL3CD6tUrhI2LVsg3Lck0aql5TRH29n4sj3emcROypkZVUfSuA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.0.tgz", + "integrity": "sha512-BOehWE7MgQ8W8Qn0CQnMtg2tHPHPulcS/5AVpFvs2KCK1ET+0WqZqPvnpRpFN81gYoFopdIEJX9Sgjw3ZBccPg==", "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" @@ -2294,31 +2280,28 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", - "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", + "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.8", - "@babel/types": "^7.24.8", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.2", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2335,9 +2318,9 @@ } }, "node_modules/@babel/types": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", - "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", + "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", @@ -2411,9 +2394,9 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/@emotion/cache": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.0.tgz", - "integrity": "sha512-hPV345J/tH0Cwk2wnU/3PBzORQ9HeX+kQSbwI+jslzpRCHE6fSGTohswksA/Ensr8znPzwfzKZCmAM9Lmlhp7g==", + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", "dependencies": { "@emotion/memoize": "^0.9.0", "@emotion/sheet": "^1.4.0", @@ -2637,9 +2620,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", - "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz", + "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2673,29 +2656,29 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", - "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz", + "integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==", "dependencies": { - "@floating-ui/utils": "^0.2.5" + "@floating-ui/utils": "^0.2.7" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", - "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz", + "integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==", "dependencies": { "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.5" + "@floating-ui/utils": "^0.2.7" } }, "node_modules/@floating-ui/react": { - "version": "0.26.20", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.20.tgz", - "integrity": "sha512-RixKJJG92fcIsVoqrFr4Onpzh7hlOx4U7NV4aLhMLmtvjZ5oTB/WzXaANYUZATKqXvvW7t9sCxtzejip26N5Ag==", + "version": "0.26.22", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.22.tgz", + "integrity": "sha512-LNv4azPt8SpT4WW7Kku5JNVjLk2GcS0bGGjFTAgqOONRFo9r/aaGHHPpdiIuQbB1t8shmWyWqTTUDmZ9fcNshg==", "dependencies": { "@floating-ui/react-dom": "^2.1.1", - "@floating-ui/utils": "^0.2.5", + "@floating-ui/utils": "^0.2.7", "tabbable": "^6.0.0" }, "peerDependencies": { @@ -2716,9 +2699,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", - "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz", + "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==" }, "node_modules/@formatjs/ecma402-abstract": { "version": "2.0.0", @@ -2933,9 +2916,9 @@ } }, "node_modules/@internationalized/date": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.4.tgz", - "integrity": "sha512-qoVJVro+O0rBaw+8HPjUB1iH8Ihf8oziEnqMnvhJUSuVIrHOuZ6eNLHNvzXJKUvAtaDiqMnRlg8Z2mgh09BlUw==", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.5.tgz", + "integrity": "sha512-H+CfYvOZ0LTJeeLOqm19E3uj/4YjrmOFtBufDHPfvtI80hFAMqtrp7oCACpe4Cil5l8S0Qu/9dYfZc/5lY8WQQ==", "dependencies": { "@swc/helpers": "^0.5.0" } @@ -3558,9 +3541,9 @@ } }, "node_modules/@jsonjoy.com/json-pack": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz", - "integrity": "sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", + "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", "dependencies": { "@jsonjoy.com/base64": "^1.1.1", "@jsonjoy.com/util": "^1.1.2", @@ -3579,9 +3562,9 @@ } }, "node_modules/@jsonjoy.com/util": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz", - "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz", + "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==", "engines": { "node": ">=10.0" }, @@ -3783,18 +3766,18 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.4.tgz", - "integrity": "sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.6.tgz", + "integrity": "sha512-kytg6LheUG42V8H/o/Ptz3olSO5kUXW9zF0ox18VnblX6bO2yif1FPItgc3ey1t5ansb1+gbe7SatntqusQupg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.4.tgz", - "integrity": "sha512-j9/CWctv6TH6Dou2uR2EH7UOgu79CW/YcozxCYVLJ7l03pCsiOlJ5sBArnWJxJ+nGkFwyL/1d1k8JEPMDR125A==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.6.tgz", + "integrity": "sha512-ceNGjoXheH9wbIFa1JHmSc9QVjJUvh18KvHrR4/FkJCSi9HXJ+9ee1kUhCOEFfuxNF8UB6WWVrIUOUgRd70t0A==", "dependencies": { "@babel/runtime": "^7.23.9" }, @@ -3817,15 +3800,15 @@ } }, "node_modules/@mui/material": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.4.tgz", - "integrity": "sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.6.tgz", + "integrity": "sha512-0LUIKBOIjiFfzzFNxXZBRAyr9UQfmTAFzbt6ziOU2FDXhorNN2o3N9/32mNJbCA8zJo2FqFU6d3dtoqUDyIEfA==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/core-downloads-tracker": "^5.16.4", - "@mui/system": "^5.16.4", + "@mui/core-downloads-tracker": "^5.16.6", + "@mui/system": "^5.16.6", "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.4", + "@mui/utils": "^5.16.6", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.0", @@ -3861,12 +3844,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz", - "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", + "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.16.4", + "@mui/utils": "^5.16.6", "prop-types": "^15.8.1" }, "engines": { @@ -3887,9 +3870,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", - "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", + "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", "dependencies": { "@babel/runtime": "^7.23.9", "@emotion/cache": "^11.11.0", @@ -3918,15 +3901,15 @@ } }, "node_modules/@mui/system": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz", - "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.6.tgz", + "integrity": "sha512-5xgyJjBIMPw8HIaZpfbGAaFYPwImQn7Nyh+wwKWhvkoIeDosQ1ZMVrbTclefi7G8hNmqhip04duYwYpbBFnBgw==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.16.4", - "@mui/styled-engine": "^5.16.4", + "@mui/private-theming": "^5.16.6", + "@mui/styled-engine": "^5.16.6", "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.4", + "@mui/utils": "^5.16.6", "clsx": "^2.1.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -3970,11 +3953,12 @@ } }, "node_modules/@mui/utils": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", - "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", + "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", "dependencies": { "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", "@types/prop-types": "^15.7.12", "clsx": "^2.1.1", "prop-types": "^15.8.1", @@ -4148,372 +4132,387 @@ } }, "node_modules/@react-aria/actiongroup": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/@react-aria/actiongroup/-/actiongroup-3.7.5.tgz", - "integrity": "sha512-asJk6WN6MhtwqWzVx7zkakhTbrpk1XhJbxF2piGlk2pTCh8zUCnMjvFAmMdQN+voj5lEW4/CZNfrblNDwzCimQ==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-stately/list": "^3.10.5", - "@react-types/actiongroup": "^3.4.9", - "@react-types/shared": "^3.23.1", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@react-aria/actiongroup/-/actiongroup-3.7.7.tgz", + "integrity": "sha512-qkbCnMYt32ZWN8X7ycup/kbdaQLENJ+uzy3gRI5VY06RwN+btdvT8seZl1xR0n7qfdDCZxmd5WaKbXA0gl3bBA==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/list": "^3.10.7", + "@react-types/actiongroup": "^3.4.11", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/breadcrumbs": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.13.tgz", - "integrity": "sha512-G1Gqf/P6kVdfs94ovwP18fTWuIxadIQgHsXS08JEVcFVYMjb9YjqnEBaohUxD1tq2WldMbYw53ahQblT4NTG+g==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/link": "^3.7.1", - "@react-aria/utils": "^3.24.1", - "@react-types/breadcrumbs": "^3.7.5", - "@react-types/shared": "^3.23.1", + "version": "3.5.15", + "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.15.tgz", + "integrity": "sha512-KJ7678hwKbacz6dyY4aOJlgtV91PtuSnlWGR+AsK88WwHhpjjTjLLTSRepjbQ35GuQuoYokM4mmfaS/I0nblhw==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/link": "^3.7.3", + "@react-aria/utils": "^3.25.1", + "@react-types/breadcrumbs": "^3.7.7", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/button": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.9.5.tgz", - "integrity": "sha512-dgcYR6j8WDOMLKuVrtxzx4jIC05cVKDzc+HnPO8lNkBAOfjcuN5tkGRtIjLtqjMvpZHhQT5aDbgFpIaZzxgFIg==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-stately/toggle": "^3.7.4", - "@react-types/button": "^3.9.4", - "@react-types/shared": "^3.23.1", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.9.7.tgz", + "integrity": "sha512-xwE6uatbbn3KbNSc0dyDnOo539HJM2cqCPfjiQGt8O9cFbpQSmx76Fj4WotU3BwT7ZVbcAC8D206CgF1C2cDcQ==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/toggle": "^3.7.6", + "@react-types/button": "^3.9.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/calendar": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.8.tgz", - "integrity": "sha512-Whlp4CeAA5/ZkzrAHUv73kgIRYjw088eYGSc+cvSOCxfrc/2XkBm9rNrnSBv0DvhJ8AG0Fjz3vYakTmF3BgZBw==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.10.tgz", + "integrity": "sha512-5PokdIHAH+CAd6vMHFW9mg77I5tC0FQglYsCEI9ikhCnL5xlt3FmJjLtOs3UJQaWgrd4cdVd0oINpPafJ9ydhA==", "dependencies": { - "@internationalized/date": "^3.5.4", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", + "@internationalized/date": "^3.5.5", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/utils": "^3.24.1", - "@react-stately/calendar": "^3.5.1", - "@react-types/button": "^3.9.4", - "@react-types/calendar": "^3.4.6", - "@react-types/shared": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/calendar": "^3.5.3", + "@react-types/button": "^3.9.6", + "@react-types/calendar": "^3.4.8", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/checkbox": { - "version": "3.14.3", - "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.14.3.tgz", - "integrity": "sha512-EtBJL6iu0gvrw3A4R7UeVLR6diaVk/mh4kFBc7c8hQjpEJweRr4hmJT3hrNg3MBcTWLxFiMEXPGgWEwXDBygtA==", - "dependencies": { - "@react-aria/form": "^3.0.5", - "@react-aria/interactions": "^3.21.3", - "@react-aria/label": "^3.7.8", - "@react-aria/toggle": "^3.10.4", - "@react-aria/utils": "^3.24.1", - "@react-stately/checkbox": "^3.6.5", - "@react-stately/form": "^3.0.3", - "@react-stately/toggle": "^3.7.4", - "@react-types/checkbox": "^3.8.1", - "@react-types/shared": "^3.23.1", + "version": "3.14.5", + "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.14.5.tgz", + "integrity": "sha512-On8m66CNi1LvbDeDo355au0K66ayIjo0nDe4oe85aNsR/owyzz8hXNPAFuh98owQVMsKt4596FZICAVSMzzhJg==", + "dependencies": { + "@react-aria/form": "^3.0.7", + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.10", + "@react-aria/toggle": "^3.10.6", + "@react-aria/utils": "^3.25.1", + "@react-stately/checkbox": "^3.6.7", + "@react-stately/form": "^3.0.5", + "@react-stately/toggle": "^3.7.6", + "@react-types/checkbox": "^3.8.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@react-aria/collections": { + "version": "3.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/@react-aria/collections/-/collections-3.0.0-alpha.3.tgz", + "integrity": "sha512-SKsoQrCuz4zIVMwKGz0WcFoRbIP0H8+eRU2XzjmWX9KlRdrfeqIBOxuiU8XO3or0aHdbBI/bC/YtCjVzix5Lrg==", + "dependencies": { + "@react-aria/ssr": "^3.9.5", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/color": { - "version": "3.0.0-beta.33", - "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.0-beta.33.tgz", - "integrity": "sha512-nhqnIHYm5p6MbuF3cC6lnqzG7MjwBsBd0DtpO+ByFYO+zxpMMbeC5R+1SFxvapR4uqmAzTotbtiUCGsG+SUaIg==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/numberfield": "^3.11.3", - "@react-aria/slider": "^3.7.8", - "@react-aria/spinbutton": "^3.6.5", - "@react-aria/textfield": "^3.14.5", - "@react-aria/utils": "^3.24.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-stately/color": "^3.6.1", - "@react-stately/form": "^3.0.3", - "@react-types/color": "3.0.0-beta.25", - "@react-types/shared": "^3.23.1", + "version": "3.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.0-rc.1.tgz", + "integrity": "sha512-oP9PE0Xpo9uQ/TtH1x8iWhsjtk4OTIoTFdQZyoDsj8d84sqRv6Og9ajBZ/VTaneNK1n4NrPSx+qWfXu+SrWlDg==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/numberfield": "^3.11.5", + "@react-aria/slider": "^3.7.10", + "@react-aria/spinbutton": "^3.6.7", + "@react-aria/textfield": "^3.14.7", + "@react-aria/utils": "^3.25.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-stately/color": "^3.7.1", + "@react-stately/form": "^3.0.5", + "@react-types/color": "3.0.0-rc.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/combobox": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.9.1.tgz", - "integrity": "sha512-SpK92dCmT8qn8aEcUAihRQrBb5LZUhwIbDExFII8PvUvEFy/PoQHXIo3j1V29WkutDBDpMvBv/6XRCHGXPqrhQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.10.1.tgz", + "integrity": "sha512-B0zjX66HEqjPFnunYR0quAqwVJ6U0ez1eqBp25/611Dtzh3JHUovQmTE0xGGTjRe6N6qJg0VHVr2eRO/D0A+Lw==", "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/listbox": "^3.12.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/listbox": "^3.13.1", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/menu": "^3.14.1", - "@react-aria/overlays": "^3.22.1", - "@react-aria/selection": "^3.18.1", - "@react-aria/textfield": "^3.14.5", - "@react-aria/utils": "^3.24.1", - "@react-stately/collections": "^3.10.7", - "@react-stately/combobox": "^3.8.4", - "@react-stately/form": "^3.0.3", - "@react-types/button": "^3.9.4", - "@react-types/combobox": "^3.11.1", - "@react-types/shared": "^3.23.1", + "@react-aria/menu": "^3.15.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/textfield": "^3.14.7", + "@react-aria/utils": "^3.25.1", + "@react-stately/collections": "^3.10.9", + "@react-stately/combobox": "^3.9.1", + "@react-stately/form": "^3.0.5", + "@react-types/button": "^3.9.6", + "@react-types/combobox": "^3.12.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/datepicker": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.10.1.tgz", - "integrity": "sha512-4HZL593nrNMa1GjBmWEN/OTvNS6d3/16G1YJWlqiUlv11ADulSbqBIjMmkgwrJVFcjrgqtXFy+yyrTA/oq94Zw==", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.11.1.tgz", + "integrity": "sha512-yEEuDt/ynt7bTfd/9RD1EiLPysWhbgSYSpn5PHVz7I2XORvNPpyamyAgz3+oFiLFLC/zy0qrG7e6V1rvI1NBzw==", "dependencies": { - "@internationalized/date": "^3.5.4", + "@internationalized/date": "^3.5.5", "@internationalized/number": "^3.5.3", "@internationalized/string": "^3.2.3", - "@react-aria/focus": "^3.17.1", - "@react-aria/form": "^3.0.5", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/label": "^3.7.8", - "@react-aria/spinbutton": "^3.6.5", - "@react-aria/utils": "^3.24.1", - "@react-stately/datepicker": "^3.9.4", - "@react-stately/form": "^3.0.3", - "@react-types/button": "^3.9.4", - "@react-types/calendar": "^3.4.6", - "@react-types/datepicker": "^3.7.4", - "@react-types/dialog": "^3.5.10", - "@react-types/shared": "^3.23.1", + "@react-aria/focus": "^3.18.1", + "@react-aria/form": "^3.0.7", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.10", + "@react-aria/spinbutton": "^3.6.7", + "@react-aria/utils": "^3.25.1", + "@react-stately/datepicker": "^3.10.1", + "@react-stately/form": "^3.0.5", + "@react-types/button": "^3.9.6", + "@react-types/calendar": "^3.4.8", + "@react-types/datepicker": "^3.8.1", + "@react-types/dialog": "^3.5.12", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/dialog": { - "version": "3.5.14", - "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.14.tgz", - "integrity": "sha512-oqDCjQ8hxe3GStf48XWBf2CliEnxlR9GgSYPHJPUc69WBj68D9rVcCW3kogJnLAnwIyf3FnzbX4wSjvUa88sAQ==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/overlays": "^3.22.1", - "@react-aria/utils": "^3.24.1", - "@react-types/dialog": "^3.5.10", - "@react-types/shared": "^3.23.1", + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.16.tgz", + "integrity": "sha512-2clBSQQaoqCjAUkHnMA/noZ1ZnFbEVU67fL9M1QfokezAyLAlyCyD9XSed6+Td/Ncj80N3/Lax65XAlvWCyOlg==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-types/dialog": "^3.5.12", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/dnd": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.6.1.tgz", - "integrity": "sha512-6WnujUTD+cIYZVF/B+uXdHyJ+WSpbYa8jH282epvY4FUAq1qLmen12/HHcoj/5dswKQe8X6EM3OhkQM89d9vFw==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.7.1.tgz", + "integrity": "sha512-p3/pc8p2fGd4s+Qj4SfRPJjZFStuuXqRNyDQxd9AAFYUWcCQxwDOqtiTZmfvs7Hvl0PUuysHW6Q5v7ABRjVr7w==", "dependencies": { "@internationalized/string": "^3.2.3", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/overlays": "^3.22.1", - "@react-aria/utils": "^3.24.1", - "@react-stately/dnd": "^3.3.1", - "@react-types/button": "^3.9.4", - "@react-types/shared": "^3.23.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/dnd": "^3.4.1", + "@react-types/button": "^3.9.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/focus": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.17.1.tgz", - "integrity": "sha512-FLTySoSNqX++u0nWZJPPN5etXY0WBxaIe/YuL/GTEeuqUIuC/2bJSaw5hlsM6T2yjy6Y/VAxBcKSdAFUlU6njQ==", + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.1.tgz", + "integrity": "sha512-N0Cy61WCIv+57mbqC7hiZAsB+3rF5n4JKabxUmg/2RTJL6lq7hJ5N4gx75ymKxkN8GnVDwt4pKZah48Wopa5jw==", "dependencies": { - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/form": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.5.tgz", - "integrity": "sha512-n290jRwrrRXO3fS82MyWR+OKN7yznVesy5Q10IclSTVYHHI3VI53xtAPr/WzNjJR1um8aLhOcDNFKwnNIUUCsQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.7.tgz", + "integrity": "sha512-VIsKP/KytJPOLRQl0NxWWS1bQELPBuW3vRjmmhBrtgPFmp0uCLhjPBkP6A4uIVj1E/JtAocyHN3DNq4+IJGQCg==", "dependencies": { - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-stately/form": "^3.0.3", - "@react-types/shared": "^3.23.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/form": "^3.0.5", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/grid": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.9.1.tgz", - "integrity": "sha512-fGEZqAEaS8mqzV/II3N4ndoNWegIcbh+L3PmKbXdpKKUP8VgMs/WY5rYl5WAF0f5RoFwXqx3ibDLeR9tKj/bOg==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.10.1.tgz", + "integrity": "sha512-7dSgiYVQapBtPV4SIit+9fJ1qoEjtp+PXffJkWAPtGbg/jJ4b0jcVzykH7ARD4w/6jAJN/oVSfrKZqFPoLAd9w==", "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/selection": "^3.18.1", - "@react-aria/utils": "^3.24.1", - "@react-stately/collections": "^3.10.7", - "@react-stately/grid": "^3.8.7", - "@react-stately/selection": "^3.15.1", - "@react-stately/virtualizer": "^3.7.1", - "@react-types/checkbox": "^3.8.1", - "@react-types/grid": "^3.2.6", - "@react-types/shared": "^3.23.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/collections": "^3.10.9", + "@react-stately/grid": "^3.9.1", + "@react-stately/selection": "^3.16.1", + "@react-types/checkbox": "^3.8.3", + "@react-types/grid": "^3.2.8", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/gridlist": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.8.1.tgz", - "integrity": "sha512-vVPkkA+Ct0NDcpnNm/tnYaBumg0fP9pXxsPLqL1rxvsTyj1PaIpFTZ4corabPTbTDExZwUSTS3LG1n+o1OvBtQ==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/grid": "^3.9.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/selection": "^3.18.1", - "@react-aria/utils": "^3.24.1", - "@react-stately/collections": "^3.10.7", - "@react-stately/list": "^3.10.5", - "@react-stately/tree": "^3.8.1", - "@react-types/shared": "^3.23.1", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.9.1.tgz", + "integrity": "sha512-cue2KCI4WyVmL3j9tZx7xG7gUJ7UyRbawzRTcocJukOmpeoyRaw/robrIYK2Pd//GhRbIMAoo4iOyZk5j7vEww==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/grid": "^3.10.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/collections": "^3.10.9", + "@react-stately/list": "^3.10.7", + "@react-stately/tree": "^3.8.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/i18n": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.11.1.tgz", - "integrity": "sha512-vuiBHw1kZruNMYeKkTGGnmPyMnM5T+gT8bz97H1FqIq1hQ6OPzmtBZ6W6l6OIMjeHI5oJo4utTwfZl495GALFQ==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.1.tgz", + "integrity": "sha512-0q3gyogF9Ekah+9LOo6tcfshxsk2Ope+KdbtFHJVhznedMxn6RpHGcVur5ImbQ1dYafA5CmjBUGJW70b56+BGA==", "dependencies": { - "@internationalized/date": "^3.5.4", + "@internationalized/date": "^3.5.5", "@internationalized/message": "^3.1.4", "@internationalized/number": "^3.5.3", "@internationalized/string": "^3.2.3", - "@react-aria/ssr": "^3.9.4", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", + "@react-aria/ssr": "^3.9.5", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/interactions": { - "version": "3.21.3", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.21.3.tgz", - "integrity": "sha512-BWIuf4qCs5FreDJ9AguawLVS0lV9UU+sK4CCnbCNNmYqOWY+1+gRXCsnOM32K+oMESBxilAjdHW5n1hsMqYMpA==", + "version": "3.22.1", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.1.tgz", + "integrity": "sha512-5TLzQaDAQQ5C70yG8GInbO4wIylKY67RfTIIwQPGR/4n5OIjbUD8BOj3NuSsuZ/frUPaBXo1VEBBmSO23fxkjw==", "dependencies": { - "@react-aria/ssr": "^3.9.4", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", + "@react-aria/ssr": "^3.9.5", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/label": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.8.tgz", - "integrity": "sha512-MzgTm5+suPA3KX7Ug6ZBK2NX9cin/RFLsv1BdafJ6CZpmUSpWnGE/yQfYUB7csN7j31OsZrD3/P56eShYWAQfg==", + "version": "3.7.10", + "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.10.tgz", + "integrity": "sha512-e5XVHA+OUK0aIwr4nHcnIj0z1kUryGaJWYYD2OGkkIltyUCKmwpRqdx8LQYbO4HGsJhvC3hJgidFdGcQwHHPYw==", "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/link": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.1.tgz", - "integrity": "sha512-a4IaV50P3fXc7DQvEIPYkJJv26JknFbRzFT5MJOMgtzuhyJoQdILEUK6XHYjcSSNCA7uLgzpojArVk5Hz3lCpw==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-types/link": "^3.5.5", - "@react-types/shared": "^3.23.1", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.3.tgz", + "integrity": "sha512-dOwzxzo7LF4djBfRC8GcIhuTpDkNUIMT6ykQRV1a3749kgrr10YLascsO/l66k60i2k0T2oClkzfefYEK6WZeA==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-types/link": "^3.5.7", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/listbox": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.12.1.tgz", - "integrity": "sha512-7JiUp0NGykbv/HgSpmTY1wqhuf/RmjFxs1HZcNaTv8A+DlzgJYc7yQqFjP3ZA/z5RvJFuuIxggIYmgIFjaRYdA==", - "dependencies": { - "@react-aria/interactions": "^3.21.3", - "@react-aria/label": "^3.7.8", - "@react-aria/selection": "^3.18.1", - "@react-aria/utils": "^3.24.1", - "@react-stately/collections": "^3.10.7", - "@react-stately/list": "^3.10.5", - "@react-types/listbox": "^3.4.9", - "@react-types/shared": "^3.23.1", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.13.1.tgz", + "integrity": "sha512-b5Nu+5d5shJbxpy4s6OXvMlMzm+PVbs3L6CtoHlsKe8cAlSWD340vPHCOGYLwZApIBewepOBvRWgeAF8IDI04w==", + "dependencies": { + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.10", + "@react-aria/selection": "^3.19.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/collections": "^3.10.9", + "@react-stately/list": "^3.10.7", + "@react-types/listbox": "^3.5.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/live-announcer": { @@ -4525,237 +4524,237 @@ } }, "node_modules/@react-aria/menu": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.14.1.tgz", - "integrity": "sha512-BYliRb38uAzq05UOFcD5XkjA5foQoXRbcH3ZufBsc4kvh79BcP1PMW6KsXKGJ7dC/PJWUwCui6QL1kUg8PqMHA==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/overlays": "^3.22.1", - "@react-aria/selection": "^3.18.1", - "@react-aria/utils": "^3.24.1", - "@react-stately/collections": "^3.10.7", - "@react-stately/menu": "^3.7.1", - "@react-stately/tree": "^3.8.1", - "@react-types/button": "^3.9.4", - "@react-types/menu": "^3.9.9", - "@react-types/shared": "^3.23.1", + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.15.1.tgz", + "integrity": "sha512-ZBTMZiJ17j6t7epcsjd0joAzsMKO31KLJHPtWAEfk1JkBxrMoirISPN8O1CeK/uBX++VaWSrDZfFe1EjrOwKuA==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/collections": "^3.10.9", + "@react-stately/menu": "^3.8.1", + "@react-stately/tree": "^3.8.3", + "@react-types/button": "^3.9.6", + "@react-types/menu": "^3.9.11", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/meter": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.13.tgz", - "integrity": "sha512-oG6KvHQM3ri93XkYQkgEaMKSMO9KNDVpcW1MUqFfqyUXHFBRZRrJB4BTXMZ4nyjheFVQjVboU51fRwoLjOzThg==", + "version": "3.4.15", + "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.15.tgz", + "integrity": "sha512-OUAzgmfiyEvBF+h9NlG7s8jvrGNTqj/zAWyUWEh5FMEjKFrDfni6awwFoRs164QqmUvRBNC0/eKv3Ghd2GIkRA==", "dependencies": { - "@react-aria/progress": "^3.4.13", - "@react-types/meter": "^3.4.1", - "@react-types/shared": "^3.23.1", + "@react-aria/progress": "^3.4.15", + "@react-types/meter": "^3.4.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/numberfield": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.3.tgz", - "integrity": "sha512-QQ9ZTzBbRI8d9ksaBWm6YVXbgv+5zzUsdxVxwzJVXLznvivoORB8rpdFJzUEWVCo25lzoBxluCEPYtLOxP1B0w==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/spinbutton": "^3.6.5", - "@react-aria/textfield": "^3.14.5", - "@react-aria/utils": "^3.24.1", - "@react-stately/form": "^3.0.3", - "@react-stately/numberfield": "^3.9.3", - "@react-types/button": "^3.9.4", - "@react-types/numberfield": "^3.8.3", - "@react-types/shared": "^3.23.1", + "version": "3.11.5", + "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.5.tgz", + "integrity": "sha512-cfJzU7SWsksKiLjfubSj5lR18ebQ7IbYaMQZbxdpZSPOANHIiktaxjPK4Nz7cqZ+HZ/6tQEirpY0iqpLx35CSw==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/spinbutton": "^3.6.7", + "@react-aria/textfield": "^3.14.7", + "@react-aria/utils": "^3.25.1", + "@react-stately/form": "^3.0.5", + "@react-stately/numberfield": "^3.9.5", + "@react-types/button": "^3.9.6", + "@react-types/numberfield": "^3.8.5", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/overlays": { - "version": "3.22.1", - "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.22.1.tgz", - "integrity": "sha512-GHiFMWO4EQ6+j6b5QCnNoOYiyx1Gk8ZiwLzzglCI4q1NY5AG2EAmfU4Z1+Gtrf2S5Y0zHbumC7rs9GnPoGLUYg==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/ssr": "^3.9.4", - "@react-aria/utils": "^3.24.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-stately/overlays": "^3.6.7", - "@react-types/button": "^3.9.4", - "@react-types/overlays": "^3.8.7", - "@react-types/shared": "^3.23.1", + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.23.1.tgz", + "integrity": "sha512-qNV3pGThvRXjhdHCfqN9Eg4uD+nFm2DoK6d5e9LFd1+xCkKbT88afDBIcLmeG7fgfmukb1sNmzCJQJt8Svk54g==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/ssr": "^3.9.5", + "@react-aria/utils": "^3.25.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-stately/overlays": "^3.6.9", + "@react-types/button": "^3.9.6", + "@react-types/overlays": "^3.8.9", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/progress": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.13.tgz", - "integrity": "sha512-YBV9bOO5JzKvG8QCI0IAA00o6FczMgIDiK8Q9p5gKorFMatFUdRayxlbIPoYHMi+PguLil0jHgC7eOyaUcrZ0g==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/label": "^3.7.8", - "@react-aria/utils": "^3.24.1", - "@react-types/progress": "^3.5.4", - "@react-types/shared": "^3.23.1", + "version": "3.4.15", + "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.15.tgz", + "integrity": "sha512-wlx8pgEet3mlq5Skjy7yV1DfQiEg79tZtojpb5YGN2dIAH8sxClrKOSJRVce0fy9IXVCKrQxjQNXPNUIojK5Rg==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/label": "^3.7.10", + "@react-aria/utils": "^3.25.1", + "@react-types/progress": "^3.5.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/radio": { - "version": "3.10.4", - "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.4.tgz", - "integrity": "sha512-3fmoMcQtCpgjTwJReFjnvIE/C7zOZeCeWUn4JKDqz9s1ILYsC3Rk5zZ4q66tFn6v+IQnecrKT52wH6+hlVLwTA==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/form": "^3.0.5", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/label": "^3.7.8", - "@react-aria/utils": "^3.24.1", - "@react-stately/radio": "^3.10.4", - "@react-types/radio": "^3.8.1", - "@react-types/shared": "^3.23.1", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.6.tgz", + "integrity": "sha512-Cr7kiTUWw+HOEdFHztqrFlSXvwuzOCTMbwNkziTyc9fualIX6UDilykND2ctfBgkM4qH7SgQt+SxAIwTdevsKg==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/form": "^3.0.7", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.10", + "@react-aria/utils": "^3.25.1", + "@react-stately/radio": "^3.10.6", + "@react-types/radio": "^3.8.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/searchfield": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.7.5.tgz", - "integrity": "sha512-h1sMUOWjhevaKKUHab/luHbM6yiyeN57L4RxZU0IIc9Ww0h5Rp2GUuKZA3pcdPiExHje0aijcImL3wBHEbKAzw==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/textfield": "^3.14.5", - "@react-aria/utils": "^3.24.1", - "@react-stately/searchfield": "^3.5.3", - "@react-types/button": "^3.9.4", - "@react-types/searchfield": "^3.5.5", - "@react-types/shared": "^3.23.1", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.7.7.tgz", + "integrity": "sha512-2f087PCR8X5LYyLnvjCIOV27xjjTCkDFPnQaC7XSPCfzDYGM8utCR56JfZMqHnjcMnVNoiEg7EjSBBrh7I2bnQ==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/textfield": "^3.14.7", + "@react-aria/utils": "^3.25.1", + "@react-stately/searchfield": "^3.5.5", + "@react-types/button": "^3.9.6", + "@react-types/searchfield": "^3.5.7", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/select": { - "version": "3.14.5", - "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.14.5.tgz", - "integrity": "sha512-s8jixBuTUNdKWRHe2tIJqp55ORHeUObGMw1s7PQRRVrrHPdNSYseAOI9B2W7qpl3hKhvjJg40UW+45mcb1WKbw==", - "dependencies": { - "@react-aria/form": "^3.0.5", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/label": "^3.7.8", - "@react-aria/listbox": "^3.12.1", - "@react-aria/menu": "^3.14.1", - "@react-aria/selection": "^3.18.1", - "@react-aria/utils": "^3.24.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-stately/select": "^3.6.4", - "@react-types/button": "^3.9.4", - "@react-types/select": "^3.9.4", - "@react-types/shared": "^3.23.1", + "version": "3.14.7", + "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.14.7.tgz", + "integrity": "sha512-qZy5oX6P8SGrdv4bHb8iVMIVv+vLuo7UwOJtsQ1FUORIsZmBEz0RyfgYdzlueMcZNoQ9JgLYtrK2e0h6AmJOlg==", + "dependencies": { + "@react-aria/form": "^3.0.7", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.10", + "@react-aria/listbox": "^3.13.1", + "@react-aria/menu": "^3.15.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/utils": "^3.25.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-stately/select": "^3.6.6", + "@react-types/button": "^3.9.6", + "@react-types/select": "^3.9.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/selection": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.18.1.tgz", - "integrity": "sha512-GSqN2jX6lh7v+ldqhVjAXDcrWS3N4IsKXxO6L6Ygsye86Q9q9Mq9twWDWWu5IjHD6LoVZLUBCMO+ENGbOkyqeQ==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-stately/selection": "^3.15.1", - "@react-types/shared": "^3.23.1", + "version": "3.19.1", + "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.19.1.tgz", + "integrity": "sha512-mbExvq2Omi60sTWFGjwcNz1ja2P8VDsxWAqSypHRTyqXhtgqbv8V/v8Gp+7BmVPH1YHcbhztl6rvUZTDOSszzw==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/selection": "^3.16.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/separator": { - "version": "3.3.13", - "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.3.13.tgz", - "integrity": "sha512-hofA6JCPnAOqSE9vxnq7Dkazr7Kb2A0I5sR16fOG7ddjYRc/YEY5Nv7MWfKUGU0kNFHkgNjsDAILERtLechzeA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.4.1.tgz", + "integrity": "sha512-bZ+GQ936Y+WXAtsQjJdEMgYeqmqjhU90+wOlRGjmGdwf+/ht2yzBpeRuHEYUbE6F0iis/YoVc+b8ppAtPna/kA==", "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/slider": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.8.tgz", - "integrity": "sha512-MYvPcM0K8jxEJJicUK2+WxUkBIM/mquBxOTOSSIL3CszA80nXIGVnLlCUnQV3LOUzpWtabbWaZokSPtGgOgQOw==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/label": "^3.7.8", - "@react-aria/utils": "^3.24.1", - "@react-stately/slider": "^3.5.4", - "@react-types/shared": "^3.23.1", - "@react-types/slider": "^3.7.3", + "version": "3.7.10", + "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.10.tgz", + "integrity": "sha512-QmBn87sDkncS/uhcrH0MxUN7bcEo8cHYcWk+gk7mibdIpyxyVDPKh7v7ZsosmAJLzjS0yb2ec1/Q5Oldfg1k/A==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.10", + "@react-aria/utils": "^3.25.1", + "@react-stately/slider": "^3.5.6", + "@react-types/shared": "^3.24.1", + "@react-types/slider": "^3.7.5", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/spinbutton": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.5.tgz", - "integrity": "sha512-0aACBarF/Xr/7ixzjVBTQ0NBwwwsoGkf5v6AVFVMTC0uYMXHTALvRs+ULHjHMa5e/cX/aPlEvaVT7jfSs+Xy9Q==", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.7.tgz", + "integrity": "sha512-OCimp4yXoFIgh6WAMOls5DDDRDRO75ZFic3YA6wLWTRNHxo1Lj8S90i1A6pakY6bi4hdBCKmj4DnFSNKAw1iWg==", "dependencies": { - "@react-aria/i18n": "^3.11.1", + "@react-aria/i18n": "^3.12.1", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/utils": "^3.24.1", - "@react-types/button": "^3.9.4", - "@react-types/shared": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-types/button": "^3.9.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/ssr": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz", - "integrity": "sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.5.tgz", + "integrity": "sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==", "dependencies": { "@swc/helpers": "^0.5.0" }, @@ -4763,220 +4762,221 @@ "node": ">= 12" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/switch": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.4.tgz", - "integrity": "sha512-2nVqz4ZuJyof47IpGSt3oZRmp+EdS8wzeDYgf42WHQXrx4uEOk1mdLJ20+NnsYhj/2NHZsvXVrjBeKMjlMs+0w==", + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.6.tgz", + "integrity": "sha512-+dZOX1utODlx5dC90DtwnXd9nvln9HxMffBj/gmMT1/cD/RmXfjvymfjTsTMwvHhqCew9yfpvod0ZWwj3BkLGw==", "dependencies": { - "@react-aria/toggle": "^3.10.4", - "@react-stately/toggle": "^3.7.4", - "@react-types/switch": "^3.5.3", + "@react-aria/toggle": "^3.10.6", + "@react-stately/toggle": "^3.7.6", + "@react-types/shared": "^3.24.1", + "@react-types/switch": "^3.5.5", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/table": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.14.1.tgz", - "integrity": "sha512-WaPgQe4zQF5OaluO5rm+Y2nEoFR63vsLd4BT4yjK1uaFhKhDY2Zk+1SCVQvBLLKS4WK9dhP05nrNzT0vp/ZPOw==", + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.15.1.tgz", + "integrity": "sha512-jVDLxp6Y/9M6y45c1I6u6msJ9dBg2I7Cu/FlSaK6HthTpN23UXuGw1oWuAjbfqi31nVXHWBwjCZkGKTdMjLf5A==", "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/grid": "^3.9.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", + "@react-aria/focus": "^3.18.1", + "@react-aria/grid": "^3.10.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/utils": "^3.24.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-stately/collections": "^3.10.7", + "@react-aria/utils": "^3.25.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-stately/collections": "^3.10.9", "@react-stately/flags": "^3.0.3", - "@react-stately/table": "^3.11.8", - "@react-stately/virtualizer": "^3.7.1", - "@react-types/checkbox": "^3.8.1", - "@react-types/grid": "^3.2.6", - "@react-types/shared": "^3.23.1", - "@react-types/table": "^3.9.5", + "@react-stately/table": "^3.12.1", + "@react-types/checkbox": "^3.8.3", + "@react-types/grid": "^3.2.8", + "@react-types/shared": "^3.24.1", + "@react-types/table": "^3.10.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/tabs": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.1.tgz", - "integrity": "sha512-S5v/0sRcOaSXaJYZuuy1ZVzYc7JD4sDyseG1133GjyuNjJOFHgoWMb+b4uxNIJbZxnLgynn/ZDBZSO+qU+fIxw==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/selection": "^3.18.1", - "@react-aria/utils": "^3.24.1", - "@react-stately/tabs": "^3.6.6", - "@react-types/shared": "^3.23.1", - "@react-types/tabs": "^3.3.7", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.3.tgz", + "integrity": "sha512-J1KOCdx4eSyMMeNCvO8BIz8E8xez12B+cYbM4BbJzWlcfMboGYUnM0lvI8QSpFPa/H9LkAhp7BJnl9IZeIBzoA==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/tabs": "^3.6.8", + "@react-types/shared": "^3.24.1", + "@react-types/tabs": "^3.3.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/tag": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.1.tgz", - "integrity": "sha512-gcIGPYZ2OBwMT4IHnlczEezKlxr0KRPL/mSfm2Q91GE027ZGOJnqusH9az6DX1qxrQx8x3vRdqYT2KmuefkrBQ==", - "dependencies": { - "@react-aria/gridlist": "^3.8.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/label": "^3.7.8", - "@react-aria/selection": "^3.18.1", - "@react-aria/utils": "^3.24.1", - "@react-stately/list": "^3.10.5", - "@react-types/button": "^3.9.4", - "@react-types/shared": "^3.23.1", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.3.tgz", + "integrity": "sha512-BqXKazX9YHvt6+qzGTu770V0FqGVefzz03hmnV2IVb+zYchXBv3WYbWVy46s/D5zTePOAXdpitQHxqy5rh+hgw==", + "dependencies": { + "@react-aria/gridlist": "^3.9.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.10", + "@react-aria/selection": "^3.19.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/list": "^3.10.7", + "@react-types/button": "^3.9.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/textfield": { - "version": "3.14.5", - "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.5.tgz", - "integrity": "sha512-hj7H+66BjB1iTKKaFXwSZBZg88YT+wZboEXZ0DNdQB2ytzoz/g045wBItUuNi4ZjXI3P+0AOZznVMYadWBAmiA==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/form": "^3.0.5", - "@react-aria/label": "^3.7.8", - "@react-aria/utils": "^3.24.1", - "@react-stately/form": "^3.0.3", - "@react-stately/utils": "^3.10.1", - "@react-types/shared": "^3.23.1", - "@react-types/textfield": "^3.9.3", + "version": "3.14.7", + "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.7.tgz", + "integrity": "sha512-1cWCG6vkjlwJuRTXKbKl9P0Q/0Li5pnMafZqDDWfDOlkS5dFGxYG6QFfoaYp7N6XMoNkXiculnCssfrQ+8hWgA==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/form": "^3.0.7", + "@react-aria/label": "^3.7.10", + "@react-aria/utils": "^3.25.1", + "@react-stately/form": "^3.0.5", + "@react-stately/utils": "^3.10.2", + "@react-types/shared": "^3.24.1", + "@react-types/textfield": "^3.9.5", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/toggle": { - "version": "3.10.4", - "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.4.tgz", - "integrity": "sha512-bRk+CdB8QzrSyGNjENXiTWxfzYKRw753iwQXsEAU7agPCUdB8cZJyrhbaUoD0rwczzTp2zDbZ9rRbUPdsBE2YQ==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-stately/toggle": "^3.7.4", - "@react-types/checkbox": "^3.8.1", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.6.tgz", + "integrity": "sha512-AGlbtB1b8grrtjbiW5Au0LKYzxR83RHbHhaUkFwajyYRGyuEzr3Y03OiveoPB+DayA8Gz3H1ZVmW++8JZQOWHw==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/toggle": "^3.7.6", + "@react-types/checkbox": "^3.8.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/toolbar": { - "version": "3.0.0-beta.5", - "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.5.tgz", - "integrity": "sha512-c8spY7aeLI6L+ygdXvEbAzaT41vExsxZ1Ld0t7BB+6iEF3nyBNJHshjkgdR7nv8FLgNk0no4tj0GTq4Jj4UqHQ==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", + "version": "3.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.7.tgz", + "integrity": "sha512-PKaXD2qiWcVOn/bX07ipamTc6OlqypqcQRGG7WUL0ZXWfV6AfL7GFPS1B2Jh7Etetq68Ynyuo6R4jT4Jypsjdg==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/tooltip": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.4.tgz", - "integrity": "sha512-+XRx4HlLYqWY3fB8Z60bQi/rbWDIGlFUtXYbtoa1J+EyRWfhpvsYImP8qeeNO/vgjUtDy1j9oKa8p6App9mBMQ==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-stately/tooltip": "^3.4.9", - "@react-types/shared": "^3.23.1", - "@react-types/tooltip": "^3.4.9", + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.6.tgz", + "integrity": "sha512-JvRAMTcMju/KBOtISjVKKtIDzG3J1r6xK+mZTvu6ArM7DdeMBM5A8Lwk0bJ8dhr+YybiM9rR3hoZv3/E7IIYVw==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/tooltip": "^3.4.11", + "@react-types/shared": "^3.24.1", + "@react-types/tooltip": "^3.4.11", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/tree": { - "version": "3.0.0-alpha.1", - "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.0.0-alpha.1.tgz", - "integrity": "sha512-CucyeJ4VeAvWO5UJHt/l9JO65CVtsOVUctMOVNCQS77Isqp3olX9pvfD3LXt8fD5Ph2g0Q/b7siVpX5ieVB32g==", - "dependencies": { - "@react-aria/gridlist": "^3.8.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/selection": "^3.18.1", - "@react-aria/utils": "^3.24.1", - "@react-stately/tree": "^3.8.1", - "@react-types/button": "^3.9.4", - "@react-types/shared": "^3.23.1", + "version": "3.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.0.0-alpha.3.tgz", + "integrity": "sha512-o/9B+PVSUYxDM1KxQ/Pl1CytPtIagyidmasd10266hWfwzvPA0ZyakBwIEFj+ROnr9buAdP+A4sOTRo+a6g+YQ==", + "dependencies": { + "@react-aria/gridlist": "^3.9.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/tree": "^3.8.3", + "@react-types/button": "^3.9.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/utils": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.24.1.tgz", - "integrity": "sha512-O3s9qhPMd6n42x9sKeJ3lhu5V1Tlnzhu6Yk8QOvDuXf7UGuUjXf9mzfHJt1dYzID4l9Fwm8toczBzPM9t0jc8Q==", + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.25.1.tgz", + "integrity": "sha512-5Uj864e7T5+yj78ZfLnfHqmypLiqW2mN+nsdslog2z5ssunTqjolVeM15ootXskjISlZ7MojLpq97kIC4nlnAw==", "dependencies": { - "@react-aria/ssr": "^3.9.4", - "@react-stately/utils": "^3.10.1", - "@react-types/shared": "^3.23.1", + "@react-aria/ssr": "^3.9.5", + "@react-stately/utils": "^3.10.2", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/virtualizer": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-3.10.1.tgz", - "integrity": "sha512-y34w+n/B3nwwj18QHIZlkNj5Fn2rt5CbQE4BBWAM8jYZ5ypwF77i2toxhGTuk1Oo1/hgTX7JYIgDIAQbNraBcg==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-stately/virtualizer": "^3.7.1", - "@react-types/shared": "^3.23.1", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-4.0.1.tgz", + "integrity": "sha512-JZ6X0l38ZwBU/JgeLwkDA8mknRxqO1nYSVaPZHgOg8fd9BzMRWBjse7VW+Uf09P0uAEFElwlB+RY8UDx+W/Fmg==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-stately/virtualizer": "^4.0.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-aria/visually-hidden": { - "version": "3.8.12", - "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.12.tgz", - "integrity": "sha512-Bawm+2Cmw3Xrlr7ARzl2RLtKh0lNUdJ0eNqzWcyx4c0VHUAWtThmH5l+HRqFUGzzutFZVo89SAy40BAbd0gjVw==", + "version": "3.8.14", + "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.14.tgz", + "integrity": "sha512-DV3yagbAgO4ywQTq6D/AxcIaTC8c77r/SxlIMhQBMQ6vScJWTCh6zFG55wmLe3NKqvRrowv1OstlmYfZQ4v/XA==", "dependencies": { - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-google-maps/api": { @@ -5007,1114 +5007,1118 @@ "integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw==" }, "node_modules/@react-spectrum/actionbar": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/@react-spectrum/actionbar/-/actionbar-3.4.5.tgz", - "integrity": "sha512-9+b3B5he/zwyk+1pHc5l8/q6mBy+zKkphha2kBScbj/2XRHTwwlcamBJMANMYfVirQT9UP5FHGhHV6OiRgZLrA==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/actionbar/-/actionbar-3.5.1.tgz", + "integrity": "sha512-yPqUjIbRaUPZtips+FXYNCNv5Yyqcd5MjN238C6kUXoEOMNRfXiO3QLO7JRMywwi4EWPz4GjH+329/VoV+iXsw==", "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/actiongroup": "^3.10.5", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/overlays": "^5.6.1", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-types/actionbar": "^3.1.7", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/actiongroup": "^3.10.7", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/overlays": "^5.6.3", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-types/actionbar": "^3.1.9", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/actiongroup": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/@react-spectrum/actiongroup/-/actiongroup-3.10.5.tgz", - "integrity": "sha512-KHSuZvCD5XyOA4wz2iu85JQem2Y01pniWTfhzGLPfJG+1OdOCt+C0mO/jU0DL4NM6UwzdLy4JfvUij/xBsLrRw==", - "dependencies": { - "@react-aria/actiongroup": "^3.7.5", - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/menu": "^3.19.1", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/tooltip": "^3.6.7", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-stately/list": "^3.10.5", - "@react-types/actiongroup": "^3.4.9", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", - "@spectrum-icons/workflow": "^4.2.12", + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@react-spectrum/actiongroup/-/actiongroup-3.10.7.tgz", + "integrity": "sha512-IJqr+TOEZRPWJ+9OSGZvZBPQZG/mp++2awKIVPJzOCWOWu81oIu8fMRgnuQev+RoAJWKBXR1sh5EPMmLJHSzqA==", + "dependencies": { + "@react-aria/actiongroup": "^3.7.7", + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/menu": "^3.20.1", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/tooltip": "^3.6.9", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-stately/list": "^3.10.7", + "@react-types/actiongroup": "^3.4.11", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", + "@spectrum-icons/workflow": "^4.2.14", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.2.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/avatar": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@react-spectrum/avatar/-/avatar-3.0.12.tgz", - "integrity": "sha512-H5dZG+mPiSHlST2TBMfMR7mOf+g5C0i9Q2+aMMQ8khphXLFL4fj5GqxgEE7Mi5efS+raofwXJ/dM+AedsSl6WQ==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/avatar": "^3.0.7", - "@react-types/shared": "^3.23.1", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@react-spectrum/avatar/-/avatar-3.0.14.tgz", + "integrity": "sha512-QQRRQEO4mHdW9UtXomEJw9gAfOliqhMaYMJYWlwytCAipErrllae7U9VK0AaECokfNBib3Klhp8b/4VtLKr+dw==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/avatar": "^3.0.9", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.2.1", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/badge": { - "version": "3.1.13", - "resolved": "https://registry.npmjs.org/@react-spectrum/badge/-/badge-3.1.13.tgz", - "integrity": "sha512-zfsmbw3hxYWxuySQZTMNkxI5vD1XktHNIBqDUYNaDu8A+GVaORI9pcrua4T2YXyQrw1hYXbqVAmeISJYURajjA==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-types/badge": "^3.1.9", - "@react-types/shared": "^3.23.1", + "version": "3.1.15", + "resolved": "https://registry.npmjs.org/@react-spectrum/badge/-/badge-3.1.15.tgz", + "integrity": "sha512-fCjEXw5ej0GzXTk7g3PkhPKj0sS1mQ6XtrhGIwM1g78AYdv0+no7Zsew1ojRQJpOhWDqJPj2QNRJplouGTI3uA==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-types/badge": "^3.1.11", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/breadcrumbs": { - "version": "3.9.7", - "resolved": "https://registry.npmjs.org/@react-spectrum/breadcrumbs/-/breadcrumbs-3.9.7.tgz", - "integrity": "sha512-1wA9cgSugaplYmT4z/WiUAZsOcXPWN+8sx43Wc5foS3qUSOLpW4+43sjDTVmzVlbXYuZ4byxf1nrXZNEqCWZXA==", - "dependencies": { - "@react-aria/breadcrumbs": "^3.5.13", - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/menu": "^3.19.1", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-types/breadcrumbs": "^3.7.5", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/@react-spectrum/breadcrumbs/-/breadcrumbs-3.9.9.tgz", + "integrity": "sha512-JQ9OGQJTV68ZxCc7cNNa1ob5G+AAXYD3BjAd81ZfUwxjzEnHPXu/FJWHC7H8zaCGno6Pqq8nhgBHNR1TBiQqGw==", + "dependencies": { + "@react-aria/breadcrumbs": "^3.5.15", + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/menu": "^3.20.1", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-types/breadcrumbs": "^3.7.7", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/button": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/@react-spectrum/button/-/button-3.16.4.tgz", - "integrity": "sha512-ksPZkmhkz8fJuu+cC9GM5e1pJ0d2sWmkU9sqKn5SNfWh9ngemgvShtkqkuQoz6ThH+MI3n/n4JhFd+UhJ/lILA==", - "dependencies": { - "@react-aria/button": "^3.9.5", - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/progress": "^3.7.7", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/toggle": "^3.7.4", - "@react-types/button": "^3.9.4", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.16.6", + "resolved": "https://registry.npmjs.org/@react-spectrum/button/-/button-3.16.6.tgz", + "integrity": "sha512-dNJldfq9xQ1pN29km0+vTmhlmRpx8ZXF5K/1edvdLpPtpI3a6iJIBxGh8v4uQFNaAN3Er7mdHdvguHkPsnTD3w==", + "dependencies": { + "@react-aria/button": "^3.9.7", + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/progress": "^3.7.9", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/toggle": "^3.7.6", + "@react-types/button": "^3.9.6", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/buttongroup": { - "version": "3.6.13", - "resolved": "https://registry.npmjs.org/@react-spectrum/buttongroup/-/buttongroup-3.6.13.tgz", - "integrity": "sha512-QUNTtDMiY/ydrpUYq8fO0kkssdnTEJsIxlfhbQa3ZEpEObjgt9XbAehNKPelWATwLNQ/gY8o21m9GT1m7J/8zg==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/buttongroup": "^3.3.9", - "@react-types/shared": "^3.23.1", + "version": "3.6.15", + "resolved": "https://registry.npmjs.org/@react-spectrum/buttongroup/-/buttongroup-3.6.15.tgz", + "integrity": "sha512-QelfmkrH1bWDGTJyVRQxOVSJsn1dv3aNGlgd3u9HvBDQyZItRl+qiflOCZnrtPgX7SBUBVxGooW+3/AunIBkrw==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/buttongroup": "^3.3.11", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/calendar": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/@react-spectrum/calendar/-/calendar-3.4.9.tgz", - "integrity": "sha512-5546bmMQ/v3dscTDFx0llEQ3jA23vkcjbiY7hIad5a9bpXHPQSuIeREelFPtsVUzsD3f3v2BL2nDAt6SPLVqCA==", - "dependencies": { - "@internationalized/date": "^3.5.4", - "@react-aria/calendar": "^3.5.8", - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/calendar": "^3.5.1", - "@react-types/button": "^3.9.4", - "@react-types/calendar": "^3.4.6", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@react-spectrum/calendar/-/calendar-3.4.11.tgz", + "integrity": "sha512-NZZvdWDOhkNphUa4if1gM4x+tUDZb7fiMoTjp0/RSN2VaBl8Z5tt6R5hP9IAWvjfyPH8rv2zI40yO6ts/QCgcg==", + "dependencies": { + "@internationalized/date": "^3.5.5", + "@react-aria/calendar": "^3.5.10", + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/calendar": "^3.5.3", + "@react-types/button": "^3.9.6", + "@react-types/calendar": "^3.4.8", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/checkbox": { - "version": "3.9.6", - "resolved": "https://registry.npmjs.org/@react-spectrum/checkbox/-/checkbox-3.9.6.tgz", - "integrity": "sha512-aU4bDFwaiC2hpqOFv9vbUw20V6VlMO7pn1P8Q/qUfNxWVzPY03rJC0Gqcq8NQy2zofmm4tDBJKKOF1F4amGTyw==", - "dependencies": { - "@react-aria/checkbox": "^3.14.3", - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/checkbox": "^3.6.5", - "@react-stately/toggle": "^3.7.4", - "@react-types/checkbox": "^3.8.1", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.9.8", + "resolved": "https://registry.npmjs.org/@react-spectrum/checkbox/-/checkbox-3.9.8.tgz", + "integrity": "sha512-qOwzemGpa+Qj9ZmwDhFtCd0OkqCY+c6yw8iggCfA0A+jrreSexkOAtUo6JIGg6Vsh44oqM44PKKMgvbpW1LXJw==", + "dependencies": { + "@react-aria/checkbox": "^3.14.5", + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/checkbox": "^3.6.7", + "@react-stately/toggle": "^3.7.6", + "@react-types/checkbox": "^3.8.3", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0", - "react-aria-components": "^1.2.1" + "react-aria-components": "^1.3.1" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/combobox": { - "version": "3.12.5", - "resolved": "https://registry.npmjs.org/@react-spectrum/combobox/-/combobox-3.12.5.tgz", - "integrity": "sha512-S6TA8FrPm0ibLkeulki2S0DsUqy/hEcTVTvvic7qIRyURN/J+DQMQDWmy+Zzz9mxJr8qdJAoWSArBVWtxKhMKg==", - "dependencies": { - "@react-aria/button": "^3.9.5", - "@react-aria/combobox": "^3.9.1", - "@react-aria/dialog": "^3.5.14", - "@react-aria/focus": "^3.17.1", - "@react-aria/form": "^3.0.5", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/label": "^3.7.8", - "@react-aria/overlays": "^3.22.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/listbox": "^3.12.9", - "@react-spectrum/overlays": "^5.6.1", - "@react-spectrum/progress": "^3.7.7", - "@react-spectrum/textfield": "^3.12.1", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-stately/combobox": "^3.8.4", - "@react-types/button": "^3.9.4", - "@react-types/combobox": "^3.11.1", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/combobox/-/combobox-3.13.1.tgz", + "integrity": "sha512-p6Wt8TCvaE/ljDpRZQEuGjxvFkXiIwElz3Fq/qoV6qhdeXbm8GxEwkfzpcBk2SgvjVAAWgQYcmUJVav+R5J0/g==", + "dependencies": { + "@react-aria/button": "^3.9.7", + "@react-aria/combobox": "^3.10.1", + "@react-aria/dialog": "^3.5.16", + "@react-aria/focus": "^3.18.1", + "@react-aria/form": "^3.0.7", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.10", + "@react-aria/overlays": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/listbox": "^3.13.1", + "@react-spectrum/overlays": "^5.6.3", + "@react-spectrum/progress": "^3.7.9", + "@react-spectrum/textfield": "^3.12.3", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-stately/combobox": "^3.9.1", + "@react-types/button": "^3.9.6", + "@react-types/combobox": "^3.12.1", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/contextualhelp": { - "version": "3.6.11", - "resolved": "https://registry.npmjs.org/@react-spectrum/contextualhelp/-/contextualhelp-3.6.11.tgz", - "integrity": "sha512-mQimyXdwXyZWFWO/7BdHZ46YzCQThjnHGGMmlv2y+YfqaOqoP3UTQb4D6noSbV1M6zKJgMq5timhVo81Sujk9Q==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/dialog": "^3.8.11", - "@react-spectrum/utils": "^3.11.7", - "@react-types/contextualhelp": "^3.2.10", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/workflow": "^4.2.12", + "version": "3.6.13", + "resolved": "https://registry.npmjs.org/@react-spectrum/contextualhelp/-/contextualhelp-3.6.13.tgz", + "integrity": "sha512-tSY2l9v+kTvMfL6Alu8AoDSqXLCX0lqi8wuQxOVOHvbKEYf9BnRdlHQ5ILLHpt9eFxriVnsQcIbR6sGdoOi2pw==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/dialog": "^3.8.13", + "@react-spectrum/utils": "^3.11.9", + "@react-types/contextualhelp": "^3.2.12", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/workflow": "^4.2.14", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/datepicker": { - "version": "3.9.6", - "resolved": "https://registry.npmjs.org/@react-spectrum/datepicker/-/datepicker-3.9.6.tgz", - "integrity": "sha512-MeLle/V2t3dBe7wq/qkc39hJyV6NTZncCZnBfPHnTcLXeZl8sfTf4rt11JS3Y4JOOtM3jiuw1oMpZ7wv+h6hOA==", - "dependencies": { - "@internationalized/date": "^3.5.4", - "@react-aria/datepicker": "^3.10.1", - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/calendar": "^3.4.9", - "@react-spectrum/dialog": "^3.8.11", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/utils": "^3.11.7", - "@react-spectrum/view": "^3.6.10", - "@react-stately/datepicker": "^3.9.4", - "@react-types/datepicker": "^3.7.4", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", - "@spectrum-icons/workflow": "^4.2.12", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/datepicker/-/datepicker-3.10.1.tgz", + "integrity": "sha512-+cmnSGSMrMiO94q1KOM3rCIUeFQouwJ8SbECxMQQDAGINHbhQxlceW4sKl0SldpXzS2yVINKj17rjFAbOvxEHw==", + "dependencies": { + "@internationalized/date": "^3.5.5", + "@react-aria/datepicker": "^3.11.1", + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/calendar": "^3.4.11", + "@react-spectrum/dialog": "^3.8.13", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/utils": "^3.11.9", + "@react-spectrum/view": "^3.6.12", + "@react-stately/datepicker": "^3.10.1", + "@react-types/datepicker": "^3.8.1", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", + "@spectrum-icons/workflow": "^4.2.14", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/dialog": { - "version": "3.8.11", - "resolved": "https://registry.npmjs.org/@react-spectrum/dialog/-/dialog-3.8.11.tgz", - "integrity": "sha512-/ng49paipA3MHC5nVbfDlZL6QXFJWCrSDgQ4fXon5q6gB+94d2DvkZ+CvnLZ5oo0Bpkws/vT3jxcG0hsBz1f6g==", - "dependencies": { - "@react-aria/dialog": "^3.5.14", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/overlays": "^3.22.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/buttongroup": "^3.6.13", - "@react-spectrum/divider": "^3.5.13", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/overlays": "^5.6.1", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-spectrum/view": "^3.6.10", - "@react-stately/overlays": "^3.6.7", - "@react-types/button": "^3.9.4", - "@react-types/dialog": "^3.5.10", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.8.13", + "resolved": "https://registry.npmjs.org/@react-spectrum/dialog/-/dialog-3.8.13.tgz", + "integrity": "sha512-BbmBKRVcSOZhV01xCl/MJTG2D+dctDMs/8/SOpM//BXzvlDIGXHRVJiYcPKCGe4Egt+6mNCjY/xvvfqxOXRNhw==", + "dependencies": { + "@react-aria/dialog": "^3.5.16", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/buttongroup": "^3.6.15", + "@react-spectrum/divider": "^3.5.15", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/overlays": "^5.6.3", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-spectrum/view": "^3.6.12", + "@react-stately/overlays": "^3.6.9", + "@react-types/button": "^3.9.6", + "@react-types/dialog": "^3.5.12", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/divider": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@react-spectrum/divider/-/divider-3.5.13.tgz", - "integrity": "sha512-7LoOTj+qs3yTBZiWudgU5TpzLREApMt0rwzalyq9ORRQrE8C0YXUxlSLPizyUmQeP4Rj8p3lCdUNWAe1cAn1tQ==", - "dependencies": { - "@react-aria/separator": "^3.3.13", - "@react-spectrum/utils": "^3.11.7", - "@react-types/divider": "^3.3.9", - "@react-types/shared": "^3.23.1", + "version": "3.5.15", + "resolved": "https://registry.npmjs.org/@react-spectrum/divider/-/divider-3.5.15.tgz", + "integrity": "sha512-bL0pwPup9VL7W4faxvHonChx8eEbBUhX67/V47wR21q4PmnuP3bOVZ6U3qqCbhA+R246zsyxlBouX3mL6QuKvg==", + "dependencies": { + "@react-aria/separator": "^3.4.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/divider": "^3.3.11", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/dnd": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/@react-spectrum/dnd/-/dnd-3.3.10.tgz", - "integrity": "sha512-Qp+Fp6BnMgrp5G18IAcbEUetf2YWelRugYJr8TH8h236n8lariyUpri1Mj604DV/UqNoK6f6k6ocY8JBmvOd9Q==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/dnd/-/dnd-3.4.1.tgz", + "integrity": "sha512-sg99ExYMmm5sb8EWsTJRUK6efb41t+s7Ih19M/iamfhwSaypAZaMbfP1zjtFbUqC9GtEALteZpt5OqVRkiKlvQ==", "dependencies": { - "@react-aria/dnd": "^3.6.1", - "@react-stately/dnd": "^3.3.1", - "@react-types/shared": "^3.23.1", + "@react-aria/dnd": "^3.7.1", + "@react-stately/dnd": "^3.4.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/dropzone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/dropzone/-/dropzone-3.0.1.tgz", - "integrity": "sha512-8hEu6mF1ExJMc+Pv5lk3YHz3yZcRy4FkjKgBMXWWn8kxT2DEIK5hONspECBmlsNtUHuk1QQFFSISMGgsMZFQVw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@react-spectrum/dropzone/-/dropzone-3.0.3.tgz", + "integrity": "sha512-YtX4W9RtAaQwk2RbLmW/GjJ9DimqwGUSYaWAb9+LaoMBiUvEtJsy7m22frtph8wp62crQR1S/u16sTnqq8tlzQ==", "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/shared": "^3.23.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", - "react-aria-components": "^1.2.1" + "react-aria-components": "^1.3.1" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/filetrigger": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/filetrigger/-/filetrigger-3.0.1.tgz", - "integrity": "sha512-9PfhjeGdHjyumlzdvrFNumKnGeaK41kYragnDMSD3KNH0XWu2kVUTB7eUbA9d6FLL/+g8tyPx+wDo0ZJW79Fpg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@react-spectrum/filetrigger/-/filetrigger-3.0.3.tgz", + "integrity": "sha512-6bWa7ENBaj/oM0JkXd2Q7fzZg/gL23fitK1nVyRfFw9BHfgqCSZwMM2exBJjtX+Az6II4LjhY9cSbL28i9EsGw==", "dependencies": { "@swc/helpers": "^0.5.0", - "react-aria-components": "^1.2.1" + "react-aria-components": "^1.3.1" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/form": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/@react-spectrum/form/-/form-3.7.6.tgz", - "integrity": "sha512-uh/r3d3haWGjdxh++HCCbezWRiw7PGDStvOHEVLCVz/cN0lrUb77dwx5E4jMvY+oLkaBv05R3UtdMxNdXV1DZQ==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/form": "^3.0.3", - "@react-types/form": "^3.7.4", - "@react-types/shared": "^3.23.1", + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/@react-spectrum/form/-/form-3.7.8.tgz", + "integrity": "sha512-FAsSOhltgBCnqLXsdTeYaDUQo7TU9GT/byCgKs0+FK9RKPQMtwYRCHDmoEOoWVhIlH6jiOTT6UXxRP+uGJiSAg==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/form": "^3.0.5", + "@react-types/form": "^3.7.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/icon": { - "version": "3.7.13", - "resolved": "https://registry.npmjs.org/@react-spectrum/icon/-/icon-3.7.13.tgz", - "integrity": "sha512-hbd1OZ2UOOZ807zkU/ay8TWQOSnB56cj9HHm3FzUBjpTwpt849Pvk4TBO5K2SAmuQi4gslmvFGmd8BoOEoEcjg==", + "version": "3.7.15", + "resolved": "https://registry.npmjs.org/@react-spectrum/icon/-/icon-3.7.15.tgz", + "integrity": "sha512-b8VouL33orbT6wUxsgvmaPrNOXftagVE4BNLbOFhBik98ycy8H+KajCII5ZnTM8O4+9f9lDyO8D0R8n5VeOaiA==", "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/shared": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/illustratedmessage": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/illustratedmessage/-/illustratedmessage-3.5.1.tgz", - "integrity": "sha512-HpTueLW3duV1TE3sYw5WeBaGECqS0RVEXr2UaXDXSLteY238Oc7prli2qPk2xaGeRKgh97jsfySDBOvedCuZJQ==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/utils": "^3.11.7", - "@react-types/illustratedmessage": "^3.3.9", - "@react-types/shared": "^3.23.1", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@react-spectrum/illustratedmessage/-/illustratedmessage-3.5.3.tgz", + "integrity": "sha512-2f5P9s8TWLRWDOdk84aqWkyNhgT8PZfAdbMLpzrzra0QM5FYwABbMDcjtVaprFq55KqPk9iLwGSb0Avk3T+aDA==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/utils": "^3.11.9", + "@react-types/illustratedmessage": "^3.3.11", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/image": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/image/-/image-3.5.1.tgz", - "integrity": "sha512-MFl2WkMT224L4v1M9n4ZGkkXhBqecQ6uWZfxHBURrTXFMgPq5sxWY7qw42pc3mAX339kNiLZXTCTA5mKyiqxnQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@react-spectrum/image/-/image-3.5.3.tgz", + "integrity": "sha512-8ZUkWXH9tnR+ZnxEeMEflo/nMRNFn60VpXOt9hfJlXbhwUKD4eO3TFA14QQXr407XSZwt9d7CGkT4urw4lxtmA==", "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/image": "^3.4.1", - "@react-types/shared": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/image": "^3.4.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/inlinealert": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@react-spectrum/inlinealert/-/inlinealert-3.2.5.tgz", - "integrity": "sha512-D9EF8pIQME6GHpvk7HR8/Qr3g79l78EsvczL0wGOzdcMt+LoV9F6RNJSobrI+dgzX0RcbqRyWsdCixboFrfefg==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/utils": "^3.11.7", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@react-spectrum/inlinealert/-/inlinealert-3.2.7.tgz", + "integrity": "sha512-jWO7gNx3rulFA0lkvcv/czNdGZRmG77Jo8aAe2ku/96WvJc9h4ZNyTVu7F+8W5iR+I1Ige1D6UHB9dJCTZlfHQ==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/utils": "^3.11.9", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/label": { - "version": "3.16.6", - "resolved": "https://registry.npmjs.org/@react-spectrum/label/-/label-3.16.6.tgz", - "integrity": "sha512-RF1YqQOKpDYqnSxM+TK/4gZGBsoKjfaZYsOvjya90LvUO8/2Va8Ux0bwHlqtOxu46yjxPLflpt0u9rl9ce+Ubg==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/utils": "^3.11.7", - "@react-types/label": "^3.9.3", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.16.8", + "resolved": "https://registry.npmjs.org/@react-spectrum/label/-/label-3.16.8.tgz", + "integrity": "sha512-2qIju/PZNzwTviR1OiiT8SR+aZdkBCI+S0GfT/FABjkmxJvm+lWxIhc+okr9CRGgEzCYnq9b3S5PfPIupLh8ew==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/utils": "^3.11.9", + "@react-types/label": "^3.9.5", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/labeledvalue": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/@react-spectrum/labeledvalue/-/labeledvalue-3.1.14.tgz", - "integrity": "sha512-JeZHCRRmSPShgOozHs31+e0NnN4S3+SP0NpPGFUo0itPHvOcJSV9aoRCefdMTdXbUupIi5h1EM5Ty0owdy8y0w==", - "dependencies": { - "@internationalized/date": "^3.5.4", - "@react-aria/i18n": "^3.11.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/utils": "^3.11.7", - "@react-types/shared": "^3.23.1", + "version": "3.1.16", + "resolved": "https://registry.npmjs.org/@react-spectrum/labeledvalue/-/labeledvalue-3.1.16.tgz", + "integrity": "sha512-ZzrGErsGvnndVpL9MMdanYpmL4I97enWU7tQ6w17TUvmb6pG4VIKUVepPMpw9sn9VcEc44dY56nDqH9m+uR35g==", + "dependencies": { + "@internationalized/date": "^3.5.5", + "@react-aria/i18n": "^3.12.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/utils": "^3.11.9", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/layout": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/@react-spectrum/layout/-/layout-3.6.5.tgz", - "integrity": "sha512-kl/vZue7ZQZtkypPeOPZ3WENk4Mn9aYsjSBFZP+3GVRGPi0GBlhVOSicraio7UD3oGz1Xkhy5WZg01s3zQC0zg==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/layout": "^3.3.15", - "@react-types/shared": "^3.23.1", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/@react-spectrum/layout/-/layout-3.6.7.tgz", + "integrity": "sha512-EheC/J99qt2GpVq05UqPk9iH9PImH9SHXmikNqf/pckKH2Xh/EUY9t5ab+oOYq0N9JbdLp9a38AvuL9KyTJAFQ==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/layout": "^3.3.17", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/link": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/@react-spectrum/link/-/link-3.6.7.tgz", - "integrity": "sha512-g9yWHXO8OdoOnUH0xAIek5wDHDi0gYmEL3hqqKwzfMvkmQQCQjVS+D/9IlkxKT5LaumUiHdHDiA2PL1voPUh0g==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/link": "^3.7.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/link": "^3.5.5", + "version": "3.6.9", + "resolved": "https://registry.npmjs.org/@react-spectrum/link/-/link-3.6.9.tgz", + "integrity": "sha512-eZDGvH8R1GKQVnlk5h1T6utKO/i3xFEhqC8cI/B5Pwh3WwVB9fSwUljzf9Cb3dqfSMTFXH3GrPmF1XVfRIliFg==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/link": "^3.7.3", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/link": "^3.5.7", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/list": { - "version": "3.7.10", - "resolved": "https://registry.npmjs.org/@react-spectrum/list/-/list-3.7.10.tgz", - "integrity": "sha512-UxS+pXgJGaTeLP+KQdq7IQsaJN1tq6tpqFXFKXdrXGnLZPd9GtBT3zYP2Rnb9r/6Vm67D+pewF6tVKLzctE1sw==", - "dependencies": { - "@react-aria/button": "^3.9.5", - "@react-aria/focus": "^3.17.1", - "@react-aria/gridlist": "^3.8.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/utils": "^3.24.1", - "@react-aria/virtualizer": "^3.10.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-spectrum/checkbox": "^3.9.6", - "@react-spectrum/dnd": "^3.3.10", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/progress": "^3.7.7", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-stately/layout": "^3.13.9", - "@react-stately/list": "^3.10.5", - "@react-types/grid": "^3.2.6", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/list/-/list-3.8.1.tgz", + "integrity": "sha512-8gSq7cMtVwrPA7DMCg2b9PEYcT8IAmpsKREtAWGOZtzT0xgm8xdEwMUAbhbiDmE1Nbuupe+0vDl2XkUjlrdmXw==", + "dependencies": { + "@react-aria/button": "^3.9.7", + "@react-aria/focus": "^3.18.1", + "@react-aria/gridlist": "^3.9.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/utils": "^3.25.1", + "@react-aria/virtualizer": "^4.0.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-spectrum/checkbox": "^3.9.8", + "@react-spectrum/dnd": "^3.4.1", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/progress": "^3.7.9", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-stately/layout": "^4.0.1", + "@react-stately/list": "^3.10.7", + "@react-stately/virtualizer": "^4.0.1", + "@react-types/grid": "^3.2.8", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0", "react-transition-group": "^4.4.5" }, "peerDependencies": { "@react-spectrum/provider": "^3.2.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/listbox": { - "version": "3.12.9", - "resolved": "https://registry.npmjs.org/@react-spectrum/listbox/-/listbox-3.12.9.tgz", - "integrity": "sha512-9adZJtEtAVwNtJEU70edZOlx+LfBOeVpWCOXoAJ+5iU+rNrQER7bEpFj15GlJOL+vcwFuCPoIsDBKSxygJANLw==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/listbox": "^3.12.1", - "@react-aria/utils": "^3.24.1", - "@react-aria/virtualizer": "^3.10.1", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/progress": "^3.7.7", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-stately/layout": "^3.13.9", - "@react-stately/list": "^3.10.5", - "@react-stately/virtualizer": "^3.7.1", - "@react-types/listbox": "^3.4.9", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/listbox/-/listbox-3.13.1.tgz", + "integrity": "sha512-VaLxXVMMDltrQclfWUZJcpq/0u4Ijm2vr1S1L4ype2VF2S8X2gKiwnfsMfzjhxmfSvjKr1vH+kxRC45sDuFdWA==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/listbox": "^3.13.1", + "@react-aria/utils": "^3.25.1", + "@react-aria/virtualizer": "^4.0.1", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/progress": "^3.7.9", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-stately/layout": "^4.0.1", + "@react-stately/list": "^3.10.7", + "@react-stately/virtualizer": "^4.0.1", + "@react-types/listbox": "^3.5.1", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.2.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/menu": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/menu/-/menu-3.19.1.tgz", - "integrity": "sha512-/bpqSPef1UvoaIwd5GVrqMt8LiByi5rV9yh0K+SSzZ5uY/w4zRQN9y14XnLf4P53R67DpSqAqk3JoWOLFj0Zcg==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/menu": "^3.14.1", - "@react-aria/overlays": "^3.22.1", - "@react-aria/separator": "^3.3.13", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/overlays": "^5.6.1", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-stately/menu": "^3.7.1", - "@react-stately/overlays": "^3.6.7", - "@react-stately/tree": "^3.8.1", - "@react-types/menu": "^3.9.9", - "@react-types/overlays": "^3.8.7", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", - "@spectrum-icons/workflow": "^4.2.12", + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/menu/-/menu-3.20.1.tgz", + "integrity": "sha512-lIkL14tJaZh3Ago2x8EMcLlyGBMRquDz0OsqgMHeHwQOtUOnIY31JdrWNBdSYWgASZDytrKJSU4e5gXRMCYNEw==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/menu": "^3.15.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/separator": "^3.4.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/overlays": "^5.6.3", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-stately/menu": "^3.8.1", + "@react-stately/overlays": "^3.6.9", + "@react-stately/tree": "^3.8.3", + "@react-types/menu": "^3.9.11", + "@react-types/overlays": "^3.8.9", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", + "@spectrum-icons/workflow": "^4.2.14", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/meter": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/meter/-/meter-3.5.1.tgz", - "integrity": "sha512-xmQwPDmT8hfkEuyUrijpe2xXyzWlFErrnKpQIf49Lql/GudeGHIvtekx3Qj2kvhwLpHKeOOECk35PufCJmwF2A==", - "dependencies": { - "@react-aria/meter": "^3.4.13", - "@react-spectrum/progress": "^3.7.7", - "@react-spectrum/utils": "^3.11.7", - "@react-types/meter": "^3.4.1", - "@react-types/shared": "^3.23.1", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@react-spectrum/meter/-/meter-3.5.3.tgz", + "integrity": "sha512-mfsF+O4MkjaMGBQRT80zn5yd1TXtBF/aqtW2nrGFKxE/sRGJ6mWuqEuPheL+jEuQwcnAanQBk03+yaSUgYPW8Q==", + "dependencies": { + "@react-aria/meter": "^3.4.15", + "@react-spectrum/progress": "^3.7.9", + "@react-spectrum/utils": "^3.11.9", + "@react-types/meter": "^3.4.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/numberfield": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@react-spectrum/numberfield/-/numberfield-3.9.3.tgz", - "integrity": "sha512-t3LllH5NkaqlwkvfFVizmzp4+MhMCqooLlUsBIbDgqyNCWEbxiC16ZqPOPkZkBDFio1aKX0zzSb9SiuUFw2ZwA==", - "dependencies": { - "@react-aria/button": "^3.9.5", - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/numberfield": "^3.11.3", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/textfield": "^3.12.1", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/numberfield": "^3.9.3", - "@react-types/button": "^3.9.4", - "@react-types/numberfield": "^3.8.3", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", - "@spectrum-icons/workflow": "^4.2.12", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@react-spectrum/numberfield/-/numberfield-3.9.5.tgz", + "integrity": "sha512-fmaeAarm3ay7PpbrvvIrKkHdEMSKsuRyjcfkSjLCpkkI2D2sg2iJBtlbD+FypwvkpMJh/Lk6UPpirNgsX/+kcw==", + "dependencies": { + "@react-aria/button": "^3.9.7", + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/numberfield": "^3.11.5", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/textfield": "^3.12.3", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/numberfield": "^3.9.5", + "@react-types/button": "^3.9.6", + "@react-types/numberfield": "^3.8.5", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", + "@spectrum-icons/workflow": "^4.2.14", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/overlays": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/overlays/-/overlays-5.6.1.tgz", - "integrity": "sha512-ABacMG1V6gHCHHHtD01xt9RjTCu51Kytr/oHdUPEFd5Zvh8m/O7j3IQI4nSj5a5kDoj73NAkENq9Cq12gjwL4g==", - "dependencies": { - "@react-aria/interactions": "^3.21.3", - "@react-aria/overlays": "^3.22.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/overlays": "^3.6.7", - "@react-types/overlays": "^3.8.7", - "@react-types/shared": "^3.23.1", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@react-spectrum/overlays/-/overlays-5.6.3.tgz", + "integrity": "sha512-EUnpn99fx3nmBQAUc1Cxgf75Ro1Cg1rey1SC/TIVllhz2D3tSOsDD22I/eWXMEdBNS+IeSFzbEGApOvJrp4RKQ==", + "dependencies": { + "@react-aria/interactions": "^3.22.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/overlays": "^3.6.9", + "@react-types/overlays": "^3.8.9", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", "react-transition-group": "^4.4.5" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/picker": { - "version": "3.14.5", - "resolved": "https://registry.npmjs.org/@react-spectrum/picker/-/picker-3.14.5.tgz", - "integrity": "sha512-FBCMibgStP62XKS2yJWHtn+XOLsxuzs0pl0jHkozuBaqC42H6fkDcINgQ08wbS2PlEEJSOYIkeL3LXFcxuewEA==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/select": "^3.14.5", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/listbox": "^3.12.9", - "@react-spectrum/overlays": "^5.6.1", - "@react-spectrum/progress": "^3.7.7", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-stately/select": "^3.6.4", - "@react-types/select": "^3.9.4", - "@react-types/shared": "^3.23.1", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/picker/-/picker-3.15.1.tgz", + "integrity": "sha512-vsTRw7U7d1TppJwJtwXfZ75WgUf87nIDOhNrqykVvCXxt7C9DTJ8OwJPBfOl88ImfT4U1f6ldr681uC4VU7lIA==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/select": "^3.14.7", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/listbox": "^3.13.1", + "@react-spectrum/overlays": "^5.6.3", + "@react-spectrum/progress": "^3.7.9", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-stately/select": "^3.6.6", + "@react-types/select": "^3.9.6", + "@react-types/shared": "^3.24.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.1.4", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/progress": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@react-spectrum/progress/-/progress-3.7.7.tgz", - "integrity": "sha512-FI/oc9hEQqbv00VJbaxqFTncBDDbxWN9cbvNNrPoROBQWL3NgB3tvEqY/fm5IXtDeFEV/U+tSm8BnZTGn6Mdxg==", - "dependencies": { - "@react-aria/progress": "^3.4.13", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/progress": "^3.5.4", - "@react-types/shared": "^3.23.1", + "version": "3.7.9", + "resolved": "https://registry.npmjs.org/@react-spectrum/progress/-/progress-3.7.9.tgz", + "integrity": "sha512-C6sozAPqupK1geqhmbS9K28b5xW2ZdIiBrk1XGjIiBuAqQZhvqFxCliwr2pbjWPcOGLQJrgc8dGWUuvZXUtGXQ==", + "dependencies": { + "@react-aria/progress": "^3.4.15", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/progress": "^3.5.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/provider": { - "version": "3.9.7", - "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.9.7.tgz", - "integrity": "sha512-VRu8cOWrLJU/Krulo8njfPCMeJT+uu1k9GjFZ9Cw88mHGW7a3MK54IzI5p2evLPab7pgplPIoJcv3bC2XB+DAA==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/overlays": "^3.22.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/provider": "^3.8.1", - "@react-types/shared": "^3.23.1", + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.9.9.tgz", + "integrity": "sha512-sVgIG0MZ/4KCrJgWjOGyEdP5nhl8fXxp6L1s7SWyzWT/e6ypD0Og9hkQo/yY2XHP2hI4ZiZ4Psc1H4olsrp5lw==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/provider": "^3.8.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/radio": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/@react-spectrum/radio/-/radio-3.7.6.tgz", - "integrity": "sha512-KRtipJfIkRWbnvhS/zZ7j3ltEQXrQeVNhmIWChuP+sC5hdA3N8llMgf30Xa9PqtFhGH4CvUlXC9NA/rhLWnm4w==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/radio": "^3.10.4", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/radio": "^3.10.4", - "@react-types/radio": "^3.8.1", - "@react-types/shared": "^3.23.1", + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/@react-spectrum/radio/-/radio-3.7.8.tgz", + "integrity": "sha512-H11U3Hf15wVhp8hoyYR2bUKgKyyihhjPw40rf2ZESnS/FEeOifVQtzr6UbEKqb1qC/LX5YhuHjUyXv+j4DuVeA==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/radio": "^3.10.6", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/radio": "^3.10.6", + "@react-types/radio": "^3.8.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/searchfield": { - "version": "3.8.6", - "resolved": "https://registry.npmjs.org/@react-spectrum/searchfield/-/searchfield-3.8.6.tgz", - "integrity": "sha512-RU928ZeQsqPGMsNVtoLvahHmuRC3OAW9im5W0/CVgglINn2IapF2U0oxHVw6ymzx1NyCYrYR8pO9skMF0E68/Q==", - "dependencies": { - "@react-aria/searchfield": "^3.7.5", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/textfield": "^3.12.1", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/searchfield": "^3.5.3", - "@react-types/searchfield": "^3.5.5", - "@react-types/textfield": "^3.9.3", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.8.8", + "resolved": "https://registry.npmjs.org/@react-spectrum/searchfield/-/searchfield-3.8.8.tgz", + "integrity": "sha512-HR0lQNNzjNyi12bEJ39U/rASZpQuHIpUq9A3DzarRMARrHLmidHzH4F7zu9I4k3GTFm/mL+j2q44EJIP2GqtQQ==", + "dependencies": { + "@react-aria/searchfield": "^3.7.7", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/textfield": "^3.12.3", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/searchfield": "^3.5.5", + "@react-types/searchfield": "^3.5.7", + "@react-types/textfield": "^3.9.5", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/slider": { - "version": "3.6.9", - "resolved": "https://registry.npmjs.org/@react-spectrum/slider/-/slider-3.6.9.tgz", - "integrity": "sha512-2X6qxlyObfowb8uZQ8UXEozozcfGLzhQI9BS9DS9Kste/REXMTcRDzFygP1D1HdkvRaWmYRNoYhi/Jl2Kkw7Eg==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/slider": "^3.7.8", - "@react-aria/utils": "^3.24.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/slider": "^3.5.4", - "@react-types/shared": "^3.23.1", - "@react-types/slider": "^3.7.3", + "version": "3.6.11", + "resolved": "https://registry.npmjs.org/@react-spectrum/slider/-/slider-3.6.11.tgz", + "integrity": "sha512-Rz8yzQKZTO+PBjnEwRCd+dxIMo/A7Qsj1Vs3sVowSlmLeq6qHeLajdTbe2SN95pUC/b6n+tkNxMyy2bzsW2VlQ==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/slider": "^3.7.10", + "@react-aria/utils": "^3.25.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/slider": "^3.5.6", + "@react-types/shared": "^3.24.1", + "@react-types/slider": "^3.7.5", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/statuslight": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@react-spectrum/statuslight/-/statuslight-3.5.13.tgz", - "integrity": "sha512-FvvsDVs9lapRf5zmOq3g8ZRpAxOTVRfhG9WyehIqgaRPtqqNpQhAGSXWz0ErXF3zV8AwVvjD70g0atcDCoDeBQ==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/shared": "^3.23.1", - "@react-types/statuslight": "^3.3.9", + "version": "3.5.15", + "resolved": "https://registry.npmjs.org/@react-spectrum/statuslight/-/statuslight-3.5.15.tgz", + "integrity": "sha512-gTv4HvnJNcNBTJs3Xw6ki984A7Z58CE2jlKEJ9+PrOJY+cckjeocfWR1XqQsJHCaNuGC9LYhzuJsqsPnqxFNZA==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/shared": "^3.24.1", + "@react-types/statuslight": "^3.3.11", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/switch": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/@react-spectrum/switch/-/switch-3.5.5.tgz", - "integrity": "sha512-IIVctsGXnChqMlvf2/pMRkI84vyjf0gMsBXEgky8h8s4i91wxQvl6800/4I9rCSQdAAnQYb+Nd3St8Ik7BupQg==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/switch": "^3.6.4", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/toggle": "^3.7.4", - "@react-types/shared": "^3.23.1", - "@react-types/switch": "^3.5.3", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@react-spectrum/switch/-/switch-3.5.7.tgz", + "integrity": "sha512-tXkUadG3VeCGskROYUdFjYNSsQ9G1D72hCG7LoXusIUqYzvNz3xlm3TSP1LOF/lq+WGhPxhhV5LkA1HqN+ZeeA==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/switch": "^3.6.6", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/toggle": "^3.7.6", + "@react-types/shared": "^3.24.1", + "@react-types/switch": "^3.5.5", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/table": { - "version": "3.12.10", - "resolved": "https://registry.npmjs.org/@react-spectrum/table/-/table-3.12.10.tgz", - "integrity": "sha512-a9Qa/1uuoChRez6GncmYdkDgSS4MDXzV4Cl/BrO44Dnph1ygXiJGmBgAvmtevcbndfuERGHoIYqzklIr6veArg==", - "dependencies": { - "@react-aria/button": "^3.9.5", - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/overlays": "^3.22.1", - "@react-aria/table": "^3.14.1", - "@react-aria/utils": "^3.24.1", - "@react-aria/virtualizer": "^3.10.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-spectrum/checkbox": "^3.9.6", - "@react-spectrum/dnd": "^3.3.10", - "@react-spectrum/layout": "^3.6.5", - "@react-spectrum/menu": "^3.19.1", - "@react-spectrum/progress": "^3.7.7", - "@react-spectrum/tooltip": "^3.6.7", - "@react-spectrum/utils": "^3.11.7", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/table/-/table-3.13.1.tgz", + "integrity": "sha512-CnxgizMey9sdAL3iyMCX0BGim+USgeKtss8ZIzWIhGmrUBpoQy32ZedXpcN7UwBIScWYo1b44fyNxw6z44K6Dw==", + "dependencies": { + "@react-aria/button": "^3.9.7", + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/table": "^3.15.1", + "@react-aria/utils": "^3.25.1", + "@react-aria/virtualizer": "^4.0.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-spectrum/checkbox": "^3.9.8", + "@react-spectrum/dnd": "^3.4.1", + "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/menu": "^3.20.1", + "@react-spectrum/progress": "^3.7.9", + "@react-spectrum/tooltip": "^3.6.9", + "@react-spectrum/utils": "^3.11.9", "@react-stately/flags": "^3.0.3", - "@react-stately/layout": "^3.13.9", - "@react-stately/table": "^3.11.8", - "@react-stately/virtualizer": "^3.7.1", - "@react-types/grid": "^3.2.6", - "@react-types/shared": "^3.23.1", - "@react-types/table": "^3.9.5", - "@spectrum-icons/ui": "^3.6.7", + "@react-stately/layout": "^4.0.1", + "@react-stately/table": "^3.12.1", + "@react-stately/virtualizer": "^4.0.1", + "@react-types/grid": "^3.2.8", + "@react-types/shared": "^3.24.1", + "@react-types/table": "^3.10.1", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/tabs": { - "version": "3.8.10", - "resolved": "https://registry.npmjs.org/@react-spectrum/tabs/-/tabs-3.8.10.tgz", - "integrity": "sha512-LoNkxalAbOjKgbF/x3NU5zhvhUgAEqJvEwzKLVSr+KDQlMAFe9LZ+HOH2NRiWR8ak9BkW3RR6C8cGo7G7fdrfA==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/tabs": "^3.9.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/picker": "^3.14.5", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-stately/list": "^3.10.5", - "@react-stately/tabs": "^3.6.6", - "@react-types/select": "^3.9.4", - "@react-types/shared": "^3.23.1", - "@react-types/tabs": "^3.3.7", + "version": "3.8.12", + "resolved": "https://registry.npmjs.org/@react-spectrum/tabs/-/tabs-3.8.12.tgz", + "integrity": "sha512-tvHEzV5Web6D98vLNbWVwrGGNKx/n6NeuYB6QX88lA8Pp0M9XCuQ6S6548Zk/eUHS0eExi60yX+AcPn1mZTtNQ==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/tabs": "^3.9.3", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/picker": "^3.15.1", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-stately/list": "^3.10.7", + "@react-stately/tabs": "^3.6.8", + "@react-types/select": "^3.9.6", + "@react-types/shared": "^3.24.1", + "@react-types/tabs": "^3.3.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/tag": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@react-spectrum/tag/-/tag-3.2.6.tgz", - "integrity": "sha512-OSGIL2fYLMmiPRCEGvdrQVazS6/S0nhzf/FO52pAAjDZHkd4RDlHHY00Yv/2GPJKroa4e5jdyd5NHCxlW5Vbaw==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/selection": "^3.18.1", - "@react-aria/tag": "^3.4.1", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/button": "^3.16.4", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/text": "^3.5.5", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/collections": "^3.10.7", - "@react-stately/list": "^3.10.5", - "@react-types/shared": "^3.23.1", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@react-spectrum/tag/-/tag-3.2.8.tgz", + "integrity": "sha512-cZO745mdjwoSvEoBjWTREdZiOshuGq8jm+1XuO6eWGcxCsktU6ToPjz7wrmHi6kE4fuhXj/UxcyA+8IXSL1mhw==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/selection": "^3.19.1", + "@react-aria/tag": "^3.4.3", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/button": "^3.16.6", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/text": "^3.5.7", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/collections": "^3.10.9", + "@react-stately/list": "^3.10.7", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/text": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/@react-spectrum/text/-/text-3.5.5.tgz", - "integrity": "sha512-MSRMUNWjuqjAH0eRjSw0fOCvM7haqgfy3HgwHpB5czpeUtR1p22e+UWA9gHior7S57zrQN1WotpeWZ1AmnzvWg==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/shared": "^3.23.1", - "@react-types/text": "^3.3.9", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@react-spectrum/text/-/text-3.5.7.tgz", + "integrity": "sha512-Tvnto3UrWEc4iBiKYAFH9X6GzLwwzy4uWxRaPiZ3uu+I+JCd/Sz+mjdk5lOLtpPA78xtPkHO/I/iGijk4ag6mg==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/shared": "^3.24.1", + "@react-types/text": "^3.3.11", "@swc/helpers": "^0.5.0", - "react-aria-components": "^1.2.1" + "react-aria-components": "^1.3.1" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/textfield": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/textfield/-/textfield-3.12.1.tgz", - "integrity": "sha512-ehvStKrduGo71SfEieodw6NHBDvyE5wYYZh1uLwbde9hjfyOf2q56lfMdSQiBSJ5pDnpS0ToLpoomoPz315u+Q==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/textfield": "^3.14.5", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/form": "^3.7.6", - "@react-spectrum/label": "^3.16.6", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/utils": "^3.10.1", - "@react-types/shared": "^3.23.1", - "@react-types/textfield": "^3.9.3", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.12.3", + "resolved": "https://registry.npmjs.org/@react-spectrum/textfield/-/textfield-3.12.3.tgz", + "integrity": "sha512-1NUTA/Wo8cPLmKcQymgzVBd37Q1mLf358stV4MxLqKjnPT+rGHBTflhV1cmRpLbWdXYnyPSEXyZx12YXctauKg==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/textfield": "^3.14.7", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/form": "^3.7.8", + "@react-spectrum/label": "^3.16.8", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/utils": "^3.10.2", + "@react-types/shared": "^3.24.1", + "@react-types/textfield": "^3.9.5", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/theme-dark": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@react-spectrum/theme-dark/-/theme-dark-3.5.10.tgz", - "integrity": "sha512-xDzuWY9Vtd0X7Ww5fBvhbTq7oM0PiNtKlT+cPVnKm4YmJB5RvVG/m6jYF4/9GN36NAyiRnNRdBCs7SUuKEfTkA==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@react-spectrum/theme-dark/-/theme-dark-3.5.12.tgz", + "integrity": "sha512-WLicILM0CDx3peenTZC9JQ7uhmZee2IiQtYMjYXGzCzHD3WG+X6OodpXG0VgtzHhb8lmtbzwxvGGPJlCPJIzqw==", "dependencies": { - "@react-types/provider": "^3.8.1", + "@react-types/provider": "^3.8.3", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/theme-default": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@react-spectrum/theme-default/-/theme-default-3.5.10.tgz", - "integrity": "sha512-qCGce11d5p0Ce4nSz25vRYoMZycb8oxbgMUM9YXXHgUBDbRRB/s0JNUXxlyikENtaNWiCyeWzVm80bJKmmIijw==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@react-spectrum/theme-default/-/theme-default-3.5.12.tgz", + "integrity": "sha512-bGtwv0NirmYIC4/4Tkkikn7yqKMITY8VKGEY8105EpiDZX+/8tr4dwypWi/EE0OMF8kTCW61zu5aScrNUQfGew==", "dependencies": { - "@react-types/provider": "^3.8.1", + "@react-types/provider": "^3.8.3", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/theme-light": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/@react-spectrum/theme-light/-/theme-light-3.4.10.tgz", - "integrity": "sha512-MKHxBlfawja16hBlcBTFD72B+luPwhCG/pTY35WMy+gCVWUeYEwJU8ijOhG7A7a7KkrLpHgebpHojxEXYkmFIA==", + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/@react-spectrum/theme-light/-/theme-light-3.4.12.tgz", + "integrity": "sha512-KrWYTQFcuKayEIJCdMA5z0Kbd2l4oeT72QSaqV+h2Hi7mnjxM7R16GZgF3swAJOvWEMSqhLLCzr/6P0prRmVmQ==", "dependencies": { - "@react-types/provider": "^3.8.1", + "@react-types/provider": "^3.8.3", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/tooltip": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/@react-spectrum/tooltip/-/tooltip-3.6.7.tgz", - "integrity": "sha512-kJDFY7G5MGuKc5e4K24ftYbzFLt9ugO5zbGMAg6Zbz79+ER8jTsbGNVupK3E7m9uSimF/aPRRwf2p8UdoksH6Q==", - "dependencies": { - "@react-aria/focus": "^3.17.1", - "@react-aria/overlays": "^3.22.1", - "@react-aria/tooltip": "^3.7.4", - "@react-aria/utils": "^3.24.1", - "@react-spectrum/overlays": "^5.6.1", - "@react-spectrum/utils": "^3.11.7", - "@react-stately/tooltip": "^3.4.9", - "@react-types/overlays": "^3.8.7", - "@react-types/shared": "^3.23.1", - "@react-types/tooltip": "^3.4.9", - "@spectrum-icons/ui": "^3.6.7", + "version": "3.6.9", + "resolved": "https://registry.npmjs.org/@react-spectrum/tooltip/-/tooltip-3.6.9.tgz", + "integrity": "sha512-AVWowYE43ZyOh2tck5TKs7a5a6RaAefeRPiqLpBo8W64TwP07WZgRtUJjLSFrt1AIVwfRyjOiwBiG/Ur896Zfw==", + "dependencies": { + "@react-aria/focus": "^3.18.1", + "@react-aria/overlays": "^3.23.1", + "@react-aria/tooltip": "^3.7.6", + "@react-aria/utils": "^3.25.1", + "@react-spectrum/overlays": "^5.6.3", + "@react-spectrum/utils": "^3.11.9", + "@react-stately/tooltip": "^3.4.11", + "@react-types/overlays": "^3.8.9", + "@react-types/shared": "^3.24.1", + "@react-types/tooltip": "^3.4.11", + "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/utils": { - "version": "3.11.7", - "resolved": "https://registry.npmjs.org/@react-spectrum/utils/-/utils-3.11.7.tgz", - "integrity": "sha512-o/9zTvUor0EaRwKZWVlgOcyvH+/JIBsNxuvhDgCP5lD868KoZePmx1L64TejUqK/swwH8jr35gyULpYU2kQXRw==", - "dependencies": { - "@react-aria/i18n": "^3.11.1", - "@react-aria/ssr": "^3.9.4", - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", + "version": "3.11.9", + "resolved": "https://registry.npmjs.org/@react-spectrum/utils/-/utils-3.11.9.tgz", + "integrity": "sha512-k+0dwCflYejSix7FaRMp63ptgs/nc9ndOVa1qJVI/VGK+P9alZmqMXUhIztClLCcyFjJrd9O2YIaAEsBCkBNRw==", + "dependencies": { + "@react-aria/i18n": "^3.12.1", + "@react-aria/ssr": "^3.9.5", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/view": { - "version": "3.6.10", - "resolved": "https://registry.npmjs.org/@react-spectrum/view/-/view-3.6.10.tgz", - "integrity": "sha512-AbvwyORDzntt9XiP9Soc5mCuYsYOJKj+4mwX0ugZZi9I18g1JVeSPnGG/myYdHr2xXNC00pgVILOLA/B0JWMXw==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/shared": "^3.23.1", - "@react-types/view": "^3.4.9", + "version": "3.6.12", + "resolved": "https://registry.npmjs.org/@react-spectrum/view/-/view-3.6.12.tgz", + "integrity": "sha512-zcmeEuOUDC+fGPTyuDZWouFFMm8/58RaHJtSIvrzSCixV3RAfGeWwi6tRCDjSQuYgDBjNvxUMCbYP88CO2FULw==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/shared": "^3.24.1", + "@react-types/view": "^3.4.11", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spectrum/well": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/@react-spectrum/well/-/well-3.4.13.tgz", - "integrity": "sha512-zKJsaWnndRvCK4crkZ/Jt5uUk5Jwkx+pRaVu40BEK41aOfavQ44GR90uLogrvDuw2LDZ9mdTj/H7bCVNjkLkgA==", - "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-spectrum/utils": "^3.11.7", - "@react-types/shared": "^3.23.1", - "@react-types/well": "^3.3.9", + "version": "3.4.15", + "resolved": "https://registry.npmjs.org/@react-spectrum/well/-/well-3.4.15.tgz", + "integrity": "sha512-bzSIZAtXjHaLzcENYracSDabjQgU1KJAXofQ/YwBqZwMDVsokG+kvR+bfGfW05tldgZH5/7Am9D/pIcSW4qBUQ==", + "dependencies": { + "@react-aria/utils": "^3.25.1", + "@react-spectrum/utils": "^3.11.9", + "@react-types/shared": "^3.24.1", + "@react-types/well": "^3.3.11", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spring/animated": { @@ -6184,127 +6188,127 @@ } }, "node_modules/@react-stately/calendar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.1.tgz", - "integrity": "sha512-7l7QhqGUJ5AzWHfvZzbTe3J4t72Ht5BmhW4hlVI7flQXtfrmYkVtl3ZdytEZkkHmWGYZRW9b4IQTQGZxhtlElA==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.3.tgz", + "integrity": "sha512-SRwsgszyc9FNcvkjqBe81e/tnjKpRqH+yTYpG0uI9NR1HfyddmhR3Y7QilWPcqQkq4SQb7pL68SkTPH2dX2dng==", "dependencies": { - "@internationalized/date": "^3.5.4", - "@react-stately/utils": "^3.10.1", - "@react-types/calendar": "^3.4.6", - "@react-types/shared": "^3.23.1", + "@internationalized/date": "^3.5.5", + "@react-stately/utils": "^3.10.2", + "@react-types/calendar": "^3.4.8", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/checkbox": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.5.tgz", - "integrity": "sha512-IXV3f9k+LtmfQLE+DKIN41Q5QB/YBLDCB1YVx5PEdRp52S9+EACD5683rjVm8NVRDwjMi2SP6RnFRk7fVb5Azg==", - "dependencies": { - "@react-stately/form": "^3.0.3", - "@react-stately/utils": "^3.10.1", - "@react-types/checkbox": "^3.8.1", - "@react-types/shared": "^3.23.1", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.7.tgz", + "integrity": "sha512-ZOaBNXXazpwkuKj5hk6FtGbXO7HoKEGXvf3p7FcHcIHyiEJ65GBvC7e7HwMc3jYxlBwtbebSpEcf3oFqI5dl3A==", + "dependencies": { + "@react-stately/form": "^3.0.5", + "@react-stately/utils": "^3.10.2", + "@react-types/checkbox": "^3.8.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/collections": { - "version": "3.10.7", - "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.7.tgz", - "integrity": "sha512-KRo5O2MWVL8n3aiqb+XR3vP6akmHLhLWYZEmPKjIv0ghQaEebBTrN3wiEjtd6dzllv0QqcWvDLM1LntNfJ2TsA==", + "version": "3.10.9", + "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.9.tgz", + "integrity": "sha512-plyrng6hOQMG8LrjArMA6ts/DgWyXln3g90/hFNbqe/hdVYF53sDVsj8Jb+5LtoYTpiAlV6eOvy1XR0vPZUf8w==", "dependencies": { - "@react-types/shared": "^3.23.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/color": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.6.1.tgz", - "integrity": "sha512-iW0nAhl3+fUBegHMw5EcAbFVDpgwHBrivfC85pVoTM3pyzp66hqNN6R6xWxW6ETyljS8UOer59+/w4GDVGdPig==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.7.1.tgz", + "integrity": "sha512-pJqM7fZ7+zy8wnzCUkBMkTgmjMs+lBLjQm1k+dFbmXK2SuELiDOQLirrl6j15NVBOKn8avvRHXpAQhGX43GOCQ==", "dependencies": { "@internationalized/number": "^3.5.3", "@internationalized/string": "^3.2.3", - "@react-aria/i18n": "^3.11.1", - "@react-stately/form": "^3.0.3", - "@react-stately/numberfield": "^3.9.3", - "@react-stately/slider": "^3.5.4", - "@react-stately/utils": "^3.10.1", - "@react-types/color": "3.0.0-beta.25", - "@react-types/shared": "^3.23.1", + "@react-aria/i18n": "^3.12.1", + "@react-stately/form": "^3.0.5", + "@react-stately/numberfield": "^3.9.5", + "@react-stately/slider": "^3.5.6", + "@react-stately/utils": "^3.10.2", + "@react-types/color": "3.0.0-rc.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/combobox": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.8.4.tgz", - "integrity": "sha512-iLVGvKRRz0TeJXZhZyK783hveHpYA6xovOSdzSD+WGYpiPXo1QrcrNoH3AE0Z2sHtorU+8nc0j58vh5PB+m2AA==", - "dependencies": { - "@react-stately/collections": "^3.10.7", - "@react-stately/form": "^3.0.3", - "@react-stately/list": "^3.10.5", - "@react-stately/overlays": "^3.6.7", - "@react-stately/select": "^3.6.4", - "@react-stately/utils": "^3.10.1", - "@react-types/combobox": "^3.11.1", - "@react-types/shared": "^3.23.1", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.9.1.tgz", + "integrity": "sha512-jmeKUKs0jK18NwDAlpu79ATufgxrc6Sn3ZMmI8KPVQ5sdPTjNlnDx6gTFyOOIa87axf/c6WYU7v3jxmcp+RDdg==", + "dependencies": { + "@react-stately/collections": "^3.10.9", + "@react-stately/form": "^3.0.5", + "@react-stately/list": "^3.10.7", + "@react-stately/overlays": "^3.6.9", + "@react-stately/select": "^3.6.6", + "@react-stately/utils": "^3.10.2", + "@react-types/combobox": "^3.12.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/data": { - "version": "3.11.4", - "resolved": "https://registry.npmjs.org/@react-stately/data/-/data-3.11.4.tgz", - "integrity": "sha512-PbnUQxeE6AznSuEWYnRmrYQ9t5z1Asx98Jtrl96EeA6Iapt9kOjTN9ySqCxtPxMKleb1NIqG3+uHU3veIqmLsg==", + "version": "3.11.6", + "resolved": "https://registry.npmjs.org/@react-stately/data/-/data-3.11.6.tgz", + "integrity": "sha512-S8q1Ejuhijl8SnyVOdDNFrMrWWnLk/Oh1ZT3KHSbTdpfMRtvhi5HukoiP06jlzz75phnpSPQL40npDtUB/kk3Q==", "dependencies": { - "@react-types/shared": "^3.23.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/datepicker": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.9.4.tgz", - "integrity": "sha512-yBdX01jn6gq4NIVvHIqdjBUPo+WN8Bujc4OnPw+ZnfA4jI0eIgq04pfZ84cp1LVXW0IB0VaCu1AlQ/kvtZjfGA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.10.1.tgz", + "integrity": "sha512-KXr5cxLOLUYBf3wlDSKhvshsKOWpdV2flhS075V6dgC/EPBh7igBZGUXJ9AZzndT7Hx1w8v/ul6CIffxEJz1Nw==", "dependencies": { - "@internationalized/date": "^3.5.4", + "@internationalized/date": "^3.5.5", "@internationalized/string": "^3.2.3", - "@react-stately/form": "^3.0.3", - "@react-stately/overlays": "^3.6.7", - "@react-stately/utils": "^3.10.1", - "@react-types/datepicker": "^3.7.4", - "@react-types/shared": "^3.23.1", + "@react-stately/form": "^3.0.5", + "@react-stately/overlays": "^3.6.9", + "@react-stately/utils": "^3.10.2", + "@react-types/datepicker": "^3.8.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/dnd": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.3.1.tgz", - "integrity": "sha512-I/Ci5xB8hSgAXzoWYWScfMM9UK1MX/eTlARBhiSlfudewweOtNJAI+cXJgU7uiUnGjh4B4v3qDBtlAH1dWDCsw==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.4.1.tgz", + "integrity": "sha512-EXPW1vKx3vNpMaXOpPKTOU1T4S+jqjllGFDyWD659Ql0lL9SQ5Y4IU/KmIK3T3yKkjps9xrMmCjLAkb75PH5zg==", "dependencies": { - "@react-stately/selection": "^3.15.1", - "@react-types/shared": "^3.23.1", + "@react-stately/selection": "^3.16.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/flags": { @@ -6316,756 +6320,756 @@ } }, "node_modules/@react-stately/form": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.0.3.tgz", - "integrity": "sha512-92YYBvlHEWUGUpXgIaQ48J50jU9XrxfjYIN8BTvvhBHdD63oWgm8DzQnyT/NIAMzdLnhkg7vP+fjG8LjHeyIAg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.0.5.tgz", + "integrity": "sha512-J3plwJ63HQz109OdmaTqTA8Qhvl3gcYYK7DtgKyNP6mc/Me2Q4tl2avkWoA+22NRuv5m+J8TpBk4AVHUEOwqeQ==", "dependencies": { - "@react-types/shared": "^3.23.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/grid": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.8.7.tgz", - "integrity": "sha512-he3TXCLAhF5C5z1/G4ySzcwyt7PEiWcVIupxebJQqRyFrNWemSuv+7tolnStmG8maMVIyV3P/3j4eRBbdSlOIg==", - "dependencies": { - "@react-stately/collections": "^3.10.7", - "@react-stately/selection": "^3.15.1", - "@react-types/grid": "^3.2.6", - "@react-types/shared": "^3.23.1", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.9.1.tgz", + "integrity": "sha512-LSVIcXO/cqwG0IgDSk2juDbpARBS1IzGnsTp/8vSOejMxq5MXrwxL5hUcqNczL8Ss6aLpELm42tCS0kPm3cMKw==", + "dependencies": { + "@react-stately/collections": "^3.10.9", + "@react-stately/selection": "^3.16.1", + "@react-types/grid": "^3.2.8", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/layout": { - "version": "3.13.9", - "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-3.13.9.tgz", - "integrity": "sha512-JCj2cnvRbBjah9LFZbBXMdKkoKuEpzn6hvYBw7h0fNIhNGISpiI1TW4ya1X34kD2vcv/3dc31KV/UqmI4hJCQw==", - "dependencies": { - "@react-stately/collections": "^3.10.7", - "@react-stately/table": "^3.11.8", - "@react-stately/virtualizer": "^3.7.1", - "@react-types/grid": "^3.2.6", - "@react-types/shared": "^3.23.1", - "@react-types/table": "^3.9.5", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-4.0.1.tgz", + "integrity": "sha512-4oNYFhQprcwP1fNV/p3dbx1a6lzMGBAKLTdcvtCuBCgclNA3etqjdQAUIZ0Bpq+Z8i9qo3c85oxr6Tr8BKQV4w==", + "dependencies": { + "@react-stately/collections": "^3.10.9", + "@react-stately/table": "^3.12.1", + "@react-stately/virtualizer": "^4.0.1", + "@react-types/grid": "^3.2.8", + "@react-types/shared": "^3.24.1", + "@react-types/table": "^3.10.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/list": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.5.tgz", - "integrity": "sha512-fV9plO+6QDHiewsYIhboxcDhF17GO95xepC5ki0bKXo44gr14g/LSo/BMmsaMnV+1BuGdBunB05bO4QOIaigXA==", - "dependencies": { - "@react-stately/collections": "^3.10.7", - "@react-stately/selection": "^3.15.1", - "@react-stately/utils": "^3.10.1", - "@react-types/shared": "^3.23.1", + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.7.tgz", + "integrity": "sha512-W5PG7uG5GQV2Q59vXJE7QLKHZIoUNEx+JmHrBUCMKUgyngSpKIIEDR/R/C1b6ZJ9jMqqZA68Zlnd5iK1/mBi1A==", + "dependencies": { + "@react-stately/collections": "^3.10.9", + "@react-stately/selection": "^3.16.1", + "@react-stately/utils": "^3.10.2", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/menu": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.7.1.tgz", - "integrity": "sha512-mX1w9HHzt+xal1WIT2xGrTQsoLvDwuB2R1Er1MBABs//MsJzccycatcgV/J/28m6tO5M9iuFQQvLV+i1dCtodg==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.8.1.tgz", + "integrity": "sha512-HzAANHg+QUpyRok0CBIL/5qb+4TARteP0q9av2tKnQWPG91iJw84phJDJrmmY55uFFax4fxBgDM9dy1t12iKgQ==", "dependencies": { - "@react-stately/overlays": "^3.6.7", - "@react-types/menu": "^3.9.9", - "@react-types/shared": "^3.23.1", + "@react-stately/overlays": "^3.6.9", + "@react-types/menu": "^3.9.11", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/numberfield": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.3.tgz", - "integrity": "sha512-UlPTLSabhLEuHtgzM0PgfhtEaHy3yttbzcRb8yHNvGo4KbCHeHpTHd3QghKfTFm024Mug7+mVlWCmMtW0f5ttg==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.5.tgz", + "integrity": "sha512-aWilyzrZOvkgntcXd6Kl+t1QiCbnajUCN8yll6/saByKpfuOf1k6AGYNQBJ0CO/5HyffPPdbFs+45sj4e3cdjA==", "dependencies": { "@internationalized/number": "^3.5.3", - "@react-stately/form": "^3.0.3", - "@react-stately/utils": "^3.10.1", - "@react-types/numberfield": "^3.8.3", + "@react-stately/form": "^3.0.5", + "@react-stately/utils": "^3.10.2", + "@react-types/numberfield": "^3.8.5", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/overlays": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.7.tgz", - "integrity": "sha512-6zp8v/iNUm6YQap0loaFx6PlvN8C0DgWHNlrlzMtMmNuvjhjR0wYXVaTfNoUZBWj25tlDM81ukXOjpRXg9rLrw==", + "version": "3.6.9", + "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.9.tgz", + "integrity": "sha512-4chfyzKw7P2UEainm0yzjUgYwG1ovBejN88eTrn+O62x5huuMCwe0cbMxmYh4y7IhRFSee3jIJd0SP0u/+i39w==", "dependencies": { - "@react-stately/utils": "^3.10.1", - "@react-types/overlays": "^3.8.7", + "@react-stately/utils": "^3.10.2", + "@react-types/overlays": "^3.8.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/radio": { - "version": "3.10.4", - "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.4.tgz", - "integrity": "sha512-kCIc7tAl4L7Hu4Wt9l2jaa+MzYmAJm0qmC8G8yPMbExpWbLRu6J8Un80GZu+JxvzgDlqDyrVvyv9zFifwH/NkQ==", - "dependencies": { - "@react-stately/form": "^3.0.3", - "@react-stately/utils": "^3.10.1", - "@react-types/radio": "^3.8.1", - "@react-types/shared": "^3.23.1", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.6.tgz", + "integrity": "sha512-wiJuUUQ6LuEv0J1DQtkC0+Sed7tO6y3sIPeB+5uIxIIsUpxvNlDcqr+JOkrQm7gZmkmvcfotb5Gv5PqaIl1zKA==", + "dependencies": { + "@react-stately/form": "^3.0.5", + "@react-stately/utils": "^3.10.2", + "@react-types/radio": "^3.8.3", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/searchfield": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.3.tgz", - "integrity": "sha512-H0OvlgwPIFdc471ypw79MDjz3WXaVq9+THaY6JM4DIohEJNN5Dwei7O9g6r6m/GqPXJIn5TT3b74kJ2Osc00YQ==", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.5.tgz", + "integrity": "sha512-rKWIVNbxft5eGGxQ4CtcTKGXm2B1AuYSg6kLRQLq+VYspPNq3wfeMtVBeIdy4LNjWXsTmzs2b3o+zkFYdPqPPw==", "dependencies": { - "@react-stately/utils": "^3.10.1", - "@react-types/searchfield": "^3.5.5", + "@react-stately/utils": "^3.10.2", + "@react-types/searchfield": "^3.5.7", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/select": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.4.tgz", - "integrity": "sha512-whZgF1N53D0/dS8tOFdrswB0alsk5Q5620HC3z+5f2Hpi8gwgAZ8TYa+2IcmMYRiT+bxVuvEc/NirU9yPmqGbA==", - "dependencies": { - "@react-stately/form": "^3.0.3", - "@react-stately/list": "^3.10.5", - "@react-stately/overlays": "^3.6.7", - "@react-types/select": "^3.9.4", - "@react-types/shared": "^3.23.1", + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.6.tgz", + "integrity": "sha512-JEpBosWNSXRexE/iReATei1EiVdTIwOWlLcCGw6K7oC/5/f+OHMsh2Kkt/c/RzM/to3vgR+Wbbqwrb712AWgYQ==", + "dependencies": { + "@react-stately/form": "^3.0.5", + "@react-stately/list": "^3.10.7", + "@react-stately/overlays": "^3.6.9", + "@react-types/select": "^3.9.6", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/selection": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.15.1.tgz", - "integrity": "sha512-6TQnN9L0UY9w19B7xzb1P6mbUVBtW840Cw1SjgNXCB3NPaCf59SwqClYzoj8O2ZFzMe8F/nUJtfU1NS65/OLlw==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.16.1.tgz", + "integrity": "sha512-qmnmYaXY7IhhzmIiInec1a/yPxlPSBHka6vrWddvt0S6zN7FU5cv6sm69ONUwYwLKSoaNHgOGvZhmsTzyV0O2A==", "dependencies": { - "@react-stately/collections": "^3.10.7", - "@react-stately/utils": "^3.10.1", - "@react-types/shared": "^3.23.1", + "@react-stately/collections": "^3.10.9", + "@react-stately/utils": "^3.10.2", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/slider": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.4.tgz", - "integrity": "sha512-Jsf7K17dr93lkNKL9ij8HUcoM1sPbq8TvmibD6DhrK9If2lje+OOL8y4n4qreUnfMT56HCAeS9wCO3fg3eMyrw==", + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.6.tgz", + "integrity": "sha512-a7DZgpOVjQyGzMLPiVRCVHISPJX8E3bT+qbZpcRQN+F7T7wReOwUt2I8gQMosnnCGWgU6kdYk8snn0obXe70Fg==", "dependencies": { - "@react-stately/utils": "^3.10.1", - "@react-types/shared": "^3.23.1", - "@react-types/slider": "^3.7.3", + "@react-stately/utils": "^3.10.2", + "@react-types/shared": "^3.24.1", + "@react-types/slider": "^3.7.5", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/table": { - "version": "3.11.8", - "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.11.8.tgz", - "integrity": "sha512-EdyRW3lT1/kAVDp5FkEIi1BQ7tvmD2YgniGdLuW/l9LADo0T+oxZqruv60qpUS6sQap+59Riaxl91ClDxrJnpg==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.12.1.tgz", + "integrity": "sha512-Cg3lXrWJNrYkD1gqRclMxq0GGiR+ygxdeAqk2jbbsmHU8RSQuzoO/RtUCw6WAKfQjAq4gE0E60TlAsGgCUdJGA==", "dependencies": { - "@react-stately/collections": "^3.10.7", + "@react-stately/collections": "^3.10.9", "@react-stately/flags": "^3.0.3", - "@react-stately/grid": "^3.8.7", - "@react-stately/selection": "^3.15.1", - "@react-stately/utils": "^3.10.1", - "@react-types/grid": "^3.2.6", - "@react-types/shared": "^3.23.1", - "@react-types/table": "^3.9.5", + "@react-stately/grid": "^3.9.1", + "@react-stately/selection": "^3.16.1", + "@react-stately/utils": "^3.10.2", + "@react-types/grid": "^3.2.8", + "@react-types/shared": "^3.24.1", + "@react-types/table": "^3.10.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/tabs": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.6.tgz", - "integrity": "sha512-sOLxorH2uqjAA+v1ppkMCc2YyjgqvSGeBDgtR/lyPSDd4CVMoTExszROX2dqG0c8il9RQvzFuufUtQWMY6PgSA==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.8.tgz", + "integrity": "sha512-pLRwnMmXk/IWvbIJYSO5hm3/PiJ/VzrQlwKr6dlOcrDOSVIZpTjnGWHd6mJSDoPiDyBThlN/k3+2pUFMEOAcfw==", "dependencies": { - "@react-stately/list": "^3.10.5", - "@react-types/shared": "^3.23.1", - "@react-types/tabs": "^3.3.7", + "@react-stately/list": "^3.10.7", + "@react-types/shared": "^3.24.1", + "@react-types/tabs": "^3.3.9", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/toggle": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.4.tgz", - "integrity": "sha512-CoYFe9WrhLkDP4HGDpJYQKwfiYCRBAeoBQHv+JWl5eyK61S8xSwoHsveYuEZ3bowx71zyCnNAqWRrmNOxJ4CKA==", + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.6.tgz", + "integrity": "sha512-xRZyrjNVu1VCd1xpg5RwmNYs9fXb+JHChoUaRcBmGCCjsPD0R5uR3iNuE17RXJtWS3/8o9IJVn90+/7NW7boOg==", "dependencies": { - "@react-stately/utils": "^3.10.1", - "@react-types/checkbox": "^3.8.1", + "@react-stately/utils": "^3.10.2", + "@react-types/checkbox": "^3.8.3", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/tooltip": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.9.tgz", - "integrity": "sha512-P7CDJsdoKarz32qFwf3VNS01lyC+63gXpDZG31pUu+EO5BeQd4WKN/AH1Beuswpr4GWzxzFc1aXQgERFGVzraA==", + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.11.tgz", + "integrity": "sha512-r1ScIXau2LZ/lUUBQ5PI01S2TB2urF2zrPzNM2xgngFLlG2uTyfIgMga6/035quQQKd3Bd0qGigMvTgZ3GRGEg==", "dependencies": { - "@react-stately/overlays": "^3.6.7", - "@react-types/tooltip": "^3.4.9", + "@react-stately/overlays": "^3.6.9", + "@react-types/tooltip": "^3.4.11", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/tree": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.1.tgz", - "integrity": "sha512-LOdkkruJWch3W89h4B/bXhfr0t0t1aRfEp+IMrrwdRAl23NaPqwl5ILHs4Xu5XDHqqhg8co73pHrJwUyiTWEjw==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.3.tgz", + "integrity": "sha512-9sRQOxkK7ZMdtSTGHx0sMabHC39PEM4tMl+IdJKkmcp60bfsm3p6LHXhha3E58jwnZaemBfUrlQmTP/E26BbGw==", "dependencies": { - "@react-stately/collections": "^3.10.7", - "@react-stately/selection": "^3.15.1", - "@react-stately/utils": "^3.10.1", - "@react-types/shared": "^3.23.1", + "@react-stately/collections": "^3.10.9", + "@react-stately/selection": "^3.16.1", + "@react-stately/utils": "^3.10.2", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/utils": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.1.tgz", - "integrity": "sha512-VS/EHRyicef25zDZcM/ClpzYMC5i2YGN6uegOeQawmgfGjb02yaCX0F0zR69Pod9m2Hr3wunTbtpgVXvYbZItg==", + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.2.tgz", + "integrity": "sha512-fh6OTQtbeQC0ywp6LJuuKs6tKIgFvt/DlIZEcIpGho6/oZG229UnIk6TUekwxnDbumuYyan6D9EgUtEMmT8UIg==", "dependencies": { "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-stately/virtualizer": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-3.7.1.tgz", - "integrity": "sha512-voHgE6EQ+oZaLv6u2umKxakvIKNkCQuUihqKACTjdslp7SJh4Mvs3oLBI0hf0JOh+rCcFIKDvQtFwy1fXFRYBA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-4.0.1.tgz", + "integrity": "sha512-HCje3SlLItQFAiBHH4JZhz74mMCe2g+Q8woJa6kdKlvFqsNdmhtFHuuIr1uW6LWj76j2N0Xaa8Z7fV1f5ovX0Q==", "dependencies": { - "@react-aria/utils": "^3.24.1", - "@react-types/shared": "^3.23.1", + "@react-aria/utils": "^3.25.1", + "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/actionbar": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@react-types/actionbar/-/actionbar-3.1.7.tgz", - "integrity": "sha512-yohxM+R9o/HGADL7NdTH9tC9BnWrVYKsutobjWzVQZHGoaHEqBbz03dk3m9UvFMnw7g6kjtGxhOJQpztz7nk3Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@react-types/actionbar/-/actionbar-3.1.9.tgz", + "integrity": "sha512-omCribEByWYcDr27W63LpmFq+muACc949UzCcMzlc6fvkKc6Gq+HjRRoTQjX6k8hXXFqEbQoYJFVyRXnig6u5g==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/actiongroup": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/@react-types/actiongroup/-/actiongroup-3.4.9.tgz", - "integrity": "sha512-n6lGBLm8HxLguG4om5ysMCexSdMWNhM5L0yGjA4pZxdoKZborPALDN/Ao57svnTwaSJmeExvTwHIFds1yr4AXQ==", + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@react-types/actiongroup/-/actiongroup-3.4.11.tgz", + "integrity": "sha512-gO/A+nbPoDwovqWlEyILNlfBY1loXFR0+P7OzH+vqppCHFz+Y2dF6Ry2LqUAmE0XPaYLzwg4Y/Nkuc20jIVujQ==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/avatar": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@react-types/avatar/-/avatar-3.0.7.tgz", - "integrity": "sha512-FXws1/o0Vy3yJcBDdKYPElNzpcVjdkck6KHGQyxAkKe7vvtFUcHpzz9fxEO5kRLwTv6j7EahXsJeqsH9TpFWuA==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@react-types/avatar/-/avatar-3.0.9.tgz", + "integrity": "sha512-lvzL0DHUaZxLXci9PbtnSWxO/vrcqyPm5KBq3DwiJ/FreAQZjbk7SfOO8we9mPXbe+XePexK/x9n90BtGMKdLw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/badge": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@react-types/badge/-/badge-3.1.9.tgz", - "integrity": "sha512-GNvg3cULRiUxXZYmOOIaua0KSL72jnLwv/2LLbQeYQystLaEmsibmdoRvfQN80mEQ1f3WFfhZogiG31+4MS/xg==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@react-types/badge/-/badge-3.1.11.tgz", + "integrity": "sha512-ToIZOT5xRAHqZ9H9v8UkcC+Gds4dKmmIAMb7+aWXGCKIuRlV4wLD1WZJBS9gQlv+WlwvIOEVOgtwktpTrZJW0Q==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/breadcrumbs": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.5.tgz", - "integrity": "sha512-lV9IDYsMiu2TgdMIjEmsOE0YWwjb3jhUNK1DCZZfq6uWuiHLgyx2EncazJBUWSjHJ4ta32j7xTuXch+8Ai6u/A==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.7.tgz", + "integrity": "sha512-ZmhXwD2LLzfEA2OvOCp/QvXu8A/Edsrn5q0qUDGsmOZj9SCVeT82bIv8P+mQnATM13mi2gyoik6102Jc1OscJA==", "dependencies": { - "@react-types/link": "^3.5.5", - "@react-types/shared": "^3.23.1" + "@react-types/link": "^3.5.7", + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/button": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.9.4.tgz", - "integrity": "sha512-raeQBJUxBp0axNF74TXB8/H50GY8Q3eV6cEKMbZFP1+Dzr09Ngv0tJBeW0ewAxAguNH5DRoMUAUGIXtSXskVdA==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.9.6.tgz", + "integrity": "sha512-8lA+D5JLbNyQikf8M/cPP2cji91aVTcqjrGpDqI7sQnaLFikM8eFR6l1ZWGtZS5MCcbfooko77ha35SYplSQvw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/buttongroup": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/@react-types/buttongroup/-/buttongroup-3.3.9.tgz", - "integrity": "sha512-3hEWI/GOsY8Z3db8gjEXbxl+6E0ioBNMxfN8jIeiNnSWSDG56MLNArJLowylPrwlrp5SnxLh1WBj44OHqEE3Tg==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@react-types/buttongroup/-/buttongroup-3.3.11.tgz", + "integrity": "sha512-29F+GYWdbjuheDZVW9xhju03CQVK401i0DPH7TGqnlNZqteqF/aHqwxRyFT8490ad7og3ZuvXywTBQCwIfbh9Q==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/calendar": { - "version": "3.4.6", - "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.6.tgz", - "integrity": "sha512-WSntZPwtvsIYWvBQRAPvuCn55UTJBZroTvX0vQvWykJRQnPAI20G1hMQ3dNsnAL+gLZUYxBXn66vphmjUuSYew==", + "version": "3.4.8", + "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.8.tgz", + "integrity": "sha512-KVampt/X4uJvWU0TsxIdgPdXIAUClGtxcDWHzuFRJ7YUYkA4rH8Lad0kQ1mVehnwOLpuba8j9GCYKorkbln0gw==", "dependencies": { - "@internationalized/date": "^3.5.4", - "@react-types/shared": "^3.23.1" + "@internationalized/date": "^3.5.5", + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/checkbox": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.1.tgz", - "integrity": "sha512-5/oVByPw4MbR/8QSdHCaalmyWC71H/QGgd4aduTJSaNi825o+v/hsN2/CH7Fq9atkLKsC8fvKD00Bj2VGaKriQ==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.3.tgz", + "integrity": "sha512-f4c1mnLEt0iS1NMkyZXgT3q3AgcxzDk7w6MSONOKydcnh0xG5L2oefY14DhVDLkAuQS7jThlUFwiAs+MxiO3MA==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/color": { - "version": "3.0.0-beta.25", - "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.0.0-beta.25.tgz", - "integrity": "sha512-D24ASvLeSWouBwOBi4ftUe4/BhrZj5AiHV7tXwrVeMGOy9Z9jyeK65Xysq+R3ecaSONLXsgai5CQMvj13cOacA==", + "version": "3.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.0.0-rc.1.tgz", + "integrity": "sha512-aw6FzrBlZTWKrFaFskM7e3AFICe6JqH10wO0E919goa3LZDDFbyYEwRpatwjIyiZH1elEUkFPgwqpv3ZcPPn8g==", "dependencies": { - "@react-types/shared": "^3.23.1", - "@react-types/slider": "^3.7.3" + "@react-types/shared": "^3.24.1", + "@react-types/slider": "^3.7.5" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/combobox": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.11.1.tgz", - "integrity": "sha512-UNc3OHt5cUt5gCTHqhQIqhaWwKCpaNciD8R7eQazmHiA9fq8ROlV+7l3gdNgdhJbTf5Bu/V5ISnN7Y1xwL3zqQ==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.12.1.tgz", + "integrity": "sha512-bd5YwHZWtgnJx4jGbplWbYzXj7IbO5w3IY5suNR7r891rx6IktquZ8GQwyYH0pQ/x+X5LdK2xI59i6+QC2PmlA==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/contextualhelp": { - "version": "3.2.10", - "resolved": "https://registry.npmjs.org/@react-types/contextualhelp/-/contextualhelp-3.2.10.tgz", - "integrity": "sha512-x4rODNQfAO2YeVumkztTsUieOt4z7OXolZY7BLJgT1qonfPwJGLqf+KUayqXuX9l2CHakcGYDGaUxTUvwINQdw==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/@react-types/contextualhelp/-/contextualhelp-3.2.12.tgz", + "integrity": "sha512-5PwE2tajqVYzjatdvux6dpGb8trmqGBDp04nuTn010U+HZhxylAe12iU0/Lz+0M7dWpBlVfusE42TLvZdD5VzA==", "dependencies": { - "@react-types/overlays": "^3.8.7", - "@react-types/shared": "^3.23.1" + "@react-types/overlays": "^3.8.9", + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/datepicker": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.7.4.tgz", - "integrity": "sha512-ZfvgscvNzBJpYyVWg3nstJtA/VlWLwErwSkd1ivZYam859N30w8yH+4qoYLa6FzWLCFlrsRHyvtxlEM7lUAt5A==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.8.1.tgz", + "integrity": "sha512-ZpxHHVT3rmZ4YsYP4TWCZSMSfOUm+067mZyyGLmvHxg55eYmctiB4uMgrRCqDoeiSiOjtxad0VtpPjf6ftK1GQ==", "dependencies": { - "@internationalized/date": "^3.5.4", - "@react-types/calendar": "^3.4.6", - "@react-types/overlays": "^3.8.7", - "@react-types/shared": "^3.23.1" + "@internationalized/date": "^3.5.5", + "@react-types/calendar": "^3.4.8", + "@react-types/overlays": "^3.8.9", + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/dialog": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.10.tgz", - "integrity": "sha512-S9ga+edOLNLZw7/zVOnZdT5T40etpzUYBXEKdFPbxyPYnERvRxJAsC1/ASuBU9fQAXMRgLZzADWV+wJoGS/X9g==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.12.tgz", + "integrity": "sha512-JmpQbSpXltqEyYfEwoqDolABIiojeExkqolHNdQlayIsfFuSxZxNwXZPOpz58Ri/iwv21JP7K3QF0Gb2Ohxl9w==", "dependencies": { - "@react-types/overlays": "^3.8.7", - "@react-types/shared": "^3.23.1" + "@react-types/overlays": "^3.8.9", + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/divider": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/@react-types/divider/-/divider-3.3.9.tgz", - "integrity": "sha512-SQ3XWS16j3VZg3MGByJ1CjWDfARn+viBDay6SibAFzMqlqVbSol2nw1hQ1JPaT3zeW8C/354q+OhBsIFDOaE7w==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@react-types/divider/-/divider-3.3.11.tgz", + "integrity": "sha512-pnyEhIK21K8K10cvkXID1yx4V8jpY5uRO69o8npyq846p7RSercGGGQNE/vPSJXEViZrXTrf2KyNSPFU2x5INw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/form": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@react-types/form/-/form-3.7.4.tgz", - "integrity": "sha512-HZojAWrb6feYnhDEOy3vBamDVAHDl0l2JQZ7aIDLHmeTAGQC3JNZcm2fLTxqLye46zz8w8l8OHgI+NdD4PHdOw==", + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/@react-types/form/-/form-3.7.6.tgz", + "integrity": "sha512-lhS2y1bVtRnyYjkM+ylJUp2g663ZNbeZxu2o+mFfD5c2wYmVLA58IWR90c7DL8IVUitoANnZ1JPhhXvutiFpQQ==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/grid": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.6.tgz", - "integrity": "sha512-XfHenL2jEBUYrhKiPdeM24mbLRXUn79wVzzMhrNYh24nBwhsPPpxF+gjFddT3Cy8dt6tRInfT6pMEu9nsXwaHw==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.8.tgz", + "integrity": "sha512-6PJrpukwMqlv3IhJSDkJuVbhHM8Oe6hd2supWqd9adMXrlSP7QHt9a8SgFcFblCCTx8JzUaA0PvY5sTudcEtOQ==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/illustratedmessage": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/@react-types/illustratedmessage/-/illustratedmessage-3.3.9.tgz", - "integrity": "sha512-a/X+sGzUA+pkLkKDZzy/QpUtOY6qtFpsPs6lfY37TLwCEQmS8a1VKrc1ItlQVRgIvwuqJXKvrJpGOAw+RjVwHw==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@react-types/illustratedmessage/-/illustratedmessage-3.3.11.tgz", + "integrity": "sha512-GW3DCRU1YHv1VteVSTOUN3FH4Z5FCm22k5yTjhb8NjNP0eQ/tH3Gu6pZCVKTiqmuC2Z15nXZGdcPMmzKA8915Q==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/image": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-types/image/-/image-3.4.1.tgz", - "integrity": "sha512-6vA3vEzjXrr701i1J43DkyPziRN7jfKSdarGDP+61dOcvbiLnuTY9t+r/zXo1SdewbjF5RVliB2ys9Bb654YTg==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@react-types/image/-/image-3.4.3.tgz", + "integrity": "sha512-w5oxRYDKTGXHZr4CtLdi8759v2YU3Qux6kPj4fRq67hYRCKQxJOYdqQTlfLwkshe/ddFPb3Geu5GTdQtW+GnDw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/label": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@react-types/label/-/label-3.9.3.tgz", - "integrity": "sha512-PGVg/pBYNx3Ft59VNCvG5oqk4pXfS2Gs7t3TGnlBB1d+EXB9BbixJbOAO1PvRqt8SPCNvEAAAVfG6Vf+nOhSWw==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@react-types/label/-/label-3.9.5.tgz", + "integrity": "sha512-kvkPX/S7acwX2E5usekJjpFYFQyykbKFharQvYn06x4sYHevRnxzcRgPkaBynaTu2i5MeQ/Yot7VwyBfEleqSA==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/layout": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/@react-types/layout/-/layout-3.3.15.tgz", - "integrity": "sha512-Rj3M0TWmsag83gvFDY6UnfUkNPrA/FLuJ0kEiOryjjffoI0wTxmTAPpIgG4h7YSxpQJD6g6xQ8bkIWEMCXWyag==", + "version": "3.3.17", + "resolved": "https://registry.npmjs.org/@react-types/layout/-/layout-3.3.17.tgz", + "integrity": "sha512-CoDVto9eq9ZX65SSrPS4XSEZKBvKdnBs41B217Yai2K/s5VyyEJ0zOGtohghJOnalBCG7Ci4if8VnE27lonvcQ==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/link": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.5.tgz", - "integrity": "sha512-G6P5WagHDR87npN7sEuC5IIgL1GsoY4WFWKO4734i2CXRYx24G9P0Su3AX4GA3qpspz8sK1AWkaCzBMmvnunfw==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.7.tgz", + "integrity": "sha512-2WyaVmm1qr9UrSG3Dq6iz+2ziuVp+DH8CsYZ9CA6aNNb6U18Hxju3LTPb4a5gM0eC7W0mQGNBmrgGlAdDZEJOw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/listbox": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.4.9.tgz", - "integrity": "sha512-S5G+WmNKUIOPZxZ4svWwWQupP3C6LmVfnf8QQmPDvwYXGzVc0WovkqUWyhhjJirFDswTXRCO9p0yaTHHIlkdwQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.5.1.tgz", + "integrity": "sha512-n5bOgD9lgfK1qaLtag9WPnu151SwXBCNn/OgGY/Br9mWRl+nPUEYtFcPX+2VCld7uThf54kwrTmzlFnaraIlcw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/menu": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.9.tgz", - "integrity": "sha512-FamUaPVs1Fxr4KOMI0YcR2rYZHoN7ypGtgiEiJ11v/tEPjPPGgeKDxii0McCrdOkjheatLN1yd2jmMwYj6hTDg==", + "version": "3.9.11", + "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.11.tgz", + "integrity": "sha512-IguQVF70d7aHXgWB1Rd2a/PiIuLZ2Nt7lyayJshLcy/NLOYmgpTmTyn2WCtlA5lTfQwmQrNFf4EvnWkeljJXdA==", "dependencies": { - "@react-types/overlays": "^3.8.7", - "@react-types/shared": "^3.23.1" + "@react-types/overlays": "^3.8.9", + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/meter": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.1.tgz", - "integrity": "sha512-AIJV4NDFAqKH94s02c5Da4TH2qgJjfrw978zuFM0KUBFD85WRPKh7MvgWpomvUgmzqE6lMCzIdi1KPKqrRabdw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.3.tgz", + "integrity": "sha512-Y2fX5CTAPGRKxVSeepbeyN6/K+wlF9pMRcNxTSU2qDwdoFqNCtTWMcWuCsU/Y2L/zU0jFWu4x0Vo7WkrcsgcMA==", "dependencies": { - "@react-types/progress": "^3.5.4" + "@react-types/progress": "^3.5.6" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/numberfield": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.3.tgz", - "integrity": "sha512-z5fGfVj3oh5bmkw9zDvClA1nDBSFL9affOuyk2qZ/M2SRUmykDAPCksbfcMndft0XULWKbF4s2CYbVI+E/yrUA==", + "version": "3.8.5", + "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.5.tgz", + "integrity": "sha512-LVWggkxwd1nyVZomXBPfQA1E4I4/i4PBifjcDs2AfcV7q5RE9D+DVIDXsYucVOBxPlDOxiAq/T9ypobspWSwHw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/overlays": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.7.tgz", - "integrity": "sha512-zCOYvI4at2DkhVpviIClJ7bRrLXYhSg3Z3v9xymuPH3mkiuuP/dm8mUCtkyY4UhVeUTHmrQh1bzaOP00A+SSQA==", + "version": "3.8.9", + "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.9.tgz", + "integrity": "sha512-9ni9upQgXPnR+K9cWmbYWvm3ll9gH8P/XsEZprqIV5zNLMF334jADK48h4jafb1X9RFnj0WbHo6BqcSObzjTig==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/progress": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.4.tgz", - "integrity": "sha512-JNc246sTjasPyx5Dp7/s0rp3Bz4qlu4LrZTulZlxWyb53WgBNL7axc26CCi+I20rWL9+c7JjhrRxnLl/1cLN5g==", + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.6.tgz", + "integrity": "sha512-Nh43sjQ5adyN1bTHBPRaIPhXUdBqP0miYeJpeMY3V/KUl4qmouJLwDnccwFG4xLm6gBfYe22lgbbV7nAfNnuTQ==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/provider": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-types/provider/-/provider-3.8.1.tgz", - "integrity": "sha512-Sm59ufxdHh6fGfeUbviNQhRvtI0FMEX1gn9Okc8nL7iTVbAAitT746x0itM+xwhFLDI6gSY8FILDWc5/kIxzxA==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@react-types/provider/-/provider-3.8.3.tgz", + "integrity": "sha512-tUt/94BRS0gZFprBAErYXauyONGcJM8ZWLCae925kZ3iLdzRWxG5qoNyKZ3SRKODdLDvJAgmPjImpj8GzYc3Fg==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/radio": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.1.tgz", - "integrity": "sha512-bK0gio/qj1+0Ldu/3k/s9BaOZvnnRgvFtL3u5ky479+aLG5qf1CmYed3SKz8ErZ70JkpuCSrSwSCFf0t1IHovw==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.3.tgz", + "integrity": "sha512-fUVJt4Bb6jOReFqnhHVNxWXH7t6c60uSFfoPKuXt/xI9LL1i2jhpur0ggpTfIn3qLIAmNBU6bKBCWAdr4KjeVQ==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/searchfield": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.5.tgz", - "integrity": "sha512-T/NHg12+w23TxlXMdetogLDUldk1z5dDavzbnjKrLkajLb221bp8brlR/+O6C1CtFpuJGALqYHgTasU1qkQFSA==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.7.tgz", + "integrity": "sha512-dyuPwNWGswRZfb4i50Q1Q3tCwTBxRLkrAxcMs+Rf2Rl4t93bawBdSdIQuvxu1KEhgd0EXA9ZUW53ZplqfVmtiw==", "dependencies": { - "@react-types/shared": "^3.23.1", - "@react-types/textfield": "^3.9.3" + "@react-types/shared": "^3.24.1", + "@react-types/textfield": "^3.9.5" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/select": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.4.tgz", - "integrity": "sha512-xI7dnOW2st91fPPcv6hdtrTdcfetYiqZuuVPZ5TRobY7Q10/Zqqe/KqtOw1zFKUj9xqNJe4Ov3xP5GSdcO60Eg==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.6.tgz", + "integrity": "sha512-cVSFR0eJLup/ht1Uto+y8uyLmHO89J6wNh65SIHb3jeVz9oLBAedP3YNI2qB+F9qFMUcA8PBSLXIIuT6gXzLgQ==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/shared": { - "version": "3.23.1", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.23.1.tgz", - "integrity": "sha512-5d+3HbFDxGZjhbMBeFHRQhexMFt4pUce3okyRtUVKbbedQFUrtXSBg9VszgF2RTeQDKDkMCIQDtz5ccP/Lk1gw==", + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.24.1.tgz", + "integrity": "sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw==", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/slider": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.3.tgz", - "integrity": "sha512-F8qFQaD2mqug2D0XeWMmjGBikiwbdERFlhFzdvNGbypPLz3AZICBKp1ZLPWdl0DMuy03G/jy6Gl4mDobl7RT2g==", + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.5.tgz", + "integrity": "sha512-bRitwQRQjQoOcKEdPMljnvm474dwrmsc6pdsVQDh/qynzr+KO9IHuYc3qPW53WVE2hMQJDohlqtCAWQXWQ5Vcg==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/statuslight": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/@react-types/statuslight/-/statuslight-3.3.9.tgz", - "integrity": "sha512-6nC17gluvrMCJkb0mihzqAaz8wn0ghfgk1ILkL8CUobsqJU6pW4eGJXNoZCd5wHT/YjwnupzfhHcbMj93AHzWQ==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@react-types/statuslight/-/statuslight-3.3.11.tgz", + "integrity": "sha512-EYxya+R4PpgB1V8pcn2w4fgFbPMCuya+TeYDoO6Izp3AQRWYgQRwM8Gz3IQ/qXFvwzT9e1fEuOHPHqPW1Tiitw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/switch": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.3.tgz", - "integrity": "sha512-Nb6+J5MrPaFa8ZNFKGMzAsen/NNzl5UG/BbC65SLGPy7O0VDa/sUpn7dcu8V2xRpRwwIN/Oso4v63bt2sgdkgA==", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.5.tgz", + "integrity": "sha512-SZx1Bd+COhAOs/RTifbZG+uq/llwba7VAKx7XBeX4LeIz1dtguy5bigOBgFTMQi4qsIVCpybSWEEl+daj4XFPw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/table": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.9.5.tgz", - "integrity": "sha512-fgM2j9F/UR4Anmd28CueghCgBwOZoCVyN8fjaIFPd2MN4gCwUUfANwxLav65gZk4BpwUXGoQdsW+X50L3555mg==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.10.1.tgz", + "integrity": "sha512-xsNh0Gm4GtNeSknZqkMsfGvc94fycmfhspGO+FzQKim2hB5k4yILwd+lHYQ2UKW6New9GVH/zN2Pd3v67IeZ2g==", "dependencies": { - "@react-types/grid": "^3.2.6", - "@react-types/shared": "^3.23.1" + "@react-types/grid": "^3.2.8", + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/tabs": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.7.tgz", - "integrity": "sha512-ZdLe5xOcFX6+/ni45Dl2jO0jFATpTnoSqj6kLIS/BYv8oh0n817OjJkLf+DS3CLfNjApJWrHqAk34xNh6nRnEg==", + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.9.tgz", + "integrity": "sha512-3Q9kRVvg/qDyeJR/W1+C2z2OyvDWQrSLvOCvAezX5UKzww4rBEAA8OqBlyDwn7q3fiwrh/m64l6p+dbln+RdxQ==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/text": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/@react-types/text/-/text-3.3.9.tgz", - "integrity": "sha512-JJTmUstFXikZHQhf+0VELODGz1jUcSgXOTYJxTMiMtSjLOSCW5G+pRhT80MRgxOeuD0Z7p0XghUXo3ruD694HA==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@react-types/text/-/text-3.3.11.tgz", + "integrity": "sha512-e78lt//FlmrJSPNgZZYT2LoBXFqoG5MX/kaS738bO9WkUR4nE1wtBBMmztQxQTvqz0cV/gaJEHZla4Orp+Civw==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/textfield": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.3.tgz", - "integrity": "sha512-DoAY6cYOL0pJhgNGI1Rosni7g72GAt4OVr2ltEx2S9ARmFZ0DBvdhA9lL2nywcnKMf27PEJcKMXzXc10qaHsJw==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.5.tgz", + "integrity": "sha512-0hwZI4WXSEStPzdltKwbNUZWlgHtwbxMWE0LfqIzEW8RB7DyBflYSKzLyTBFqwUZ8j3C1gWy9c9OPSeCOq792Q==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/tooltip": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.9.tgz", - "integrity": "sha512-wZ+uF1+Zc43qG+cOJzioBmLUNjRa7ApdcT0LI1VvaYvH5GdfjzUJOorLX9V/vAci0XMJ50UZ+qsh79aUlw2yqg==", + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.11.tgz", + "integrity": "sha512-WPikHQxeT5Lb09yJEaW6Ja3ecE0g1YM6ukWYS2v/iZLUPn5YlYrGytspuCYQNSh/u7suCz4zRLEHYCl7OCigjw==", "dependencies": { - "@react-types/overlays": "^3.8.7", - "@react-types/shared": "^3.23.1" + "@react-types/overlays": "^3.8.9", + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/view": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/@react-types/view/-/view-3.4.9.tgz", - "integrity": "sha512-HY969whOXKg10ZqIrXOF12wm3rDwNaKaK9fzqhhrUc94+JR4OPKQctps+HeonAXscxy2yMy8V1/2yjiEwluvAA==", + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@react-types/view/-/view-3.4.11.tgz", + "integrity": "sha512-FgWQGppdqAHfnRUyjc01nRdMKSEpJBze99+k+xscW+Lv6XNXQR3PlC8QOpcEZ4gGy9Xx1YkbKHDX1eOCNTeYnA==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-types/well": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/@react-types/well/-/well-3.3.9.tgz", - "integrity": "sha512-3ZlxjkWXupxx0PaxpDc4Pqxxgnzp8iJkilbJ3LY5F+RJwqDm0gkKnWcFjlVJw9LkM7Emjrvm1R8naSGzJ7wJ2A==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@react-types/well/-/well-3.3.11.tgz", + "integrity": "sha512-xHe0t/4ndLIG5nrbGBEFJCeYuni4VML8t6rwEOWbQTTke6DSYZ53DPL7aepO4IP1hW0ufEOJ0WV7Bx7YTUMu+Q==", "dependencies": { - "@react-types/shared": "^3.23.1" + "@react-types/shared": "^3.24.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@rkusa/linebreak": { @@ -7099,11 +7103,11 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" }, "node_modules/@sindresorhus/is": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.3.1.tgz", - "integrity": "sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.0.0.tgz", + "integrity": "sha512-WDTlVTyvFivSOuyvMeedzg2hdoBLZ3f1uNVuEida2Rl9BrfjrIRjWA/VZIrMRLvSwJYCAlCRA3usDt1THytxWQ==", "engines": { - "node": ">=16" + "node": ">=18" }, "funding": { "url": "https://github.com/sindresorhus/is?sponsor=1" @@ -7115,31 +7119,31 @@ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" }, "node_modules/@spectrum-icons/ui": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/@spectrum-icons/ui/-/ui-3.6.7.tgz", - "integrity": "sha512-l08Juk6w8UUpM+xXNVq9LBJ0pxMC1tynXBurTZ135twdtMwofrZmtSHUYdzaRJtm31S9E/+C1Toci1I8aw7Wlw==", + "version": "3.6.9", + "resolved": "https://registry.npmjs.org/@spectrum-icons/ui/-/ui-3.6.9.tgz", + "integrity": "sha512-pxgEoSfce2Vcijh+lizPgCPwAIaBYkOHwWaOXTEHn9REglAnMADdmyAyxib84JSxVY5funJ3AWPKYbEEICEXIg==", "dependencies": { - "@adobe/react-spectrum-ui": "1.2.0", - "@react-spectrum/icon": "^3.7.13", + "@adobe/react-spectrum-ui": "1.2.1", + "@react-spectrum/icon": "^3.7.15", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@spectrum-icons/workflow": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@spectrum-icons/workflow/-/workflow-4.2.12.tgz", - "integrity": "sha512-xuyytdlM09DEZO7/vSp5z8Y2RYNXL4OOYSmOaWXeYgIa3iPNKz0HW+iVR2P+Ht0iBtKjPvRobbEFb0k280U4yQ==", + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@spectrum-icons/workflow/-/workflow-4.2.14.tgz", + "integrity": "sha512-wPz3T8sKJCM/o2sWLjHBL/tO2DmD+10zK/AjnbCoytyeMTxniUfMr7i4RM+E/H9uCUcswL9/QFX7kbgArj0A7Q==", "dependencies": { - "@adobe/react-spectrum-workflow": "2.3.4", - "@react-spectrum/icon": "^3.7.13", + "@adobe/react-spectrum-workflow": "2.3.5", + "@react-spectrum/icon": "^3.7.15", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "@react-spectrum/provider": "^3.0.0", - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/@swc/helpers": { @@ -8835,9 +8839,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", + "version": "4.3.17", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.17.tgz", + "integrity": "sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==", "dev": true }, "node_modules/@types/color": { @@ -9163,15 +9167,21 @@ "@types/ms": "*" } }, + "node_modules/@types/dom-mediacapture-record": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/@types/dom-mediacapture-record/-/dom-mediacapture-record-1.0.19.tgz", + "integrity": "sha512-Cz/85z3YTuUPnXrOp5MvSZZSgDkWTWvj1HgE7MWc5C8d/w/soJBXjnAoYDl4P5gmenDNNZkhXzNylGqxS1FzOw==", + "dev": true + }, "node_modules/@types/dom-speech-recognition": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/@types/dom-speech-recognition/-/dom-speech-recognition-0.0.4.tgz", "integrity": "sha512-zf2GwV/G6TdaLwpLDcGTIkHnXf8JEf/viMux+khqKQKDa8/8BAUtXXZS563GnvJ4Fg0PBLGAaFf2GekEVSZ6GQ==" }, "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "version": "8.56.11", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.11.tgz", + "integrity": "sha512-sVBpJMf7UPo/wGecYOpk2aQya2VUGeHhe38WG7/mN5FufNSubf5VT9Uh9Uyp8/eLJpu1/tuhJ/qTo4mhSB4V4Q==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -9253,9 +9263,9 @@ "integrity": "sha512-IGKtSn0Lonfx3HdK6KMcfd5GUc1xdeLtjW1n7ZSA5Tmn1n2gj878q6IC0s4MbF9KtBpXIRqjRQxBzi2kF4WvGw==" }, "node_modules/@types/fluent-ffmpeg": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.24.tgz", - "integrity": "sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==", + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.25.tgz", + "integrity": "sha512-a9/Jtv/RVaCG4lUwWIcuClWE5eXJFoFS/oHOecOv/RS8n+lQdJzcJVmDlxA8Xbk4B82YpO88Dijcoljb6sYTcA==", "dependencies": { "@types/node": "*" } @@ -9333,9 +9343,9 @@ "dev": true }, "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "dev": true, "dependencies": { "@types/node": "*" @@ -9366,6 +9376,7 @@ "version": "3.5.30", "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.30.tgz", "integrity": "sha512-nbWKkkyb919DOUxjmRVk8vwtDb0/k8FKncmUKFi+NY+QXqWltooxTrswvz4LspQwxvLdvzBN1TImr6cw3aQx2A==", + "dev": true, "dependencies": { "@types/sizzle": "*" } @@ -9423,9 +9434,9 @@ } }, "node_modules/@types/mapbox-gl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.1.0.tgz", - "integrity": "sha512-hI6cQDjw1bkJw7MC/eHMqq5TWUamLwsujnUUeiIX2KDRjxRNSYMjnHz07+LATz9I9XIsKumOtUz4gRYnZOJ/FA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.4.0.tgz", + "integrity": "sha512-tbn++Mm94H1kE7W6FF0oVC9rMXHVzDDNUbS7KfBMRF8NV/8csFi+67ytKcZJ4LsrpsJ+8MC6Os6ZinEDCsrunw==", "dependencies": { "@types/geojson": "*" } @@ -9462,9 +9473,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", "dependencies": { "undici-types": "~5.26.4" } @@ -9789,7 +9800,8 @@ "node_modules/@types/sizzle": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", - "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==" + "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", + "dev": true }, "node_modules/@types/sockjs": { "version": "0.3.36", @@ -9825,10 +9837,17 @@ "@types/geojson": "*" } }, + "node_modules/@types/textarea-caret": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/textarea-caret/-/textarea-caret-3.0.3.tgz", + "integrity": "sha512-bsA9GdXV1wQsXyDjS5+A+czz8IAR3haH5DU+KctIoXbzobRL2NOiwF/+EbB7pofAyudMytLj4ihPtbmbJT8FWw==", + "dev": true + }, "node_modules/@types/textfit": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/textfit/-/textfit-2.4.4.tgz", "integrity": "sha512-AYlNcJ5j/WspQfbHIhoF0Wo63F5+REnX/VPFSH5unUUuwRcr6IoXxZki3vYhG4DRVUQe51AsFYyRxml5u+qaAg==", + "dev": true, "dependencies": { "@types/jquery": "*" } @@ -9887,6 +9906,15 @@ "webpack": "^5" } }, + "node_modules/@types/webscopeio__react-textarea-autocomplete": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/@types/webscopeio__react-textarea-autocomplete/-/webscopeio__react-textarea-autocomplete-4.7.5.tgz", + "integrity": "sha512-B9YZ5KrKRcNNsh2v7tyc/tZ1rrPoyWoaXQvvfcG9pX85w9jy2HLnPPT7Kfms5TgzR3RGQ5TIvXQvmsizxdohyQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/whatwg-url": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", @@ -9896,18 +9924,18 @@ } }, "node_modules/@types/ws": { - "version": "8.5.11", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", - "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dependencies": { "@types/yargs-parser": "*" } @@ -9924,16 +9952,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", - "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/type-utils": "7.16.1", - "@typescript-eslint/utils": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -9957,14 +9985,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", - "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", - "dependencies": { - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { @@ -9984,12 +10012,12 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -10000,13 +10028,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", - "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -10027,9 +10055,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "engines": { "node": "^18.18.0 || >=20.0.0" }, @@ -10039,12 +10067,12 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -10077,15 +10105,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", - "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1" + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -10099,11 +10127,11 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dependencies": { - "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -10120,55 +10148,55 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@vue/compiler-core": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.33.tgz", - "integrity": "sha512-MoIREbkdPQlnGfSKDMgzTqzqx5nmEjIc0ydLVYlTACGBsfvOJ4tHSbZXKVF536n6fB+0eZaGEOqsGThPpdvF5A==", + "version": "3.4.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.37.tgz", + "integrity": "sha512-ZDDT/KiLKuCRXyzWecNzC5vTcubGz4LECAtfGPENpo0nrmqJHwuWtRLxk/Sb9RAKtR9iFflFycbkjkY+W/PZUQ==", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/shared": "3.4.33", - "entities": "^4.5.0", + "@vue/shared": "3.4.37", + "entities": "^5.0.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.33.tgz", - "integrity": "sha512-GzB8fxEHKw0gGet5BKlpfXEqoBnzSVWwMnT+dc25wE7pFEfrU/QsvjZMP9rD4iVXHBBoemTct8mN0GJEI6ZX5A==", + "version": "3.4.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.37.tgz", + "integrity": "sha512-rIiSmL3YrntvgYV84rekAtU/xfogMUJIclUMeIKEtVBFngOL3IeZHhsH3UaFEgB5iFGpj6IW+8YuM/2Up+vVag==", "dependencies": { - "@vue/compiler-core": "3.4.33", - "@vue/shared": "3.4.33" + "@vue/compiler-core": "3.4.37", + "@vue/shared": "3.4.37" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.33.tgz", - "integrity": "sha512-7rk7Vbkn21xMwIUpHQR4hCVejwE6nvhBOiDgoBcR03qvGqRKA7dCBSsHZhwhYUsmjlbJ7OtD5UFIyhP6BY+c8A==", + "version": "3.4.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.37.tgz", + "integrity": "sha512-vCfetdas40Wk9aK/WWf8XcVESffsbNkBQwS5t13Y/PcfqKfIwJX2gF+82th6dOpnpbptNMlMjAny80li7TaCIg==", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/compiler-core": "3.4.33", - "@vue/compiler-dom": "3.4.33", - "@vue/compiler-ssr": "3.4.33", - "@vue/shared": "3.4.33", + "@vue/compiler-core": "3.4.37", + "@vue/compiler-dom": "3.4.37", + "@vue/compiler-ssr": "3.4.37", + "@vue/shared": "3.4.37", "estree-walker": "^2.0.2", "magic-string": "^0.30.10", - "postcss": "^8.4.39", + "postcss": "^8.4.40", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.33.tgz", - "integrity": "sha512-0WveC9Ai+eT/1b6LCV5IfsufBZ0HP7pSSTdDjcuW302tTEgoBw8rHVHKPbGUtzGReUFCRXbv6zQDDgucnV2WzQ==", + "version": "3.4.37", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.37.tgz", + "integrity": "sha512-TyAgYBWrHlFrt4qpdACh8e9Ms6C/AZQ6A6xLJaWrCL8GCX5DxMzxyeFAEMfU/VFr4tylHm+a2NpfJpcd7+20XA==", "dependencies": { - "@vue/compiler-dom": "3.4.33", - "@vue/shared": "3.4.33" + "@vue/compiler-dom": "3.4.37", + "@vue/shared": "3.4.37" } }, "node_modules/@vue/shared": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.33.tgz", - "integrity": "sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA==" + "version": "3.4.37", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.37.tgz", + "integrity": "sha512-nIh8P2fc3DflG8+5Uw8PT/1i17ccFn0xxN/5oE9RfV5SVnd7G0XEFRwakrnNFE/jlS95fpGXDVG5zDETS26nmg==" }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", @@ -10439,9 +10467,9 @@ } }, "node_modules/adm-zip": { - "version": "0.5.14", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.14.tgz", - "integrity": "sha512-DnyqqifT4Jrcvb8USYjp6FHtBpEIz1mnXu6pTRHZ0RL69LbQYiO+0lDFg5+OKA7U29oWSs3a/i8fhn8ZcceIWg==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.15.tgz", + "integrity": "sha512-jYPWSeOA8EFoZnucrKCNihqBjoEGQSU4HKgHYQgKNEQ0pQF9a/DYuo/+fAxY76k4qe75LUlLWpAM1QWcBMTOKw==", "engines": { "node": ">=12.0" } @@ -11049,23 +11077,23 @@ } }, "node_modules/aws4": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", - "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==" + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.1.tgz", + "integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==" }, "node_modules/axe-core": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", - "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", + "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", + "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -11203,12 +11231,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -14655,9 +14683,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", - "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "funding": [ { "type": "opencollective", @@ -14673,9 +14701,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.0" }, "bin": { @@ -14823,32 +14851,6 @@ "node": ">=18" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -14912,9 +14914,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001643", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", - "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", "funding": [ { "type": "opencollective", @@ -15750,9 +15752,9 @@ } }, "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "version": "3.38.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.0.tgz", + "integrity": "sha512-XPpwqEodRljce9KswjZShh95qJ1URisBeKCjUdq27YdenkslVe7OO0ZJhlYXAChW7OhXaRLl8AAba7IBfoIHug==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -15760,11 +15762,11 @@ } }, "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "version": "3.38.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.0.tgz", + "integrity": "sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==", "dependencies": { - "browserslist": "^4.23.0" + "browserslist": "^4.23.3" }, "funding": { "type": "opencollective", @@ -15772,9 +15774,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", - "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==", + "version": "3.38.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.0.tgz", + "integrity": "sha512-8balb/HAXo06aHP58mZMtXgD8vcnXz9tUDePgqBgJgKdmTlMt+jw3ujqniuBDQXMvTzxnMpxHFeuSM3g1jWQuQ==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -16080,9 +16082,9 @@ } }, "node_modules/csv-stringify": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.5.0.tgz", - "integrity": "sha512-edlXFVKcUx7r8Vx5zQucsuMg4wb/xT6qyz+Sr1vnLrdXqlLD1+UKyWNyZ9zn6mUW1ewmGxrpVwAcChGF0HQ/2Q==" + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.5.1.tgz", + "integrity": "sha512-+9lpZfwpLntpTIEpFbwQyWuW/hmI/eHuJZD1XzeZpfZTqkf1fyvBbBLXTJJMsBuuS11uTShMqPwzx4A6ffXgRQ==" }, "node_modules/csvtojson": { "version": "2.0.10", @@ -16106,9 +16108,9 @@ "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==" }, "node_modules/cytoscape": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.1.tgz", - "integrity": "sha512-TRJc3HbBPkHd50u9YfJh2FxD1lDLZ+JXnJoyBn5LkncoeuT7fapO/Hq/Ed8TdFclaKshzInge2i30bg7VKeoPQ==", + "version": "3.30.2", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.2.tgz", + "integrity": "sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==", "engines": { "node": ">=0.10" } @@ -16677,9 +16679,9 @@ "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==" }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dependencies": { "ms": "2.1.2" }, @@ -17143,6 +17145,17 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/dom-walk": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", @@ -17258,9 +17271,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.832", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.832.tgz", - "integrity": "sha512-cTen3SB0H2SGU7x467NRe1eVcQgcuS6jckKfWJHia2eo0cHIGOqHoAxevIYZD4eRHcWjkvFzo93bi3vJ9W+1lA==" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz", + "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==" }, "node_modules/elkjs": { "version": "0.9.3", @@ -17369,9 +17382,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -17381,9 +17394,9 @@ } }, "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-5.0.0.tgz", + "integrity": "sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==", "engines": { "node": ">=0.12" }, @@ -19634,9 +19647,9 @@ "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" }, "node_modules/fast-xml-parser": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", - "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", "funding": [ { "type": "github", @@ -20082,9 +20095,9 @@ } }, "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -20699,11 +20712,26 @@ } }, "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, "engines": { - "node": ">=16" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -20852,9 +20880,9 @@ } }, "node_modules/globals": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", - "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==", + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", + "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", "dev": true, "engines": { "node": ">=18" @@ -20904,9 +20932,9 @@ "integrity": "sha512-sIVQCiRWOymHbVD1Aw/T9/ijbPYAVGBlgGYd1N9MRKfcyBNSpjr87Vg9nSHm+RCT8ELrvK8IJYJV0QRJuVUkCQ==" }, "node_modules/google-auth-library": { - "version": "9.11.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.11.0.tgz", - "integrity": "sha512-epX3ww/mNnhl6tL45EQ/oixsY8JLEgUFoT4A5E/5iAR4esld9Kqv6IJGk7EmGuOgDvaarwF95hU2+v7Irql9lw==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.13.0.tgz", + "integrity": "sha512-p9Y03Uzp/Igcs36zAaB0XTSwZ8Y0/tpYiz5KIde5By+H9DCVUSYtDWZu6aFXsWTqENMb8BD/pDT3hR8NVrPkfA==", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", @@ -20996,17 +21024,16 @@ } }, "node_modules/got": { - "version": "14.4.1", - "resolved": "https://registry.npmjs.org/got/-/got-14.4.1.tgz", - "integrity": "sha512-IvDJbJBUeexX74xNQuMIVgCRRuNOm5wuK+OC3Dc2pnSoh1AOmgc7JVj7WC+cJ4u0aPcO9KZ2frTXcqK4W/5qTQ==", + "version": "14.4.2", + "resolved": "https://registry.npmjs.org/got/-/got-14.4.2.tgz", + "integrity": "sha512-+Te/qEZ6hr7i+f0FNgXx/6WQteSM/QqueGvxeYQQFm0GDfoxLVJ/oiwUKYMTeioColWUTdewZ06hmrBjw6F7tw==", "dependencies": { - "@sindresorhus/is": "^6.3.1", + "@sindresorhus/is": "^7.0.0", "@szmarczak/http-timer": "^5.0.1", "cacheable-lookup": "^7.0.0", "cacheable-request": "^12.0.1", "decompress-response": "^6.0.0", "form-data-encoder": "^4.0.2", - "get-stream": "^8.0.1", "http2-wrapper": "^2.2.1", "lowercase-keys": "^3.0.0", "p-cancelable": "^4.0.1", @@ -21609,6 +21636,17 @@ "entities": "^4.4.0" } }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/http-browserify": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/http-browserify/-/http-browserify-1.7.0.tgz", @@ -23763,9 +23801,9 @@ } }, "node_modules/launch-editor": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", - "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", + "integrity": "sha512-elBx2l/tp9z99X5H/qev8uyDywVh0VXAwEbjk8kJhnc5grOFkGh7aW6q55me9xnYbss261XtnUrysZ+XvGbhQA==", "dev": true, "dependencies": { "picocolors": "^1.0.0", @@ -24094,11 +24132,11 @@ } }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/magicli": { @@ -24264,6 +24302,17 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/markdown-table": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", @@ -31094,9 +31143,9 @@ } }, "node_modules/mongoose": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.1.tgz", - "integrity": "sha512-OhVcwVl91A1G6+XpjDcpkGP7l7ikZkxa0DylX7NT/lcEqAjggzSdqDxb48A+xsDxqNAr0ntSJ1yiE3+KJTOd5Q==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.2.tgz", + "integrity": "sha512-GZB4rHMdYfGatV+23IpCrqFbyCOjCNOHXgWbirr92KRwTEncBrtW3kgU9vmpKjsGf7nMmnAy06SwWUv1vhDkSg==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", @@ -34216,9 +34265,9 @@ } }, "node_modules/openai": { - "version": "4.52.7", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.52.7.tgz", - "integrity": "sha512-dgxA6UZHary6NXUHEDj5TWt8ogv0+ibH+b4pT5RrWMjiRZVylNwLcw/2ubDrX5n0oUmHX/ZgudMJeemxzOvz7A==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.55.1.tgz", + "integrity": "sha512-FziYJcWl+SAGbt5AcRIzVzNcnKohpEMQdtzVOmHFbBp/if7x2+ACqgxF2XUbyi2PcKONPcVpmtG5h9qoDAEXwQ==", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", @@ -34226,17 +34275,24 @@ "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7", - "web-streams-polyfill": "^3.2.1" + "node-fetch": "^2.6.7" }, "bin": { "openai": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz", - "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==", + "version": "18.19.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.43.tgz", + "integrity": "sha512-Mw/YlgXnyJdEwLoFv2dpuJaDFriX+Pc+0qOBJ57jC1H6cDxIj2xc5yUrdtArDVG0m+KV6622a4p2tenEqB3C/g==", "dependencies": { "undici-types": "~5.26.4" } @@ -34486,6 +34542,17 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/parseley": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", @@ -34720,15 +34787,15 @@ } }, "node_modules/pdfjs-dist": { - "version": "4.4.168", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.4.168.tgz", - "integrity": "sha512-MbkAjpwka/dMHaCfQ75RY1FXX3IewBVu6NGZOcxerRFlaBiIkZmUoR0jotX5VUzYZEXAGzSFtknWs5xRKliXPA==", + "version": "4.5.136", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.5.136.tgz", + "integrity": "sha512-V1BALcAN/FmxBEShLxoP73PlQZAZtzlaNfRbRhJrKvXzjLC5VaIlBAQUJuWP8iaYUmIdmdLHmt3E2TBglxOm3w==", "engines": { "node": ">=18" }, "optionalDependencies": { "canvas": "^2.11.2", - "path2d": "^0.2.0" + "path2d": "^0.2.1" } }, "node_modules/pdfjs/node_modules/pako": { @@ -34961,9 +35028,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "funding": [ { "type": "opencollective", @@ -35189,9 +35256,9 @@ "peer": true }, "node_modules/prosemirror-commands": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz", - "integrity": "sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.0.tgz", + "integrity": "sha512-xn1U/g36OqXn2tn5nGmvnnimAj/g1pUx2ypJJIe8WkVX83WyJVC5LTARaxZa2AtQRwntu9Jc5zXs9gL9svp/mg==", "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -35236,9 +35303,9 @@ } }, "node_modules/prosemirror-model": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.2.tgz", - "integrity": "sha512-I4lS7HHIW47D0Xv/gWmi4iUWcQIDYaJKd8Hk4+lcSps+553FlQrhmxtItpEvTr75iAruhzVShVp6WUwsT6Boww==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.3.tgz", + "integrity": "sha512-V4XCysitErI+i0rKFILGt/xClnFJaohe/wrrlT2NSZ+zk8ggQfDH4x2wNK7Gm0Hp4CIoWizvXFP7L9KMaCuI0Q==", "dependencies": { "orderedmap": "^2.0.0" } @@ -35669,85 +35736,90 @@ } }, "node_modules/react-aria": { - "version": "3.33.1", - "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.33.1.tgz", - "integrity": "sha512-hFC3K/UA+90Krlx2IgRTgzFbC6FSPi4pUwHT+STperPLK+cTEHkI+3Lu0YYwQSBatkgxnIv9+GtFuVbps2kROw==", + "version": "3.34.1", + "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.34.1.tgz", + "integrity": "sha512-vA4BP+SWjFFRfOTQcNJtIp9gKlxuC7kPUXQK9fuNA+2K4mJdIc9mBnmwXQiLl/eAthMf43fD4fETfY9SiCm1Zg==", "dependencies": { "@internationalized/string": "^3.2.3", - "@react-aria/breadcrumbs": "^3.5.13", - "@react-aria/button": "^3.9.5", - "@react-aria/calendar": "^3.5.8", - "@react-aria/checkbox": "^3.14.3", - "@react-aria/combobox": "^3.9.1", - "@react-aria/datepicker": "^3.10.1", - "@react-aria/dialog": "^3.5.14", - "@react-aria/dnd": "^3.6.1", - "@react-aria/focus": "^3.17.1", - "@react-aria/gridlist": "^3.8.1", - "@react-aria/i18n": "^3.11.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/label": "^3.7.8", - "@react-aria/link": "^3.7.1", - "@react-aria/listbox": "^3.12.1", - "@react-aria/menu": "^3.14.1", - "@react-aria/meter": "^3.4.13", - "@react-aria/numberfield": "^3.11.3", - "@react-aria/overlays": "^3.22.1", - "@react-aria/progress": "^3.4.13", - "@react-aria/radio": "^3.10.4", - "@react-aria/searchfield": "^3.7.5", - "@react-aria/select": "^3.14.5", - "@react-aria/selection": "^3.18.1", - "@react-aria/separator": "^3.3.13", - "@react-aria/slider": "^3.7.8", - "@react-aria/ssr": "^3.9.4", - "@react-aria/switch": "^3.6.4", - "@react-aria/table": "^3.14.1", - "@react-aria/tabs": "^3.9.1", - "@react-aria/tag": "^3.4.1", - "@react-aria/textfield": "^3.14.5", - "@react-aria/tooltip": "^3.7.4", - "@react-aria/utils": "^3.24.1", - "@react-aria/visually-hidden": "^3.8.12", - "@react-types/shared": "^3.23.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "@react-aria/breadcrumbs": "^3.5.15", + "@react-aria/button": "^3.9.7", + "@react-aria/calendar": "^3.5.10", + "@react-aria/checkbox": "^3.14.5", + "@react-aria/combobox": "^3.10.1", + "@react-aria/datepicker": "^3.11.1", + "@react-aria/dialog": "^3.5.16", + "@react-aria/dnd": "^3.7.1", + "@react-aria/focus": "^3.18.1", + "@react-aria/gridlist": "^3.9.1", + "@react-aria/i18n": "^3.12.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/label": "^3.7.10", + "@react-aria/link": "^3.7.3", + "@react-aria/listbox": "^3.13.1", + "@react-aria/menu": "^3.15.1", + "@react-aria/meter": "^3.4.15", + "@react-aria/numberfield": "^3.11.5", + "@react-aria/overlays": "^3.23.1", + "@react-aria/progress": "^3.4.15", + "@react-aria/radio": "^3.10.6", + "@react-aria/searchfield": "^3.7.7", + "@react-aria/select": "^3.14.7", + "@react-aria/selection": "^3.19.1", + "@react-aria/separator": "^3.4.1", + "@react-aria/slider": "^3.7.10", + "@react-aria/ssr": "^3.9.5", + "@react-aria/switch": "^3.6.6", + "@react-aria/table": "^3.15.1", + "@react-aria/tabs": "^3.9.3", + "@react-aria/tag": "^3.4.3", + "@react-aria/textfield": "^3.14.7", + "@react-aria/tooltip": "^3.7.6", + "@react-aria/utils": "^3.25.1", + "@react-aria/visually-hidden": "^3.8.14", + "@react-types/shared": "^3.24.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/react-aria-components": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.2.1.tgz", - "integrity": "sha512-iGIdDjbTyLLn0/tGUyBQxxu+E1bw4/H4AU89d0cRcu8yIdw6MXG29YElmRHn0ugiyrERrk/YQALihstnns5kRQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.3.1.tgz", + "integrity": "sha512-yUTA8uHbioQHU5d7iNvSLZLEfQlcTAmyhhkY+NMc8pIGPdtf0qnrlF0nPtJq8Mro5irpVrgUlqKBvvCiKwFNiQ==", "dependencies": { - "@internationalized/date": "^3.5.4", + "@internationalized/date": "^3.5.5", "@internationalized/string": "^3.2.3", - "@react-aria/color": "3.0.0-beta.33", - "@react-aria/focus": "^3.17.1", - "@react-aria/interactions": "^3.21.3", - "@react-aria/menu": "^3.14.1", - "@react-aria/toolbar": "3.0.0-beta.5", - "@react-aria/tree": "3.0.0-alpha.1", - "@react-aria/utils": "^3.24.1", - "@react-stately/color": "^3.6.1", - "@react-stately/menu": "^3.7.1", - "@react-stately/table": "^3.11.8", - "@react-stately/utils": "^3.10.1", - "@react-types/color": "3.0.0-beta.25", - "@react-types/form": "^3.7.4", - "@react-types/grid": "^3.2.6", - "@react-types/shared": "^3.23.1", - "@react-types/table": "^3.9.5", + "@react-aria/collections": "3.0.0-alpha.3", + "@react-aria/color": "3.0.0-rc.1", + "@react-aria/dnd": "^3.7.1", + "@react-aria/focus": "^3.18.1", + "@react-aria/interactions": "^3.22.1", + "@react-aria/menu": "^3.15.1", + "@react-aria/toolbar": "3.0.0-beta.7", + "@react-aria/tree": "3.0.0-alpha.3", + "@react-aria/utils": "^3.25.1", + "@react-aria/virtualizer": "^4.0.1", + "@react-stately/color": "^3.7.1", + "@react-stately/layout": "^4.0.1", + "@react-stately/menu": "^3.8.1", + "@react-stately/table": "^3.12.1", + "@react-stately/utils": "^3.10.2", + "@react-stately/virtualizer": "^4.0.1", + "@react-types/color": "3.0.0-rc.1", + "@react-types/form": "^3.7.6", + "@react-types/grid": "^3.2.8", + "@react-types/shared": "^3.24.1", + "@react-types/table": "^3.10.1", "@swc/helpers": "^0.5.0", "client-only": "^0.0.1", - "react-aria": "^3.33.1", - "react-stately": "^3.31.1", + "react-aria": "^3.34.1", + "react-stately": "^3.32.1", "use-sync-external-store": "^1.2.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/react-autosuggest": { @@ -35766,9 +35838,9 @@ } }, "node_modules/react-awesome-reveal": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/react-awesome-reveal/-/react-awesome-reveal-4.2.12.tgz", - "integrity": "sha512-cablqrGypakw34h+rMcn+CmDCMfS+n4MznL/0LBQpFksZ2FCRtKFWIYuKWWpY8lL2ttyBnWnMdlJJiuLHR99uA==", + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/react-awesome-reveal/-/react-awesome-reveal-4.2.14.tgz", + "integrity": "sha512-wknbDl+z5MIhQFfKKSj3iBJzvssqJLP8LbxQjW9OCyXPGtMSYvOFKwjG4/2p1de+qh5gqb8WBMQIYS6wVN3tNw==", "funding": [ { "type": "github", @@ -35780,7 +35852,7 @@ } ], "dependencies": { - "react-intersection-observer": "^9.10.3", + "react-intersection-observer": "^9.13.0", "react-is": "^18.3.1" }, "peerDependencies": { @@ -36100,36 +36172,36 @@ } }, "node_modules/react-stately": { - "version": "3.31.1", - "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.31.1.tgz", - "integrity": "sha512-wuq673NHkYSdoceGryjtMJJvB9iQgyDkQDsnTN0t2v91pXjGDsN/EcOvnUrxXSBtY9eLdIw74R54z9GX5cJNEg==", - "dependencies": { - "@react-stately/calendar": "^3.5.1", - "@react-stately/checkbox": "^3.6.5", - "@react-stately/collections": "^3.10.7", - "@react-stately/combobox": "^3.8.4", - "@react-stately/data": "^3.11.4", - "@react-stately/datepicker": "^3.9.4", - "@react-stately/dnd": "^3.3.1", - "@react-stately/form": "^3.0.3", - "@react-stately/list": "^3.10.5", - "@react-stately/menu": "^3.7.1", - "@react-stately/numberfield": "^3.9.3", - "@react-stately/overlays": "^3.6.7", - "@react-stately/radio": "^3.10.4", - "@react-stately/searchfield": "^3.5.3", - "@react-stately/select": "^3.6.4", - "@react-stately/selection": "^3.15.1", - "@react-stately/slider": "^3.5.4", - "@react-stately/table": "^3.11.8", - "@react-stately/tabs": "^3.6.6", - "@react-stately/toggle": "^3.7.4", - "@react-stately/tooltip": "^3.4.9", - "@react-stately/tree": "^3.8.1", - "@react-types/shared": "^3.23.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + "version": "3.32.1", + "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.32.1.tgz", + "integrity": "sha512-znw+bqHJk1fvv34O3HoVH61otyYJomRu1gI7A4B3UHCnSFS6E6nMI6D3nRv9RrAWhf4ekLLg35FwDTHDcG1zdg==", + "dependencies": { + "@react-stately/calendar": "^3.5.3", + "@react-stately/checkbox": "^3.6.7", + "@react-stately/collections": "^3.10.9", + "@react-stately/combobox": "^3.9.1", + "@react-stately/data": "^3.11.6", + "@react-stately/datepicker": "^3.10.1", + "@react-stately/dnd": "^3.4.1", + "@react-stately/form": "^3.0.5", + "@react-stately/list": "^3.10.7", + "@react-stately/menu": "^3.8.1", + "@react-stately/numberfield": "^3.9.5", + "@react-stately/overlays": "^3.6.9", + "@react-stately/radio": "^3.10.6", + "@react-stately/searchfield": "^3.5.5", + "@react-stately/select": "^3.6.6", + "@react-stately/selection": "^3.16.1", + "@react-stately/slider": "^3.5.6", + "@react-stately/table": "^3.12.1", + "@react-stately/tabs": "^3.6.8", + "@react-stately/toggle": "^3.7.6", + "@react-stately/tooltip": "^3.4.11", + "@react-stately/tree": "^3.8.3", + "@react-types/shared": "^3.24.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, "node_modules/react-textarea-autosize": { @@ -39388,9 +39460,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/terser": { - "version": "5.31.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", - "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", + "version": "5.31.5", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.5.tgz", + "integrity": "sha512-YPmas0L0rE1UyLL/llTWA0SiDOqIcAQYLeUj7cJYzXHlRTAnMSg9pPe4VJ5PlKvTrPQsdVFuiRiwyeNlYgwh2Q==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -40383,9 +40455,9 @@ } }, "node_modules/type-fest": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.23.0.tgz", - "integrity": "sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.24.0.tgz", + "integrity": "sha512-spAaHzc6qre0TlZQQ2aA/nGMe+2Z/wyGk5Z+Ru2VUfdNwT6kWO6TjevOlpebsATEG1EIQ2sOiDszud3lO5mt/Q==", "engines": { "node": ">=16" }, @@ -40479,9 +40551,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -40496,14 +40568,14 @@ "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==" }, "node_modules/typescript-eslint": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.1.tgz", - "integrity": "sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.18.0.tgz", + "integrity": "sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "7.16.1", - "@typescript-eslint/parser": "7.16.1", - "@typescript-eslint/utils": "7.16.1" + "@typescript-eslint/eslint-plugin": "7.18.0", + "@typescript-eslint/parser": "7.18.0", + "@typescript-eslint/utils": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -40879,12 +40951,15 @@ } }, "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", "dependencies": { "punycode": "^1.4.1", - "qs": "^6.11.2" + "qs": "^6.12.3" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/url-loader": { @@ -40950,9 +41025,9 @@ "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" }, "node_modules/url/node_modules/qs": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz", - "integrity": "sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dependencies": { "side-channel": "^1.0.6" }, @@ -41313,9 +41388,11 @@ } }, "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", + "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", + "optional": true, + "peer": true, "engines": { "node": ">= 8" } @@ -41479,12 +41556,12 @@ } }, "node_modules/webpack-dev-middleware/node_modules/memfs": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.3.tgz", - "integrity": "sha512-bsYSSnirtYTWi1+OPMFb0M048evMKyUYe0EbtuGQgq6BVQM1g1W8/KIUJCCvjgI/El0j6Q4WsmMiBwLUBSw8LA==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.11.1.tgz", + "integrity": "sha512-LZcMTBAgqUUKNXZagcZxvXXfgF1bHX7Y7nQ0QyEiNbRJgE29GhgPd8Yna1VQcLlPiHt/5RFJMWYN9Uv/VPNvjQ==", "dependencies": { "@jsonjoy.com/json-pack": "^1.0.3", - "@jsonjoy.com/util": "^1.1.2", + "@jsonjoy.com/util": "^1.3.0", "tree-dump": "^1.0.1", "tslib": "^2.0.0" }, @@ -41565,9 +41642,9 @@ } }, "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", - "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==", + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", "dev": true, "dependencies": { "glob": "^10.3.7" @@ -41575,9 +41652,6 @@ "bin": { "rimraf": "dist/esm/bin.mjs" }, - "engines": { - "node": "14 >=14.20 || 16 >=16.20 || >=18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -41760,13 +41834,13 @@ } }, "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", "dev": true, "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.0.5", "is-finalizationregistry": "^1.0.2", @@ -41775,8 +41849,8 @@ "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" diff --git a/package.json b/package.json index 899b2968e..302831bd2 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@types/cookie-parser": "^1.4.6", "@types/cookie-session": "^2.0.48", "@types/d3": "^7.4.3", + "@types/dom-mediacapture-record": "^1.0.19", "@types/exif": "^0.6.5", "@types/express": "^4.17.21", "@types/express-session": "^1.17.10", @@ -63,10 +64,12 @@ "@types/request": "^2.48.12", "@types/request-promise": "^4.1.51", "@types/shelljs": "^0.8.15", + "@types/textarea-caret": "^3.0.3", "@types/textfit": "^2.4.4", "@types/uuid": "^10.0.0", "@types/valid-url": "^1.0.7", "@types/webpack": "^5.28.5", + "@types/webscopeio__react-textarea-autocomplete": "^4.7.5", "@types/youtube": "0.0.50", "chai": "^5.0.0", "cross-env": "^7.0.3", diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts index fc415d589..f9e282993 100644 --- a/src/ClientUtils.ts +++ b/src/ClientUtils.ts @@ -17,7 +17,7 @@ export function DashColor(color: string | undefined) { } } -export function lightOrDark(color: any) { +export function lightOrDark(color: string | undefined) { if (color === 'transparent' || !color) return Colors.BLACK; if (color.startsWith?.('linear')) return Colors.BLACK; if (DashColor(color).isLight()) return Colors.BLACK; @@ -351,9 +351,9 @@ export namespace ClientUtils { } } -export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?: (dup: any) => void): { omit: any; extract: any } { - const omit: any = { ...obj }; - const extract: any = {}; +export function OmitKeys(obj: object, keys: string[], pattern?: string, addKeyFunc?: (dup: object) => void): { omit: { [key: string]: unknown }; extract: { [key: string]: unknown } } { + const omit: { [key: string]: unknown } = { ...obj }; + const extract: { [key: string]: unknown } = {}; keys.forEach(key => { extract[key] = omit[key]; delete omit[key]; @@ -369,8 +369,8 @@ export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc? return { omit, extract }; } -export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) { - const dup: any = {}; +export function WithKeys(obj: object & { [key: string]: unknown }, keys: string[], addKeyFunc?: (dup: unknown) => void) { + const dup: { [key: string]: unknown } = {}; keys.forEach(key => { dup[key] = obj[key]; }); @@ -521,7 +521,7 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe } } -export function getWordAtPoint(elem: any, x: number, y: number): string | undefined { +export function getWordAtPoint(elem: Element, x: number, y: number): string | undefined { if (elem.tagName === 'INPUT') return 'input'; if (elem.tagName === 'TEXTAREA') return 'textarea'; if (elem.nodeType === elem.TEXT_NODE || elem.textContent) { @@ -534,7 +534,7 @@ export function getWordAtPoint(elem: any, x: number, y: number): string | undefi range.setEnd(elem, currentPos + 1); const rangeRect = range.getBoundingClientRect(); if (rangeRect.left <= x && rangeRect.right >= x && rangeRect.top <= y && rangeRect.bottom >= y) { - range.expand?.('word'); // doesn't exist in firefox + 'expand' in range && (range.expand as (val: string) => void)('word'); // doesn't exist in firefox const ret = range.toString(); range.detach(); return ret; @@ -542,16 +542,18 @@ export function getWordAtPoint(elem: any, x: number, y: number): string | undefi currentPos += 1; } } else { - Array.from(elem.childNodes).forEach((childNode: any) => { - const range = childNode.ownerDocument.createRange(); - range.selectNodeContents(childNode); - const rangeRect = range.getBoundingClientRect(); - if (rangeRect.left <= x && rangeRect.right >= x && rangeRect.top <= y && rangeRect.bottom >= y) { - range.detach(); - const word = getWordAtPoint(childNode, x, y); - if (word) return word; - } else { - range.detach(); + Array.from(elem.children).forEach(childNode => { + const range = childNode.ownerDocument?.createRange(); + if (range) { + range.selectNodeContents(childNode); + const rangeRect = range.getBoundingClientRect(); + if (rangeRect.left <= x && rangeRect.right >= x && rangeRect.top <= y && rangeRect.bottom >= y) { + range.detach(); + const word = getWordAtPoint(childNode, x, y); + if (word) return word; + } else { + range.detach(); + } } return undefined; }); @@ -576,17 +578,18 @@ export function setupMoveUpEvents( target: object, e: React.PointerEvent, moveEvent: (e: PointerEvent, down: number[], delta: number[]) => boolean, - upEvent: (e: PointerEvent, movement: number[], isClick: boolean) => any, - clickEvent: (e: PointerEvent, doubleTap?: boolean) => any, + upEvent: (e: PointerEvent, movement: number[], isClick: boolean) => void, + clickEvent: (e: PointerEvent, doubleTap?: boolean) => unknown, // eslint-disable-next-line default-param-last stopPropagation: boolean = true, // eslint-disable-next-line default-param-last stopMovePropagation: boolean = true, noDoubleTapTimeout?: () => void ) { - const targetAny = target as any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const targetAny: object & { _downX: number; _downY: number; _lastX: number; _lastY: number; _doubleTap: boolean; _doubleTime?: NodeJS.Timeout; _lastTap: number; _noClick: boolean } = target as any; const doubleTapTimeout = 300; - targetAny._doubleTap = Date.now() - (target as any)._lastTap < doubleTapTimeout; + targetAny._doubleTap = Date.now() - targetAny._lastTap < doubleTapTimeout; targetAny._lastTap = Date.now(); targetAny._downX = targetAny._lastX = e.clientX; targetAny._downY = targetAny._lastY = e.clientY; @@ -594,13 +597,13 @@ export function setupMoveUpEvents( let moving = false; const _moveEvent = (moveEv: PointerEvent): void => { - if (moving || Math.abs(moveEv.clientX - (target as any)._downX) > ClientUtils.DRAG_THRESHOLD || Math.abs(moveEv.clientY - (target as any)._downY) > ClientUtils.DRAG_THRESHOLD) { + if (moving || Math.abs(moveEv.clientX - targetAny._downX) > ClientUtils.DRAG_THRESHOLD || Math.abs(moveEv.clientY - targetAny._downY) > ClientUtils.DRAG_THRESHOLD) { moving = true; - if ((target as any)._doubleTime) { - clearTimeout((target as any)._doubleTime); + if (targetAny._doubleTime) { + targetAny._doubleTime && clearTimeout(targetAny._doubleTime); targetAny._doubleTime = undefined; } - if (moveEvent(moveEv, [(target as any)._downX, (target as any)._downY], [moveEv.clientX - (target as any)._lastX, moveEv.clientY - (target as any)._lastY])) { + if (moveEvent(moveEv, [targetAny._downX, targetAny._downY], [moveEv.clientX - targetAny._lastX, moveEv.clientY - targetAny._lastY])) { document.removeEventListener('pointermove', _moveEvent); // eslint-disable-next-line no-use-before-define document.removeEventListener('pointerup', _upEvent); @@ -621,16 +624,16 @@ export function setupMoveUpEvents( }, doubleTapTimeout); } if (targetAny._doubleTime && targetAny._doubleTap) { - clearTimeout(targetAny._doubleTime); + targetAny._doubleTime && clearTimeout(targetAny._doubleTime); targetAny._doubleTime = undefined; } - targetAny._noClick = clickEvent(upEv, targetAny._doubleTap); + targetAny._noClick = clickEvent(upEv, targetAny._doubleTap) ? true : false; } document.removeEventListener('pointermove', _moveEvent); document.removeEventListener('pointerup', _upEvent, true); }; const _clickEvent = (clickev: MouseEvent): void => { - if ((target as any)._noClick) clickev.stopPropagation(); + if (targetAny._noClick) clickev.stopPropagation(); document.removeEventListener('click', _clickEvent, true); }; if (stopPropagation) { @@ -642,11 +645,11 @@ export function setupMoveUpEvents( document.addEventListener('click', _clickEvent, true); } -export function DivHeight(ele: HTMLElement): number { - return Number(getComputedStyle(ele).height.replace('px', '')); +export function DivHeight(ele: HTMLElement | null): number { + return ele ? Number(getComputedStyle(ele).height.replace('px', '')) : 0; } -export function DivWidth(ele: HTMLElement): number { - return Number(getComputedStyle(ele).width.replace('px', '')); +export function DivWidth(ele: HTMLElement | null): number { + return ele ? Number(getComputedStyle(ele).width.replace('px', '')) : 0; } export function dateRangeStrToDates(dateStr: string) { @@ -709,7 +712,7 @@ export function UpdateIcon( realNativeHeight: number, noSuffix: boolean, replaceRootFilename: string | undefined, - cb: (iconFile: string, nativeWidth: number, nativeHeight: number) => any + cb: (iconFile: string, nativeWidth: number, nativeHeight: number) => void ) { const newDiv = docViewContent.cloneNode(true) as HTMLDivElement; newDiv.style.width = width.toString(); @@ -719,9 +722,9 @@ export function UpdateIcon( const nativeWidth = width; const nativeHeight = height; return CreateImage(ClientUtils.prepend(''), document.styleSheets, htmlString, nativeWidth, (nativeWidth * panelHeight) / panelWidth, (scrollTop * panelHeight) / realNativeHeight) - .then(async (dataUrl: any) => { + .then(async dataUrl => { const returnedFilename = await ClientUtils.convertDataUri(dataUrl, filename, noSuffix, replaceRootFilename); cb(returnedFilename as string, nativeWidth, nativeHeight); }) - .catch((error: any) => console.error('oops, something went wrong!', error)); + .catch(error => console.error('oops, something went wrong!', error)); } diff --git a/src/JSZipUtils.js b/src/JSZipUtils.js index 5ce1bd471..755de7226 100644 --- a/src/JSZipUtils.js +++ b/src/JSZipUtils.js @@ -12,13 +12,17 @@ JSZipUtils._getBinaryFromXHR = function (xhr) { function createStandardXHR() { try { return new window.XMLHttpRequest(); - } catch (e) {} + } catch (e) { + /* empty */ + } } function createActiveXHR() { try { return new window.ActiveXObject('Microsoft.XMLHTTP'); - } catch (e) {} + } catch (e) { + /* empty */ + } } // Create the request object @@ -101,7 +105,7 @@ JSZipUtils.getBinaryContent = function (path, options) { xhr.overrideMimeType('text/plain; charset=x-user-defined'); } - xhr.onreadystatechange = function (event) { + xhr.onreadystatechange = function (/* event */) { // use `xhr` and not `this`... thanks IE if (xhr.readyState === 4) { if (xhr.status === 200 || xhr.status === 0) { diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index ac865382d..2bf3a6f9f 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -1,14 +1,14 @@ -import { runInAction } from 'mobx'; +/* eslint-disable @typescript-eslint/no-namespace */ +import { action } from 'mobx'; import { Socket, io } from 'socket.io-client'; import { ClientUtils } from '../ClientUtils'; import { Utils, emptyFunction } from '../Utils'; -import { Doc, Opt } from '../fields/Doc'; +import { Doc, FieldType, Opt, SetObjGetRefField, SetObjGetRefFields } from '../fields/Doc'; import { UpdatingFromServer } from '../fields/DocSymbols'; import { FieldLoader } from '../fields/FieldLoader'; import { HandleUpdate, Id, Parent } from '../fields/FieldSymbols'; -import { ObjectField, SetObjGetRefField, SetObjGetRefFields } from '../fields/ObjectField'; -import { RefField } from '../fields/RefField'; -import { GestureContent, Message, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, YoutubeQueryTypes } from '../server/Message'; +import { ObjectField, serverOpType } from '../fields/ObjectField'; +import { GestureContent, Message, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent } from '../server/Message'; import { SerializationHelper } from './util/SerializationHelper'; /** @@ -25,8 +25,7 @@ import { SerializationHelper } from './util/SerializationHelper'; * or update ourselves based on the server's update message, that occurs here */ export namespace DocServer { - // eslint-disable-next-line import/no-mutable-exports - let _cache: { [id: string]: RefField | Promise> } = {}; + let _cache: { [id: string]: Doc | Promise> } = {}; export function Cache() { return _cache; } @@ -34,24 +33,24 @@ export namespace DocServer { function errorFunc(): never { throw new Error("Can't use DocServer without calling init first"); } - let _UpdateField: (id: string, diff: any) => void = errorFunc; - let _CreateField: (field: RefField) => void = errorFunc; + let _UpdateField: (id: string, diff: serverOpType) => void = errorFunc; + let _CreateField: (field: Doc) => void = errorFunc; - export function AddServerHandler(socket: Socket, message: Message, handler: (args: T) => any) { + export function AddServerHandler(socket: Socket, message: Message, handler: (args: T) => void) { socket.on(message.Message, Utils.loggingCallback('Incoming', handler, message.Name)); } export function Emit(socket: Socket, message: Message, args: T) { // log('Emit', message.Name, args, false); socket.emit(message.Message, args); } - export function EmitCallback(socket: Socket, message: Message, args: T): Promise; - export function EmitCallback(socket: Socket, message: Message, args: T, fn: (args: any) => any): void; - export function EmitCallback(socket: Socket, message: Message, args: T, fn?: (args: any) => any): void | Promise { + export function EmitCallback(socket: Socket, message: Message, args: T): Promise; + export function EmitCallback(socket: Socket, message: Message, args: T, fn: (args: unknown) => unknown): void; + export function EmitCallback(socket: Socket, message: Message, args: T, fn?: (args: unknown) => unknown): void | Promise { // log('Emit', message.Name, args, false); if (fn) { socket.emit(message.Message, args, Utils.loggingCallback('Receiving', fn, message.Name)); } else { - return new Promise(res => { + return new Promise(res => { socket.emit(message.Message, args, Utils.loggingCallback('Receiving', res, message.Name)); }); } @@ -99,7 +98,7 @@ export namespace DocServer { return ClientUtils.CurrentUserEmail() === 'guest' ? WriteMode.LivePlayground : fieldWriteModes[field] || WriteMode.Default; } - export function registerDocWithCachedUpdate(doc: Doc, field: string, oldValue: any) { + export function registerDocWithCachedUpdate(doc: Doc, field: string, oldValue: FieldType) { let list = docsWithUpdates[field]; if (!list) { list = docsWithUpdates[field] = new Set(); @@ -203,7 +202,7 @@ export namespace DocServer { * the server if the document has not been cached. * @param id the id of the requested document */ - const _GetRefFieldImpl = (id: string, force: boolean = false): Promise> => { + const _GetRefFieldImpl = (id: string, force: boolean = false): Promise> => { // an initial pass through the cache to determine whether the document needs to be fetched, // is already in the process of being fetched or already exists in the // cache @@ -221,7 +220,7 @@ export namespace DocServer { // future .proto calls on the Doc won't have to go farther than the cache to get their actual value. const deserializeField = getSerializedField.then(async fieldJson => { // deserialize - const field = await SerializationHelper.Deserialize(fieldJson); + const field = (await SerializationHelper.Deserialize(fieldJson)) as Doc; if (force && field && cached instanceof Doc) { cached[UpdatingFromServer] = true; Array.from(Object.keys(field)).forEach(key => { @@ -247,7 +246,7 @@ export namespace DocServer { // here, indicate that the document associated with this id is currently // being retrieved and cached !force && (_cache[id] = deserializeField); - return force ? (cached as any) : deserializeField; + return force ? (cached instanceof Promise ? cached : new Promise(res => res(cached))) : deserializeField; } if (cached instanceof Promise) { // BEING RETRIEVED AND CACHED => some other caller previously (likely recently) called GetRefField(s), @@ -261,7 +260,7 @@ export namespace DocServer { // (field instanceof Doc) && fetchProto(field); ); }; - const _GetCachedRefFieldImpl = (id: string): Opt => { + const _GetCachedRefFieldImpl = (id: string): Opt => { const cached = _cache[id]; if (cached !== undefined && !(cached instanceof Promise)) { return cached; @@ -269,174 +268,102 @@ export namespace DocServer { return undefined; }; - let _GetRefField: (id: string, force: boolean) => Promise> = errorFunc; - let _GetCachedRefField: (id: string) => Opt = errorFunc; + let _GetRefField: (id: string, force: boolean) => Promise> = errorFunc; + let _GetCachedRefField: (id: string) => Opt = errorFunc; - export function GetRefField(id: string, force = false): Promise> { + export function GetRefField(id: string, force = false): Promise> { return _GetRefField(id, force); } - export function GetCachedRefField(id: string): Opt { + export function GetCachedRefField(id: string): Opt { return _GetCachedRefField(id); } - export async function getYoutubeChannels() { - return DocServer.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.Channels }); - } - - export function getYoutubeVideos(videoTitle: string, callBack: (videos: any[]) => void) { - DocServer.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.SearchVideo, userInput: videoTitle }, callBack); - } - - export function getYoutubeVideoDetails(videoIds: string, callBack: (videoDetails: any[]) => void) { - DocServer.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.VideoDetails, videoIds: videoIds }, callBack); - } - /** * Given a list of Doc GUIDs, this utility function will asynchronously attempt to each id's associated * field, first looking in the RefField cache and then communicating with * the server if the document has not been cached. * @param ids the ids that map to the reqested documents */ - const _GetRefFieldsImpl = async (ids: string[]): Promise<{ [id: string]: Opt }> => { - const requestedIds: string[] = []; - const promises: Promise[] = []; - - let defaultRes: any; - const defaultPromise = new Promise(res => { - defaultRes = res; + const _GetRefFieldsImpl = async (ids: string[]): Promise>> => { + const uncachedRequestedIds: string[] = []; + const deserializeDocPromises: Promise>[] = []; + + // setup a Promise that we will resolve after all cached Docs have been acquired. + let allCachesFilledResolver!: (value: Opt | PromiseLike>) => void; + const allCachesFilledPromise = new Promise>(res => { + allCachesFilledResolver = res; }); - const defaultPromises: { p: Promise; id: string }[] = []; - // 1) an initial pass through the cache to determine - // i) which documents need to be fetched - // ii) which are already in the process of being fetched - // iii) which already exist in the cache + + const fetchDocPromises: Map>> = new Map(); // { p: Promise; id: string }[] = []; // promises to fetch the value for a requested Doc + // Determine which requested documents need to be fetched // eslint-disable-next-line no-restricted-syntax for (const id of ids.filter(filterid => filterid)) { - const cached = _cache[id]; - if (cached === undefined) { - defaultPromises.push({ - id, - // eslint-disable-next-line no-loop-func - p: (_cache[id] = new Promise(res => { - defaultPromise.then(() => res(_cache[id])); - })), - }); - // NOT CACHED => we'll have to send a request to the server - requestedIds.push(id); - } else if (cached instanceof Promise) { - // BEING RETRIEVED AND CACHED => some other caller previously (likely recently) called GetRefField(s), - // and requested one of the documents I'm looking for. Shouldn't fetch again, just - // wait until this promise is resolved (see 7) - promises.push(cached); - // waitingIds.push(id); - } else { - // CACHED => great, let's just add it to the field map - // map[id] = cached; + if (_cache[id] === undefined) { + // EMPTY CACHE - make promise that we resolve after all batch-requested Docs have been fetched and deserialized and we know we have this Doc + const fetchPromise = new Promise>(res => + allCachesFilledPromise.then(() => { + // if all Docs have been cached, then we can be sure the fetched Doc has been found and cached. So return it to anyone who had been awaiting it. + const cache = _cache[id]; + if (!(cache instanceof Doc)) console.log('CACHE WAS NEVER FILLED!!'); + res(cache instanceof Doc ? cache : undefined); + }) + ); + // eslint-disable-next-line no-loop-func + fetchDocPromises.set(id, (_cache[id] = fetchPromise)); + uncachedRequestedIds.push(id); // add to list of Doc requests from server } + // else CACHED => do nothing, Doc or promise of Doc is already in cache } - if (requestedIds.length) { - // 2) synchronously, we emit a single callback to the server requesting the serialized (i.e. represented by a string) - // fields for the given ids. This returns a promise, which, when resolved, indicates that all the JSON serialized versions of - // the fields have been returned from the server - console.log('Requesting ' + requestedIds.length); - setTimeout(() => - runInAction(() => { - FieldLoader.ServerLoadStatus.requested = requestedIds.length; - }) - ); - const serializedFields = await DocServer.EmitCallback(_socket, MessageStore.GetRefFields, requestedIds); - - // 3) when the serialized RefFields have been received, go head and begin deserializing them into objects. - // Here, once deserialized, we also invoke .proto to 'load' the documents' prototypes, which ensures that all - // future .proto calls on the Doc won't have to go farther than the cache to get their actual value. + if (uncachedRequestedIds.length) { + console.log('Requesting ' + uncachedRequestedIds.length); + setTimeout(action(() => { FieldLoader.ServerLoadStatus.requested = uncachedRequestedIds.length; })); // prettier-ignore + + // Synchronously emit a single server request for the serialized (i.e. represented by a string) Doc ids + // This returns a promise, that resolves when all the JSON serialized Docs have been retrieved + const serializedFields = (await DocServer.EmitCallback(_socket, MessageStore.GetRefFields, uncachedRequestedIds)) as { id: string; fields: unknown[]; __type: string }[]; + let processed = 0; - console.log('deserializing ' + serializedFields.length + ' fields'); + console.log('Retrieved ' + serializedFields.length + ' fields'); + // After the serialized Docs have been received, deserialize them into objects. // eslint-disable-next-line no-restricted-syntax for (const field of serializedFields) { - processed++; - if (processed % 150 === 0) { + // eslint-disable-next-line no-await-in-loop + ++processed % 150 === 0 && + (await new Promise( + res => + setTimeout(action(() => res(FieldLoader.ServerLoadStatus.retrieved = processed))) // prettier-ignore + )); // force loading to yield to splash screen rendering to update progress + + if (fetchDocPromises.has(field.id)) { + // Doc hasn't started deserializing yet - the cache still has the fetch promise // eslint-disable-next-line no-loop-func - runInAction(() => { - FieldLoader.ServerLoadStatus.retrieved = processed; + const deserializePromise = SerializationHelper.Deserialize(field).then((deserialized: unknown) => { + const doc = deserialized as Doc; + // overwrite any fetch or deserialize cache promise with deserialized value. + // fetch promises wait to resolve until after all deserializations; deserialize promises resolve upon deserializaton + if (deserialized !== undefined) _cache[field.id] = doc; + else delete _cache[field.id]; + + return doc; }); - // eslint-disable-next-line no-await-in-loop - await new Promise(res => { - setTimeout(res); - }); // force loading to yield to splash screen rendering to update progress - } - const cached = _cache[field.id]; - if (!cached || (cached instanceof Promise && defaultPromises.some(dp => dp.p === cached))) { - // deserialize - // adds to a list of promises that will be awaited asynchronously - promises.push( - // eslint-disable-next-line no-loop-func - (_cache[field.id] = SerializationHelper.Deserialize(field).then(deserialized => { - // overwrite or delete any promises (that we inserted as flags - // to indicate that the field was in the process of being fetched). Now everything - // should be an actual value within or entirely absent from the cache. - if (deserialized !== undefined) { - _cache[field.id] = deserialized; - } else { - delete _cache[field.id]; - } - const promInd = defaultPromises.findIndex(dp => dp.id === field.id); - promInd !== -1 && defaultPromises.splice(promInd, 1); - return deserialized; - })) - ); - // 4) here, for each of the documents we've requested *ourselves* (i.e. weren't promises or found in the cache) - // we set the value at the field's id to a promise that will resolve to the field. - // When we find that promises exist at keys in the cache, THIS is where they were set, just by some other caller (method). - // The mapping in the .then call ensures that when other callers await these promises, they'll - // get the resolved field - } else if (cached instanceof Promise) { + deserializeDocPromises.push((_cache[field.id] = deserializePromise)); // replace the cache's placeholder fetch promise with the deserializePromise + fetchDocPromises.delete(field.id); + } else if (_cache[field.id] instanceof Promise) { console.log('.'); - // promises.push(cached); - } else if (field) { - // console.log('-'); } } } - await Promise.all(promises); - defaultPromises.forEach(df => delete _cache[df.id]); - defaultRes(); - - // 5) at this point, all fields have a) been returned from the server and b) been deserialized into actual Field objects whose - // prototype documents, if any, have also been fetched and cached. - console.log('Deserialized ' + (requestedIds.length - defaultPromises.length) + ' fields'); - // 6) with this confidence, we can now go through and update the cache at the ids of the fields that - // we explicitly had to fetch. To finish it off, we add whatever value we've come up with for a given - // id to the soon-to-be-returned field mapping. - // ids.forEach(id => (map[id] = _cache[id] as any)); - - // 7) those promises we encountered in the else if of 1), which represent - // other callers having already submitted a request to the server for (a) document(s) - // in which we're interested, must still be awaited so that we can return the proper - // values for those as well. - // - // fortunately, those other callers will also hit their own version of 6) and clean up - // the shared cache when these promises resolve, so all we have to do is... - // const otherCallersFetching = await Promise.all(promises); - // ...extract the RefFields returned from the resolution of those promises and add them to our - // own map. - // waitingIds.forEach((id, index) => (map[id] = otherCallersFetching[index])); - - // now, we return our completed mapping from all of the ids that were passed into the method - // to their actual RefField | undefined values. This return value either becomes the input - // argument to the caller's promise (i.e. GetRefFields(["_id1_", "_id2_", "_id3_"]).then(map => //do something with map...)) - // or it is the direct return result if the promise is awaited (i.e. let fields = await GetRefFields(["_id1_", "_id2_", "_id3_"])). - return ids.reduce( - (map, id) => { - map[id] = _cache[id] as any; - return map; - }, - {} as { [id: string]: Opt } - ); + await Promise.all(deserializeDocPromises); // promise resolves when cache is up-to-date with all requested Docs + Array.from(fetchDocPromises).forEach(([id]) => delete _cache[id]); + allCachesFilledResolver(undefined); // notify anyone who was promised a Doc fron when it was just being fetched (since all requested Docs have now been fetched and deserialized) + + console.log('Deserialized ' + (uncachedRequestedIds.length - fetchDocPromises.size) + ' fields'); + return new Map>(ids.map(id => [id, _cache[id] instanceof Doc ? (_cache[id] as Doc) : undefined]) as [string, Opt][]); }; - let _GetRefFields: (ids: string[]) => Promise<{ [id: string]: Opt }> = errorFunc; + let _GetRefFields: (ids: string[]) => Promise>> = errorFunc; export function GetRefFields(ids: string[]) { return _GetRefFields(ids); @@ -454,12 +381,12 @@ export namespace DocServer { * calling the same function throughout the code base (such as in Util.makeReadonly()) * @param field the [RefField] to be serialized and sent to the server to be stored in the database */ - export function CreateField(field: RefField) { + export function CreateField(field: Doc) { _cacheNeedsUpdate = true; _CreateField(field); } - function _CreateFieldImpl(field: RefField) { + function _CreateFieldImpl(field: Doc) { _cache[field[Id]] = field; const initialState = SerializationHelper.Serialize(field); ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.CreateField, initialState); @@ -475,22 +402,22 @@ export namespace DocServer { * @param updatedState the new value of the document. At some point, this * should actually be a proper diff, to improve efficiency */ - export function UpdateField(id: string, updatedState: any) { + export function UpdateField(id: string, updatedState: serverOpType) { _UpdateField(id, updatedState); } - function _UpdateFieldImpl(id: string, diff: any) { + function _UpdateFieldImpl(id: string, diff: serverOpType) { !DocServer.Control.isReadOnly() && ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.UpdateField, { id, diff }); } - function _respondToUpdateImpl(diff: any) { - const { id } = diff; + function _respondToUpdateImpl(change: { id: string; diff: serverOpType }) { + const { id } = change; // to be valid, the Diff object must reference // a document's id if (id === undefined) { return; } - const update = (f: Opt) => { + const update = (f: Opt) => { // if the RefField is absent from the cache or // its promise in the cache resolves to undefined, there // can't be anything to update @@ -500,7 +427,7 @@ export namespace DocServer { // extract this Doc's update handler const handler = f[HandleUpdate]; if (handler) { - handler.call(f, diff.diff); + handler.call(f, change.diff as { $set: { [key: string]: FieldType } } | { $unset: unknown }); } }; // check the cache for the field @@ -536,8 +463,8 @@ export namespace DocServer { const _RespondToUpdate = _respondToUpdateImpl; const _respondToDelete = _respondToDeleteImpl; - function respondToUpdate(diff: any) { - _RespondToUpdate(diff); + function respondToUpdate(change: { id: string; diff: serverOpType }) { + _RespondToUpdate(change); } function respondToDelete(ids: string | string[]) { @@ -548,7 +475,7 @@ export namespace DocServer { _cache = {}; USER_ID = identifier; _socket = io(`${protocol.startsWith('https') ? 'wss' : 'ws'}://${hostname}:${port}`, { transports: ['websocket'], rejectUnauthorized: false }); - _socket.on('connect_error', (err: any) => console.log(err)); + _socket.on('connect_error', (err: unknown) => console.log(err)); // io.connect(`https://7f079dda.ngrok.io`);// if using ngrok, create a special address for the websocket _GetCachedRefField = _GetCachedRefFieldImpl; diff --git a/src/client/Network.ts b/src/client/Network.ts index 968c407b2..8876d8190 100644 --- a/src/client/Network.ts +++ b/src/client/Network.ts @@ -8,12 +8,13 @@ import { Upload } from '../server/SharedMediaTypes'; * mainly provides methods that the client can use to begin the process of * interacting with the server, such as fetching or uploading files. */ +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Networking { export async function FetchFromServer(relativeRoute: string) { return (await fetch(relativeRoute)).text(); } - export async function PostToServer(relativeRoute: string, body?: any) { + export async function PostToServer(relativeRoute: string, body?: unknown) { const options = { uri: ClientUtils.prepend(relativeRoute), method: 'POST', @@ -31,7 +32,7 @@ export namespace Networking { * used as the guid. Otherwise, a new guid is generated. */ export interface FileGuidPair { - file: File; + file: File | Blob; guid?: string; } /** @@ -48,15 +49,14 @@ export namespace Networking { if (!fileguidpairs.length) { return []; } - const maxFileSize = 50000000; + const maxFileSize = 5000000; if (fileguidpairs.some(f => f.file.size > maxFileSize)) { - return new Promise(res => { - res([ - { - source: { name: '', type: '', size: 0, toJson: () => ({ name: '', type: '' }) }, - result: { name: '', message: `max file size (${maxFileSize / 1000000}MB) exceeded` }, - }, - ]); + return new Promise[]>(res => { + res([{ + source: { size: 0, filepath: '', mimetype: '', originalFilename: '', newFilename: '',hashAlgorithm: false, + toJSON: () => ({ size: 0, filepath: '', mimetype: '', originalFilename: '', newFilename: '',name: '', length: 0, mtime: new Date(), type: '' }) }, + result: { name: '', message: `max file size (${maxFileSize / 1000000}MB) exceeded` } + }]) // prettier-ignore }); } formData.set('fileguids', fileguidpairs.map(pair => pair.guid).join(';')); @@ -77,7 +77,12 @@ export namespace Networking { const endpoint = browndash ? '[insert endpoint allowing local => browndash]' : '/uploadFormData'; const response = await fetch(endpoint, parameters); - return response.json(); + return response.json().then((json: Upload.FileResponse[]) => + json.map(fileresponse => { + if ('message' in fileresponse.result) fileresponse.result = new Error(fileresponse.result.message); + return fileresponse; + }) + ); } export async function UploadYoutubeToServer(videoId: string, overwriteId?: string): Promise[]> { diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index 0c9fe0315..a503d732b 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -35,14 +35,16 @@ import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; import { DocumentType } from './DocumentTypes'; import { Docs, DocumentOptions } from './Documents'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const { DFLT_IMAGE_NATIVE_DIM } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', '')); +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DocUtils { - function matchFieldValue(doc: Doc, key: string, valueIn: any): boolean { + function matchFieldValue(doc: Doc, key: string, valueIn: unknown): boolean { let value = valueIn; - const hasFunctionFilter = ClientUtils.HasFunctionFilter(value); + const hasFunctionFilter = ClientUtils.HasFunctionFilter(value as string); if (hasFunctionFilter) { return hasFunctionFilter(StrCast(doc[key])); } @@ -57,8 +59,8 @@ export namespace DocUtils { // prettier-ignore return (value === Doc.FilterNone && !allLinks.length) || (value === Doc.FilterAny && !!allLinks.length) || - (allLinks.some(link => matchLink(value,DocCast(link.link_anchor_1)) || - matchLink(value,DocCast(link.link_anchor_2)) )); + (allLinks.some(link => matchLink(value as string, DocCast(link.link_anchor_1)) || + matchLink(value as string, DocCast(link.link_anchor_2)) )); } if (typeof value === 'string') { value = value.replace(`,${ClientUtils.noRecursionHack}`, ''); @@ -71,9 +73,9 @@ export namespace DocUtils { } const vals = StrListCast(fieldVal); // list typing is very imperfect. casting to a string list doesn't mean that the entries will actually be strings if (vals.length) { - return vals.some(v => typeof v === 'string' && v.includes(value)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring + return vals.some(v => typeof v === 'string' && v.includes(value as string)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring } - return Field.toString(fieldVal as FieldType).includes(value); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring + return Field.toString(fieldVal as FieldType).includes(value as string); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring } /** * @param docs @@ -215,13 +217,13 @@ export namespace DocUtils { { acl_Guest: SharingPermissions.Augment, _acl_Guest: SharingPermissions.Augment, - title: ComputedField.MakeFunction('generateLinkTitle(this)') as any, + title: ComputedField.MakeFunction('generateLinkTitle(this)') as unknown as string, // title can accept functions even though type says it can't link_anchor_1_useSmallAnchor: source.useSmallAnchor ? true : undefined, link_anchor_2_useSmallAnchor: target.useSmallAnchor ? true : undefined, link_relationship: linkSettings.link_relationship, link_description: linkSettings.link_description, - x: ComputedField.MakeFunction(`((this.${a}?.x||0)+(this.${b}?.x||0))/2`) as any, - y: ComputedField.MakeFunction(`((this.${a}?.y||0)+(this.${b}?.y||0))/2`) as any, + x: ComputedField.MakeFunction(`((this.${a}?.x||0)+(this.${b}?.x||0))/2`) as unknown as number, // x can accept functions even though type says it can't + y: ComputedField.MakeFunction(`((this.${a}?.y||0)+(this.${b}?.y||0))/2`) as unknown as number, // y can accept functions even though type says it can't link_autoMoveAnchors: true, _lockedPosition: true, _layout_showCaption: '', // removed since they conflict with showing a link with a LinkBox (ie, line, not comparison box) @@ -235,10 +237,10 @@ export namespace DocUtils { ); } - export function AssignScripts(doc: Doc, scripts?: { [key: string]: string | undefined }, funcs?: { [key: string]: string }) { + export function AssignScripts(doc: Doc, scripts?: { [key: string]: string | undefined }, funcs?: { [key: string]: string | undefined }) { scripts && Object.keys(scripts).forEach(key => { - const script = scripts[key]; + const script = scripts[key] as string; if (ScriptCast(doc[key])?.script.originalScript !== scripts[key] && script) { (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = ScriptField.MakeScript(script, { this: Doc.name, @@ -261,16 +263,17 @@ export namespace DocUtils { .filter(key => !key.endsWith('-setter')) .forEach(key => { const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); - if (ScriptCast(cfield)?.script.originalScript !== funcs[key]) { + const func = funcs[key]; + if (ScriptCast(cfield)?.script.originalScript !== func) { const setFunc = Cast(funcs[key + '-setter'], 'string', null); - (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = funcs[key] ? ComputedField.MakeFunction(funcs[key], { dragData: Doc.DocDragDataName }, { _readOnly_: true }, setFunc) : undefined; + (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = func ? ComputedField.MakeFunction(func, { dragData: Doc.DocDragDataName }, { _readOnly_: true }, setFunc) : undefined; } }); return doc; } export function AssignOpts(doc: Doc | undefined, reqdOpts: DocumentOptions, items?: Doc[]) { if (doc) { - const compareValues = (val1: any, val2: any) => { + const compareValues = (val1: unknown, val2: unknown) => { if (val1 instanceof List && val2 instanceof List && val1.length === val2.length) { return !val1.some(v => !val2.includes(v)) || !val2.some(v => val1.includes(v)); } @@ -334,7 +337,7 @@ export namespace DocUtils { if (path.includes(window.location.hostname)) { const s = path.split('/'); const id = s[s.length - 1]; - return DocServer.GetRefField(id).then(field => { + return DocServer.GetRefField(id)?.then(field => { if (field instanceof Doc) { const embedding = Doc.MakeEmbedding(field); embedding.x = (options.x as number) || 0; @@ -354,7 +357,7 @@ export namespace DocUtils { return ctor ? ctor(path, overwriteDoc ? { ...options, title: StrCast(overwriteDoc.title, path) } : options, overwriteDoc) : undefined; } - export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false, pivotField?: string, pivotValue?: string): void { + export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false, pivotField?: string, pivotValue?: string | number | boolean): void { const documentList: ContextMenuProps[] = DocListCast(DocListCast(Doc.MyTools?.data)[0]?.data) .filter(btnDoc => !btnDoc.hidden) .map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)) @@ -451,7 +454,7 @@ export namespace DocUtils { batch.end(); return doc; } - export function findTemplate(templateName: string, type: string) { + export function findTemplate(templateName: string, doc: Doc) { let docLayoutTemplate: Opt; const iconViews = DocListCast(Cast(Doc.UserDoc().template_icons, Doc, null)?.data); const templBtns = DocListCast(Cast(Doc.UserDoc().template_buttons, Doc, null)?.data); @@ -469,7 +472,8 @@ export namespace DocUtils { // first try to find a template that matches the specific document type (_). otherwise, fallback to a general match on !docLayoutTemplate && allTemplates.forEach(tempDoc => { - StrCast(tempDoc.title) === templateName + '_' + type && (docLayoutTemplate = tempDoc); + const templateType = StrCast(doc[templateName + '_fieldKey'] || doc.type); + StrCast(tempDoc.title) === templateName + '_' + templateType && (docLayoutTemplate = tempDoc); }); !docLayoutTemplate && allTemplates.forEach(tempDoc => { @@ -481,7 +485,7 @@ export namespace DocUtils { const templateName = templateSignature.replace(/\(.*\)/, ''); doc.layout_fieldKey = 'layout_' + (templateSignature || (docLayoutTemplate?.title ?? '')); // eslint-disable-next-line no-param-reassign - docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, StrCast(doc.isGroup && doc.transcription ? 'transcription' : doc.type)); + docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, doc); const customName = 'layout_' + templateSignature; const _width = NumCast(doc._width); @@ -619,7 +623,7 @@ export namespace DocUtils { const proto = protoIn; if (Upload.isImageInformation(result)) { const maxNativeDim = Math.min(Math.max(result.nativeHeight, result.nativeWidth), defaultNativeImageDim); - const exifRotation = StrCast((result.exifData?.data as any)?.Orientation).toLowerCase(); + const exifRotation = StrCast(result.exifData?.data?.Orientation).toLowerCase(); proto.data_nativeOrientation = result.exifData?.data?.image?.Orientation ?? (exifRotation.includes('rotate 90') || exifRotation.includes('rotate 270') ? 5 : undefined); proto.data_nativeWidth = result.nativeWidth < result.nativeHeight ? (maxNativeDim * result.nativeWidth) / result.nativeHeight : maxNativeDim; proto.data_nativeHeight = result.nativeWidth < result.nativeHeight ? maxNativeDim : maxNativeDim / (result.nativeWidth / result.nativeHeight); @@ -697,10 +701,10 @@ export namespace DocUtils { source: { newFilename, mimetype }, result, } = upfiles.lastElement(); - if ((result as any).message) { + if (result instanceof Error) { if (overwriteDoc) { overwriteDoc.isLoading = false; - overwriteDoc.loadingError = (result as any).message; + overwriteDoc.loadingError = result.message; Doc.removeCurrentlyLoading(overwriteDoc); } } else newFilename && processFileupload(generatedDocuments, newFilename, mimetype ?? '', result, options, overwriteDoc); @@ -736,9 +740,9 @@ export namespace DocUtils { source: { newFilename, mimetype }, result, } = upfiles.lastElement() ?? { source: { newFilename: '', mimetype: '' }, result: { message: 'upload failed' } }; - if ((result as any).message) { + if (result instanceof Error) { if (overwriteDoc) { - overwriteDoc.loadingError = (result as any).message; + overwriteDoc.loadingError = result.message; Doc.removeCurrentlyLoading(overwriteDoc); } } else newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options, overwriteDoc); @@ -768,7 +772,7 @@ export namespace DocUtils { export async function Zip(doc: Doc, zipFilename = 'dashExport.zip') { const { clone, map, linkMap } = await Doc.MakeClone(doc); const proms = new Set(); - function replacer(key: any, value: any) { + function replacer(key: string, value: { url: string; [key: string]: unknown }) { if (key && ['branchOf', 'cloneOf', 'cursors'].includes(key)) return undefined; if (value?.__type === 'image') { const extension = value.url.replace(/.*\./, ''); @@ -804,8 +808,8 @@ export namespace DocUtils { return value; } - const docs: { [id: string]: any } = {}; - const links: { [id: string]: any } = {}; + const docs: { [id: string]: unknown } = {}; + const links: { [id: string]: unknown } = {}; Array.from(map.entries()).forEach(f => { docs[f[0]] = f[1]; }); @@ -826,13 +830,13 @@ export namespace DocUtils { } else promArr.forEach((url, i) => { // loading a file and add it in a zip file - JSZipUtils.getBinaryContent(window.location.origin + '/' + url, (err: any, data: any) => { + JSZipUtils.getBinaryContent(window.location.origin + '/' + url, (err: unknown, data: unknown) => { if (err) throw err; // or handle the error // // Generate a directory within the Zip file structure // const assets = zip.folder("assets"); // assets.file(filename, data, {binary: true}); const assetPathOnServer = promArr[i].replace(window.location.origin + '/', '').replace(/\//g, '%%%'); - zip.file(assetPathOnServer, data, { binary: true }); + zip.file(assetPathOnServer, data as string, { binary: true }); console.log(' => ' + url); if (++count === promArr.length) { zip.file('docs.json', jsonDocs); @@ -862,7 +866,7 @@ ScriptingGlobals.add(function copyDragFactory(dragFactory: Doc, asDelegate?: boo return dragFactory instanceof Doc ? (asDelegate ? DocUtils.delegateDragFactory(dragFactory) : DocUtils.copyDragFactory(dragFactory)) : dragFactory; }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function makeDelegate(proto: any) { +ScriptingGlobals.add(function makeDelegate(proto: Doc) { const d = Docs.Create.DelegateDocument(proto, { title: 'child of ' + proto.title }); return d; }); diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 8f95068db..53edb2e31 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -31,7 +31,6 @@ export enum DocumentType { // special purpose wrappers that either take no data or are compositions of lower level types LINK = 'link', - IMPORT = 'import', PRES = 'presentation', PRESELEMENT = 'preselement', COMPARISON = 'comparison', diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index b96fdb4bd..d7fdf016c 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -141,12 +141,12 @@ class RtfInfo extends FInfo { } class ListInfo extends FInfo { fieldType? = FInfoFieldType.list; - values?: List[] = []; + values?: List[] = []; } type BOOLt = BoolInfo | boolean; type NUMt = NumInfo | number; type STRt = StrInfo | string; -type LISTt = ListInfo | List; +type LISTt = ListInfo | List; type DOCt = DocInfo | Doc; type RTFt = RtfInfo | RichTextField; type DIMt = DimInfo; // | typeof DimUnit.Pixel | typeof DimUnit.Ratio; @@ -358,7 +358,7 @@ export class DocumentOptions { presentation_duration?: NUMt = new NumInfo('the duration of the slide in presentation view', false); presentation_zoomText?: BOOLt = new BoolInfo('whether text anchors should shown in a larger box when following links to make them stand out', false); - data?: any; + data?: FieldType; data_useCors?: BOOLt = new BoolInfo('whether CORS protocol should be used for web page'); columnHeaders?: List; // headers for stacking views schemaHeaders?: List; // headers for schema view @@ -464,13 +464,14 @@ export class DocumentOptions { sidebar_color?: string; // background color of text sidebar sidebar_type_collection?: string; // collection type of text sidebar - data_dashboards?: List; // list of dashboards used in shareddocs; + data_dashboards?: List; // list of dashboards used in shareddocs; textTransform?: string; letterSpacing?: string; iconTemplate?: string; // name of icon template style + icon_fieldKey?: string; // specifies the icon template to use (e.g., icon_fieldKey='george', then the icon template's name is icon_george; otherwise, the template's name would be icon_ where type is the Doc's type(pdf,rich text, etc)) selectedIndex?: NUMt = new NumInfo("which item in a linear view has been selected using the 'thumb doc' ui"); - fieldValues?: List; // possible values a field can have (used by FieldInfo's only) + fieldValues?: List; // possible values a field can have (used by FieldInfo's only) fieldType?: string; // display type of a field, e.g. string, number, enumeration (used by FieldInfo's only) clipboard?: Doc; @@ -484,7 +485,10 @@ export class DocumentOptions { } export const DocOptions = new DocumentOptions(); + +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Docs { + // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Prototypes { type LayoutSource = { LayoutString: (key: string) => string }; type PrototypeTemplate = { @@ -492,7 +496,6 @@ export namespace Docs { view: LayoutSource; dataField: string; }; - data?: any; options?: Partial; }; type TemplateMap = Map; @@ -554,7 +557,7 @@ export namespace Docs { const actualProtos = await DocServer.GetRefFields(prototypeIds); // update this object to include any default values: DocumentOptions for all prototypes prototypeIds.forEach(id => { - const existing = actualProtos[id] as Doc; + const existing = actualProtos.get(id); const type = id.replace(suffix, '') as DocumentType; // get or create prototype of the specified type... const target = buildPrototype(type, id, existing); @@ -627,16 +630,15 @@ export namespace Docs { acl_Guest: SharingPermissions.View, ...(template.options || {}), layout: layout.view?.LayoutString(layout.dataField), - data: template.data, }; Object.entries(options) .filter(pair => typeof pair[1] === 'string' && pair[1].startsWith('@')) .forEach(pair => { if (!existing || ScriptCast(existing[pair[0]])?.script.originalScript !== pair[1].substring(1)) { - (options as any)[pair[0]] = ComputedField.MakeFunction(pair[1].substring(1)); + (options as { [key: string]: unknown })[pair[0]] = ComputedField.MakeFunction(pair[1].substring(1)); } }); - return Doc.assign(existing ?? new Doc(prototypeId, true), OmitKeys(options, Object.keys(existing ?? {})).omit, undefined, true); + return Doc.assign(existing ?? new Doc(prototypeId, true), OmitKeys(options, Object.keys(existing ?? {})).omit as { [key: string]: FieldType }, undefined, true); } } @@ -644,6 +646,7 @@ export namespace Docs { * Encapsulates the factory used to create new document instances * delegated from top-level prototypes */ + // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Create { /** * This function receives the relevant document prototype and uses @@ -667,10 +670,10 @@ export namespace Docs { function InstanceFromProto(proto: Doc, data: FieldType | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = 'data', protoId?: string, placeholderDocIn?: Doc, noView?: boolean) { const placeholderDoc = placeholderDocIn; const viewKeys = ['x', 'y', 'isSystem']; // keys that should be addded to the view document even though they don't begin with an "_" - const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, '^_'); + const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, '^_') as { omit: { [key: string]: FieldType | undefined }; extract: { [key: string]: FieldType | undefined } }; // dataProps.acl_Override = SharingPermissions.Unset; - dataProps.acl_Guest = options.acl_Guest ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View); + dataProps.acl_Guest = options.acl_Guest?.toString() ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View); dataProps.isSystem = viewProps.isSystem; dataProps.isDataDoc = true; dataProps.author = ClientUtils.CurrentUserEmail(); @@ -693,7 +696,7 @@ export namespace Docs { } if (!noView) { - const viewFirstProps: { [id: string]: any } = { author: ClientUtils.CurrentUserEmail() }; + const viewFirstProps: { [id: string]: FieldType } = { author: ClientUtils.CurrentUserEmail() }; viewFirstProps.acl_Guest = options._acl_Guest ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View); let viewDoc: Doc; // determines whether viewDoc should be created using placeholder Doc or default @@ -710,7 +713,7 @@ export namespace Docs { viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewFirstProps, true, true); } Doc.assign(viewDoc, viewProps, true, true); - if (![DocumentType.LINK, DocumentType.CONFIG, DocumentType.LABEL].includes(viewDoc.type as any)) { + if (![DocumentType.LINK, DocumentType.CONFIG, DocumentType.LABEL].includes(viewDoc.type as DocumentType)) { CreateLinkToActiveAudio(() => viewDoc); } updateCachedAcls(dataDoc); @@ -909,7 +912,7 @@ export namespace Docs { } export function ConfigDocument(options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id, '', undefined, undefined, true); + return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), undefined, options, id, '', undefined, undefined, true); } export function PileDocument(documents: Array, options: DocumentOptions, id?: string) { diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx index 77cf80151..d0cd69273 100644 --- a/src/client/util/CalendarManager.tsx +++ b/src/client/util/CalendarManager.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { DateRangePicker, Provider, defaultTheme } from '@adobe/react-spectrum'; import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -19,6 +17,7 @@ import { DocumentView } from '../views/nodes/DocumentView'; import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; import './CalendarManager.scss'; import { SnappingManager } from './SnappingManager'; +import { CalendarDate, DateValue } from '@internationalized/date'; // import 'react-date-range/dist/styles.css'; // import 'react-date-range/dist/theme/default.css'; @@ -29,7 +28,7 @@ interface CalendarSelectOptions { value: string; } -const formatCalendarDateToString = (calendarDate: any) => { +const formatCalendarDateToString = (calendarDate: DateValue) => { console.log('Formatting the following date: ', calendarDate); const date = new Date(calendarDate.year, calendarDate.month - 1, calendarDate.day); console.log(typeof date); @@ -44,7 +43,7 @@ const formatCalendarDateToString = (calendarDate: any) => { // TODO: For a doc already in a calendar: give option to edit date range, delete from calendar @observer -export class CalendarManager extends ObservableReactComponent<{}> { +export class CalendarManager extends ObservableReactComponent { // eslint-disable-next-line no-use-before-define public static Instance: CalendarManager; @observable private isOpen = false; @@ -101,7 +100,7 @@ export class CalendarManager extends ObservableReactComponent<{}> { this.layoutDocAcls = false; }); - constructor(props: {}) { + constructor(props: object) { super(props); CalendarManager.Instance = this; makeObservable(this); @@ -109,15 +108,6 @@ export class CalendarManager extends ObservableReactComponent<{}> { componentDidMount(): void {} - @action - handleSelectChange = (option: any) => { - if (option) { - const selectOpt = option as CalendarSelectOptions; - this.selectedExistingCalendarOption = selectOpt; - this.calendarName = selectOpt.value; // or label - } - }; - @action handleCalendarTitleChange = (event: React.ChangeEvent) => { console.log('Existing calendars: ', this.existingCalendars); @@ -212,15 +202,13 @@ export class CalendarManager extends ObservableReactComponent<{}> { }; @observable - selectedDateRange: any = [ - { - start: new Date(), - end: new Date(), - }, - ]; + selectedDateRange: { start: DateValue; end: DateValue } = { + start: new CalendarDate(2024, 1, 1), + end: new CalendarDate(2024, 1, 1), + }; @action - setSelectedDateRange = (range: any) => { + setSelectedDateRange = (range: { start: DateValue; end: DateValue }) => { console.log('Range: ', range); this.selectedDateRange = range; }; @@ -228,14 +216,14 @@ export class CalendarManager extends ObservableReactComponent<{}> { @computed get createButtonActive() { if (this.calendarName.length === 0 || this.errorMessage.length > 0) return false; // disabled if no calendar name - let startDate: Date | undefined; - let endDate: Date | undefined; + let startDate: DateValue | undefined; + let endDate: DateValue | undefined; try { startDate = this.selectedDateRange.start; endDate = this.selectedDateRange.end; console.log(startDate); console.log(endDate); - } catch (e: any) { + } catch (e) { console.log(e); return false; // disabled } @@ -288,7 +276,13 @@ export class CalendarManager extends ObservableReactComponent<{}> { isSearchable options={this.selectOptions} value={this.selectedExistingCalendarOption} - onChange={this.handleSelectChange} + onChange={change => { + if (change) { + const selectOpt = change; + this.selectedExistingCalendarOption = selectOpt; + this.calendarName = selectOpt.value; // or label + } + }} styles={{ control: () => ({ display: 'inline-flex', diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx index 253cdd8b5..47f31612f 100644 --- a/src/client/util/CaptureManager.tsx +++ b/src/client/util/CaptureManager.tsx @@ -1,26 +1,24 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { addStyleSheet } from '../../ClientUtils'; -import { Doc } from '../../fields/Doc'; +import { Doc, Opt } from '../../fields/Doc'; import { DocCast, StrCast } from '../../fields/Types'; import { MainViewModal } from '../views/MainViewModal'; import { DocumentView } from '../views/nodes/DocumentView'; import './CaptureManager.scss'; @observer -export class CaptureManager extends React.Component<{}> { +export class CaptureManager extends React.Component { // eslint-disable-next-line no-use-before-define public static Instance: CaptureManager; static _settingsStyle = addStyleSheet(); - @observable _document: any = undefined; + @observable _document: Opt = undefined; @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not. // eslint-disable-next-line react/sort-comp - constructor(props: {}) { + constructor(props: object) { super(props); makeObservable(this); CaptureManager.Instance = this; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index e095bc659..c99ce1832 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1,7 +1,7 @@ import { reaction, runInAction } from "mobx"; import * as rp from 'request-promise'; import { ClientUtils, OmitKeys } from "../../ClientUtils"; -import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc"; +import { Doc, DocListCast, DocListCastAsync, FieldType, Opt } from "../../fields/Doc"; import { DocData } from "../../fields/DocSymbols"; import { InkTool } from "../../fields/InkField"; import { List } from "../../fields/List"; @@ -60,11 +60,10 @@ interface Button { // fields that do not correspond to DocumentOption fields scripts?: { script?: string; onClick?: string; onDoubleClick?: string } - funcs?: { [key:string]: any}; + funcs?: { [key:string]: string}; subMenu?: Button[]; } -// eslint-disable-next-line import/no-mutable-exports export let resolvedPorts: { server: number, socket: number }; export class CurrentUserUtils { @@ -174,8 +173,8 @@ export class CurrentUserUtils { const imageBox = (opts: DocumentOptions, fieldKey:string) => Docs.Create.ImageDocument( "http://www.cs.brown.edu/~bcz/noImage.png", { layout:ImageBox.LayoutString(fieldKey), "icon_nativeWidth": 360 / 4, "icon_nativeHeight": 270 / 4, iconTemplate:DocumentType.IMG, _width: 360 / 4, _height: 270 / 4, _layout_showTitle: "title", ...opts }); const fontBox = (opts:DocumentOptions, fieldKey:string) => Docs.Create.FontIconDocument({ layout:FontIconBox.LayoutString(fieldKey), _nativeHeight: 30, _nativeWidth: 30, _width: 30, _height: 30, ...opts }); - const makeIconTemplate = (type: DocumentType | undefined, templateField: string, opts:DocumentOptions) => { - const title = "icon" + (type ? "_" + type : ""); + const makeIconTemplate = (name: DocumentType | string | undefined, templateField: string, opts:DocumentOptions) => { + const title = "icon" + (name ? "_" + name : ""); const curIcon = DocCast(templateIconsDoc[title]); const creator = (() => { switch (opts.iconTemplate) { case DocumentType.IMG : return imageBox; @@ -189,6 +188,10 @@ export class CurrentUserUtils { {onClick:"deiconifyView(documentView)", onDoubleClick: "deiconifyViewToLightbox(documentView)", }); }; const iconTemplates = [ + // see createCustomView for where icon templates are created at run time + // templates defined by a Docs icon_fieldKey (e.g., ink with a transciprtion shows a template of the transcribed text, not miniature ink) + makeIconTemplate("transcription", "text", { iconTemplate:DocumentType.LABEL, backgroundColor: "orange" }), + // templates defined by a Doc's type makeIconTemplate(undefined, "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "dimgray"}), makeIconTemplate(DocumentType.AUDIO, "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "lightgreen"}), makeIconTemplate(DocumentType.PDF, "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "pink"}), @@ -199,10 +202,9 @@ export class CurrentUserUtils { makeIconTemplate(DocumentType.COL, "icon", { iconTemplate:DocumentType.IMG}), makeIconTemplate(DocumentType.VID, "icon", { iconTemplate:DocumentType.IMG}), makeIconTemplate(DocumentType.BUTTON,"title", { iconTemplate:DocumentType.FONTICON}), - // nasty hack .. templates are looked up exclusively by type -- but we want a template for a document with a certain field (transcription) .. so this hack and the companion hack in createCustomView does this for now - makeIconTemplate("transcription" as any, "transcription", { iconTemplate:DocumentType.LABEL, backgroundColor: "orange" }), - // makeIconTemplate(DocumentType.PDF, "icon", {iconTemplate:DocumentType.IMG}, (opts) => imageBox("http://www.cs.brown.edu/~bcz/noImage.png", opts)) - ].filter(d => d).map(d => d!); + // makeIconTemplate(DocumentType.PDF, "icon", { iconTemplate:DocumentType.IMG}), + ].filter(d => d).map(d => d!); + DocUtils.AssignOpts(DocCast(doc[field]), {}, iconTemplates); } @@ -349,9 +351,9 @@ pie title Minerals in my tap water plotlyApi(); mermaidsApi(); const emptyThings:{key:string, // the field name where the empty thing will be stored opts:DocumentOptions, // the document options that are required for the empty thing - funcs?:{[key:string]: any}, // computed fields that are rquired for the empth thing - scripts?:{[key:string]: any}, - creator:(opts:DocumentOptions)=> any // how to create the empty thing if it doesn't exist + funcs?:{[key:string]: string}, // computed fields that are rquired for the empth thing + scripts?:{[key:string]: string}, + creator:(opts:DocumentOptions)=> Doc // how to create the empty thing if it doesn't exist }[] = [ {key: "Note", creator: opts => Docs.Create.TextDocument("", opts), opts: { _width: 200, _layout_autoHeight: true }}, {key: "Flashcard", creator: opts => Docs.Create.ComparisonDocument("", opts), opts: { _layout_isFlashcard: true, _width: 300, _height: 300}}, @@ -402,7 +404,7 @@ pie title Minerals in my tap water { toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab)}, { toolTip: "Tap or drag to create a webpage", title: "Web", icon: "globe-asia", dragFactory: doc.emptyWebpage as Doc, clickFactory: DocCast(doc.emptyWebpage)}, { toolTip: "Tap or drag to create a comparison box", title: "Compare", icon: "columns", dragFactory: doc.emptyComparison as Doc, clickFactory: DocCast(doc.emptyComparison)}, - { toolTip: "Tap or drag to create a diagram", title: "Diagram", icon: "tree", dragFactory: doc.emptyDiagram as Doc, clickFactory: DocCast(doc.emptyDiagram)}, + { toolTip: "Tap or drag to create a diagram", title: "Diagram", icon: "tree", dragFactory: doc.emptyDiagram as Doc, clickFactory: DocCast(doc.emptyDiagram)}, { toolTip: "Tap or drag to create an audio recorder", title: "Audio", icon: "microphone", dragFactory: doc.emptyAudio as Doc, clickFactory: DocCast(doc.emptyAudio), openFactoryLocation: OpenWhere.overlay}, { toolTip: "Tap or drag to create a map", title: "Map", icon: "map-marker-alt", dragFactory: doc.emptyMap as Doc, clickFactory: DocCast(doc.emptyMap)}, { toolTip: "Tap or drag to create a chat assistant", title: "Assistant Chat", icon: "book",dragFactory: doc.emptyChat as Doc, clickFactory: DocCast(doc.emptyChat)}, @@ -411,11 +413,11 @@ pie title Minerals in my tap water { toolTip: "Tap or drag to create a button", title: "Button", icon: "circle", dragFactory: doc.emptyButton as Doc, clickFactory: DocCast(doc.emptyButton)}, { toolTip: "Tap or drag to create a scripting box", title: "Script", icon: "terminal", dragFactory: doc.emptyScript as Doc, clickFactory: DocCast(doc.emptyScript), funcs: { hidden: "IsNoviceMode()"}}, { toolTip: "Tap or drag to create a data viz node", title: "DataViz", icon: "chart-bar", dragFactory: doc.emptyDataViz as Doc, clickFactory: DocCast(doc.emptyDataViz)}, - { toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "person-chalkboard", dragFactory: doc.emptySlide as Doc, clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}}, - { toolTip: "Tap or drag to create a view slide", title: "View Slide", icon: "address-card", dragFactory: doc.emptyViewSlide as Doc,clickFactory: DocCast(doc.emptyViewSlide),openFactoryLocation: OpenWhere.overlay,funcs: { hidden: "IsNoviceMode()"}}, - { toolTip: "Tap or drag to create a data note", title: "DataNote", icon: "window-maximize",dragFactory: doc.emptyHeader as Doc,clickFactory: DocCast(doc.emptyHeader), openFactoryAsDelegate: true, funcs: { hidden: "IsNoviceMode()"} }, - { toolTip: "Toggle a Calculator REPL", title: "replviewer", icon: "calculator", clickFactory: '' as any, openFactoryLocation: OpenWhere.overlay}, // hack: clickFactory is not a Doc but will get interpreted as a custom UI by the openDoc() onClick script - // { toolTip: "Toggle an UndoStack", title: "undostacker", icon: "calculator", clickFactory: "" as any, openFactoryLocation: OpenWhere.overlay}, + { toolTip: "Tap or drag to create a bullet slide", title: "PPT Slide", icon: "person-chalkboard",dragFactory: doc.emptySlide as Doc,clickFactory: DocCast(doc.emptySlide), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}}, + { toolTip: "Tap or drag to create a view slide", title: "View Slide", icon: "address-card", dragFactory: doc.emptyViewSlide as Doc,clickFactory: DocCast(doc.emptyViewSlide), openFactoryLocation: OpenWhere.overlay,funcs: { hidden: "IsNoviceMode()"}}, + { toolTip: "Tap or drag to create a data note", title: "DataNote", icon: "window-maximize",dragFactory: doc.emptyHeader as Doc,clickFactory: DocCast(doc.emptyHeader), openFactoryAsDelegate: true, funcs: { hidden: "IsNoviceMode()"} }, + { toolTip: "Toggle a Calculator REPL", title: "replviewer", icon: "calculator", clickFactory: '' as unknown as Doc, openFactoryLocation: OpenWhere.overlay}, // hack: clickFactory is not a Doc but will get interpreted as a custom UI by the openDoc() onClick script + // { toolTip: "Toggle an UndoStack", title: "undostacker", icon: "calculator", clickFactory: "" as any, openFactoryLocation: OpenWhere.overlay}, ].map(tuple => ( { openFactoryLocation: OpenWhere.addRight, scripts: { onClick: 'openDoc(copyDragFactory(this.clickFactory,this.openFactoryAsDelegate), this.openFactoryLocation)', @@ -445,7 +447,7 @@ pie title Minerals in my tap water } /// returns descriptions needed to buttons for the left sidebar to open up panes displaying different collections of documents - static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, toolTip: string, scripts:{[key:string]:any}, funcs?:{[key:string]:any}, hidden?: boolean}[] { + static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, toolTip: string, scripts:{[key:string]:undefined|string}, funcs?:{[key:string]:undefined|string}, hidden?: boolean}[] { const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(this.target?.data).filter(doc => !docList(this.target.viewed).includes(doc)).length.toString())"; const getActiveDashTrails = "Doc.ActiveDashboard?.myTrails"; return [ @@ -463,7 +465,7 @@ pie title Minerals in my tap water /// the empty panel that is filled with whichever left menu button's panel has been selected static setupLeftSidebarPanel(doc: Doc, field="myLeftSidebarPanel") { - DocUtils.AssignDocField(doc, field, (opts) => Doc.assign(new Doc(), opts as any), {title:"leftSidebarPanel", isSystem:true, undoIgnoreFields: new List(['proto'])}); + DocUtils.AssignDocField(doc, field, (opts) => Doc.assign(new Doc(), opts as {[key:string]: FieldType}), {title:"leftSidebarPanel", isSystem:true, undoIgnoreFields: new List(['proto'])}); } /// Initializes the left sidebar menu buttons and the panels they open up @@ -523,7 +525,7 @@ pie title Minerals in my tap water const contextMenuLabels = [/* "Create New Dashboard" */] as string[]; const contextMenuIcons = [/* "plus" */] as string[]; const childContextMenuScripts = [`toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(this)`, 'removeDashboard(this)', 'resetDashboard(this)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters - const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, '!IsNoviceMode()'];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts + const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', undefined, undefined, '!IsNoviceMode()'];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts const childContextMenuLabels = ["Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"];// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters const childContextMenuIcons = ["tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters const reqdOpts:DocumentOptions = { @@ -545,7 +547,7 @@ pie title Minerals in my tap water myDashboards.childContextMenuScripts = new List(childContextMenuScripts.map(script => ScriptField.MakeFunction(script)!)); } if (Cast(myDashboards.childContextMenuFilters, listSpec(ScriptField), null)?.length !== childContextMenuFilters.length) { - myDashboards.childContextMenuFilters = new List(childContextMenuFilters.map(script => !script ? script: ScriptField.MakeFunction(script)!)); + myDashboards.childContextMenuFilters = new List(childContextMenuFilters.map(script => !script ? script as unknown as ScriptField: ScriptField.MakeFunction(script)!)); } return myDashboards; } @@ -611,7 +613,7 @@ pie title Minerals in my tap water _lockedPosition: true, isSystem: true, flexDirection: "row" }) static multiToggleList = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.FontIconDocument({ - ...opts, data:docs, _gridGap: 0, _xMargin: 5, _yMargin: 5, layout_boxShadow: "0 0", _forceActive: true, + ...opts, data: new List(docs), _gridGap: 0, _xMargin: 5, _yMargin: 5, layout_boxShadow: "0 0", _forceActive: true, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), _lockedPosition: true, isSystem: true, flexDirection: "row" }) @@ -806,7 +808,7 @@ pie title Minerals in my tap water /// initializes a context menu button for the top bar context menu static setupContextMenuButton(params:Button, btnDoc?:Doc, btnContainer?:Doc) { const reqdOpts:DocumentOptions = { - ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, + ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit as {[key:string]: string|undefined}, color: Colors.WHITE, isSystem: true, _nativeWidth: params.width ?? 30, _width: params.width ?? 30, _height: 30, _nativeHeight: 30, linearBtnWidth: params.linearBtnWidth, @@ -814,7 +816,7 @@ pie title Minerals in my tap water _dragOnlyWithinContainer: true, _lockedPosition: true, _embedContainer: btnContainer }; - const reqdFuncs:{[key:string]:any} = { + const reqdFuncs:{[key:string]:string} = { ...params.funcs, } return DocUtils.AssignScripts(DocUtils.AssignOpts(btnDoc, reqdOpts) ?? Docs.Create.FontIconDocument(reqdOpts), params.scripts, reqdFuncs); @@ -853,14 +855,14 @@ pie title Minerals in my tap water Doc.UserDoc().workspaceRecordingState = undefined; Doc.UserDoc().workspaceReplayingState = undefined; const dockedBtns = DocCast(doc[field]); - const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:any}) => + const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:string|undefined}) => DocUtils.AssignScripts(DocUtils.AssignOpts(DocListCast(dockedBtns?.data)?.find(fdoc => fdoc.title === opts.title), opts) ?? CurrentUserUtils.createToolButton(opts), scripts, funcs); const btnDescs = [// setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet - { opts: { title: "Replicate",icon:"camera",toolTip: "Copy dashboard layout",btnType: ButtonType.ClickButton, expertMode: true}, scripts: { onClick: `snapshotDashboard()`}}, - { opts: { title: "Recordings", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList,expertMode: false, ignoreClick: true, width: 100}, funcs: {hidden: `false`, btnList:`getWorkspaceRecordings()`}, scripts: { script: `{ return replayWorkspace(value, _readOnly_); }`, onDragScript: `{ return startRecordingDrag(value); }`}}, - { opts: { title: "Stop Rec",icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `!isWorkspaceRecording()`}, scripts: { onClick: `stopWorkspaceRecording()`}}, + { opts: { title: "Replicate",icon:"camera",toolTip: "Copy dashboard layout",btnType: ButtonType.ClickButton, expertMode: true}, scripts: { onClick: `snapshotDashboard()`}}, + { opts: { title: "Recordings", toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList,expertMode: false, ignoreClick: true, width: 100}, funcs: {hidden: `false`, btnList:`getWorkspaceRecordings()`},scripts: { script: `{ return replayWorkspace(value, _readOnly_); }`, onDragScript: `{ return startRecordingDrag(value); }`}}, + { opts: { title: "Stop Rec",icon: "stop", toolTip: "Stop recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `!isWorkspaceRecording()`}, scripts: { onClick: `stopWorkspaceRecording()`}}, { opts: { title: "Play", icon: "play", toolTip: "Play recording", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${mediaState.Paused}"`}, scripts: { onClick: `resumeWorkspaceReplaying(getCurrentRecording())`}}, { opts: { title: "Pause", icon: "pause",toolTip: "Pause playback", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${mediaState.Playing}"`}, scripts: { onClick: `pauseWorkspaceReplaying(getCurrentRecording())`}}, { opts: { title: "Stop", icon: "stop", toolTip: "Stop playback", btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${mediaState.Paused}"`}, scripts: { onClick: `stopWorkspaceReplaying(getCurrentRecording())`}}, @@ -1002,20 +1004,20 @@ pie title Minerals in my tap water return doc; } static setupFieldInfos(doc:Doc, field="fieldInfos") { - const fieldInfoOpts = { title: "Field Infos", isSystem: true}; // bcz: all possible document options have associated field infos which are stored onn the FieldInfos document **except for title and system which are used as part of the definition of the fieldInfos object - const infos = DocUtils.AssignDocField(doc, field, opts => Doc.assign(new Doc(), opts as any), fieldInfoOpts); + const fieldInfoOpts = { title: "Field Infos", isSystem: true}; // bcz: all possible document options have associated field infos which are stored on the FieldInfos document **except for title and system which are used as part of the definition of the fieldInfos object + const infos = DocUtils.AssignDocField(doc, field, opts => Doc.assign(new Doc(), opts as {[key:string]: FieldType}), fieldInfoOpts); const entries = Object.entries(new DocumentOptions()); entries.forEach(pair => { if (!Array.from(Object.keys(fieldInfoOpts)).includes(pair[0])) { const options = pair[1] as FInfo; - const opts:DocumentOptions = { isSystem: true, title: pair[0], ...OmitKeys(options, ["values"]).omit, fieldIsLayout: pair[0].startsWith("_")}; + const opts:DocumentOptions = { isSystem: true, title: pair[0], ...OmitKeys(options, ["values"]).omit}; switch (options.fieldType) { - case FInfoFieldType.boolean: opts.fieldValues = new List(options.values as any); break; - case FInfoFieldType.number: opts.fieldValues = new List(options.values as any); break; - case FInfoFieldType.Doc: opts.fieldValues = new List(options.values as any); break; - default: opts.fieldValues = new List(options.values as any); break;// string, pointerEvents, dimUnit, dropActionType + case FInfoFieldType.boolean: opts.fieldValues = new List(options.values as boolean[]); break; + case FInfoFieldType.number: opts.fieldValues = new List(options.values as number[]); break; + case FInfoFieldType.Doc: opts.fieldValues = new List(options.values as Doc[]); break; + default: opts.fieldValues = new List(options.values); break;// string, pointerEvents, dimUnit, dropActionType } - DocUtils.AssignDocField(infos, pair[0], docOpts => Doc.assign(new Doc(), OmitKeys(docOpts,["values"]).omit), opts); + DocUtils.AssignDocField(infos, pair[0], docOpts => Doc.assign(new Doc(), OmitKeys(docOpts,["values"]).omit as {[key:string]: FieldType}), opts); } }); } @@ -1023,10 +1025,10 @@ pie title Minerals in my tap water public static async loadCurrentUser() { return rp.get(ClientUtils.prepend("/getCurrentUser")).then(async response => { if (response) { - const result: { version: string, userDocumentId: string, sharingDocumentId: string, linkDatabaseId: string, email: string, cacheDocumentIds: string, resolvedPorts: string } = JSON.parse(response); + const result: { version: string, userDocumentId: string, sharingDocumentId: string, linkDatabaseId: string, email: string, cacheDocumentIds: string, resolvedPorts: {server: number, socket: number} } = JSON.parse(response); runInAction(() => { SnappingManager.SetServerVersion(result.version); }); ClientUtils.SetCurrentUserEmail(result.email); - resolvedPorts = result.resolvedPorts as any; + resolvedPorts = result.resolvedPorts; DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts?.socket, result.email); if (result.cacheDocumentIds) { diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts index bc9fe813f..16a0df120 100644 --- a/src/client/util/DictationManager.ts +++ b/src/client/util/DictationManager.ts @@ -1,7 +1,5 @@ /* eslint-disable no-use-before-define */ import * as interpreter from 'words-to-numbers'; -// @ts-ignore bcz: how are you supposed to include these definitions since dom-speech-recognition isn't a module? -import type {} from '@types/dom-speech-recognition'; import { ClientUtils } from '../../ClientUtils'; import { Doc, Opt } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; @@ -33,19 +31,24 @@ import { UndoManager } from './UndoManager'; * In addition to compile-time default commands, you can invoke DictationManager.Commands.Register(Independent|Dependent) * to add new commands as classes or components are constructed. */ + +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DictationManager { /** * Some type maneuvering to access Webkit's built-in * speech recognizer. */ + + // eslint-disable-next-line @typescript-eslint/no-namespace namespace CORE { export interface IWindow extends Window { - webkitSpeechRecognition: any; + webkitSpeechRecognition: { new (): SpeechRecognition }; } } - const { webkitSpeechRecognition }: CORE.IWindow = window as any as CORE.IWindow; + const { webkitSpeechRecognition }: CORE.IWindow = window as unknown as CORE.IWindow; export const placeholder = 'Listening...'; + // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Controls { export const Infringed = 'unable to process: dictation manager still involved in previous session'; const browser = (() => { @@ -74,7 +77,7 @@ export namespace DictationManager { // eslint-disable-next-line new-cap const recognizer: Opt = webkitSpeechRecognition ? new webkitSpeechRecognition() : undefined; - export type InterimResultHandler = (results: string) => any; + export type InterimResultHandler = (results: string) => void; export type ContinuityArgs = { indefinite: boolean } | false; export type DelimiterArgs = { inter: string; intra: string }; export type ListeningUIStatus = { interim: boolean } | false; @@ -117,11 +120,11 @@ export namespace DictationManager { } options?.tryExecute && (await DictationManager.Commands.execute(results)); } - } catch (e: any) { + } catch (e) { console.log(e); if (overlay) { DictationOverlay.Instance.isListening = false; - DictationOverlay.Instance.dictatedPhrase = results = `dictation error: ${'error' in e ? e.error : 'unknown error'}`; + DictationOverlay.Instance.dictatedPhrase = results = `dictation error: ${(e as { error: string }).error || 'unknown error'}`; DictationOverlay.Instance.dictationSuccess = false; } } finally { @@ -156,11 +159,11 @@ export namespace DictationManager { recognizer.start(); return new Promise(resolve => { - recognizer.onerror = (e: any) => { + recognizer.onerror = e => { // e is SpeechRecognitionError but where is that defined? if (!(indefinite && e.error === 'no-speech')) { recognizer.stop(); - resolve(e); + resolve(e.message); } }; @@ -227,13 +230,14 @@ export namespace DictationManager { }; } + // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Commands { export const dictationFadeDuration = 2000; - export type IndependentAction = (target: DocumentView) => any | Promise; + export type IndependentAction = (target: DocumentView) => void | Promise; export type IndependentEntry = { action: IndependentAction; restrictTo?: DocumentType[] }; - export type DependentAction = (target: DocumentView, matches: RegExpExecArray) => any | Promise; + export type DependentAction = (target: DocumentView, matches: RegExpExecArray) => void | Promise; export type DependentEntry = { expression: RegExp; action: DependentAction; restrictTo?: DocumentType[] }; export const RegisterIndependent = (key: string, value: IndependentEntry) => Independent.set(key, value); @@ -295,7 +299,6 @@ export namespace DictationManager { [DocumentType.COL, listSpec(Doc)], [DocumentType.AUDIO, AudioField], [DocumentType.IMG, ImageField], - [DocumentType.IMPORT, listSpec(Doc)], [DocumentType.RTF, 'string'], ]); @@ -397,8 +400,8 @@ export namespace DictationManager { ]; } export function recordAudioAnnotation(dataDoc: Doc, field: string, onRecording?: (stop: () => void) => void, onEnd?: () => void) { - let gumStream: any; - let recorder: any; + let gumStream: MediaStream | undefined; + let recorder: MediaRecorder | undefined; navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => { let audioTextAnnos = Cast(dataDoc[field + '_audioAnnotations_text'], listSpec('string'), null); if (audioTextAnnos) audioTextAnnos.push(''); @@ -415,8 +418,12 @@ export namespace DictationManager { gumStream = stream; recorder = new MediaRecorder(stream); - recorder.ondataavailable = async (e: any) => { - const [{ result }] = await Networking.UploadFilesToServer({ file: e.data }); + recorder.ondataavailable = async (e: BlobEvent) => { + const file: Blob & { name?: string; lastModified?: number; webkitRelativePath?: string } = e.data; + file.name = ''; + file.lastModified = 0; + file.webkitRelativePath = ''; + const [{ result }] = await Networking.UploadFilesToServer({ file: file as Blob & { name: string; lastModified: number; webkitRelativePath: string } }); if (!(result instanceof Error)) { const audioField = new AudioField(result.accessPaths.agnostic.client); const audioAnnos = Cast(dataDoc[field + '_audioAnnotations'], listSpec(AudioField), null); @@ -426,10 +433,10 @@ export namespace DictationManager { }; recorder.start(); const stopFunc = () => { - recorder.stop(); + recorder?.stop(); DictationManager.Controls.stop(/* false */); dataDoc.audioAnnoState = AudioAnnoState.stopped; - gumStream.getAudioTracks()[0].stop(); + gumStream?.getAudioTracks()[0].stop(); }; if (onRecording) onRecording(stopFunc); else setTimeout(stopFunc, 5000); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index e41546d09..b12bf4390 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -50,22 +50,19 @@ export class DocumentManager { DocumentView.getLightboxDocumentView = this.getLightboxDocumentView; observe(Doc.CurrentlyLoading, change => { // watch CurrentlyLoading-- when something is loaded, it's removed from the list and we have to update its icon if it were iconified since LoadingBox icons are different than the media they become - switch (change.type as any) { + switch (change.type) { case 'update': break; - case 'remove': - // DocumentManager.Instance.getAllDocumentViews(change as any).forEach(dv => StrCast(dv.Document.layout_fieldKey) === 'layout_icon' && dv.iconify(() => dv.iconify())); - break; case 'splice': - (change as any).removed.forEach((doc: Doc) => DocumentManager.Instance.getAllDocumentViews(doc).forEach(dv => StrCast(dv.Document.layout_fieldKey) === 'layout_icon' && dv.iconify(() => dv.iconify()))); + change.removed.forEach((doc: Doc) => DocumentManager.Instance.getAllDocumentViews(doc).forEach(dv => StrCast(dv.Document.layout_fieldKey) === 'layout_icon' && dv.iconify(() => dv.iconify()))); break; default: } }); } - private _viewRenderedCbs: { doc: Doc; func: (dv: DocumentView) => any }[] = []; - public AddViewRenderedCb = (doc: Opt, func: (dv: DocumentView) => any) => { + private _viewRenderedCbs: { doc: Doc; func: (dv: DocumentView) => unknown }[] = []; + public AddViewRenderedCb = (doc: Opt, func: (dv: DocumentView) => unknown) => { if (doc) { const dv = DocumentView.LightboxDoc() ? this.getLightboxDocumentView(doc) : this.getDocumentView(doc); this._viewRenderedCbs.push({ doc, func }); @@ -74,6 +71,7 @@ export class DocumentManager { return true; } } else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any func(undefined as any); } return false; @@ -341,18 +339,21 @@ export class DocumentManager { // if there's an options.effect, it will be handled from linkFollowHighlight. We delay the start of // the highlight so that the target document can be somewhat centered so that the effect/highlight will be seen // bcz: should this delay be an options parameter? - setTimeout(() => { - Doc.linkFollowHighlight(viewSpec ? [docView.Document, viewSpec] : docView.Document, undefined, options.effect); - if (options.zoomTextSelections && Doc.IsUnhighlightTimerSet() && contextView && targetDoc.text_html) { - // if the docView is a text anchor, the contextView is the PDF/Web/Text doc - contextView.setTextHtmlOverlay(StrCast(targetDoc.text_html), options.effect); - DocumentManager._overlayViews.add(contextView); - } - Doc.AddUnHighlightWatcher(() => { - docView.Document[Animation] = undefined; - DocumentManager.removeOverlayViews(); - }); - }, (options.zoomTime ?? 0) * 0.5); + setTimeout( + () => { + Doc.linkFollowHighlight(viewSpec ? [docView.Document, viewSpec] : docView.Document, undefined, options.effect); + if (options.zoomTextSelections && Doc.IsUnhighlightTimerSet() && contextView && targetDoc.text_html) { + // if the docView is a text anchor, the contextView is the PDF/Web/Text doc + contextView.setTextHtmlOverlay(StrCast(targetDoc.text_html), options.effect); + DocumentManager._overlayViews.add(contextView); + } + Doc.AddUnHighlightWatcher(() => { + docView.Document[Animation] = undefined; + DocumentManager.removeOverlayViews(); + }); + }, + (options.zoomTime ?? 0) * 0.5 + ); if (options.playMedia) docView.ComponentView?.playFrom?.(NumCast(docView.Document._layout_currentTimecode)); if (options.playAudio) DocumentManager.playAudioAnno(docView.Document); if (options.toggleTarget && (!options.didMove || docView.Document.hidden)) docView.Document.hidden = !docView.Document.hidden; diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index fda505420..c237a75de 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -1,4 +1,3 @@ -/* eslint-disable import/no-mutable-exports */ /* eslint-disable no-use-before-define */ /** * The DragManager handles all dragging interactions that occur entirely within Dash (as opposed to external drag operations from the file system, etc) @@ -23,13 +22,14 @@ import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; import { PrefetchProxy } from '../../fields/Proxy'; import { ScriptField } from '../../fields/ScriptField'; -import { ScriptCast } from '../../fields/Types'; +import { ScriptCast, StrCast } from '../../fields/Types'; import { Docs } from '../documents/Documents'; import { DocumentView } from '../views/nodes/DocumentView'; import { dropActionType } from './DropActionTypes'; import { SnappingManager } from './SnappingManager'; import { UndoManager } from './UndoManager'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const { contextMenuZindex } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore /** @@ -70,6 +70,7 @@ export function SetupDrag(_reference: React.RefObject, docFunc: () return onItemDown; } +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DragManager { export const dragClassName = 'collectionFreeFormDocumentView-container'; let dragDiv: HTMLDivElement; @@ -78,7 +79,7 @@ export namespace DragManager { export let CompleteWindowDrag: Opt<(aborted: boolean) => void>; export let AbortDrag: () => void = emptyFunction; export const docsBeingDragged: Doc[] = observable([]); - export let DocDragData: DocumentDragData | undefined; + export let DraggedDocs: Doc[] | undefined; export function Root() { const root = document.getElementById('root'); @@ -118,7 +119,7 @@ export namespace DragManager { // event called when the drag operation has completed (aborted or completed a drop) -- this will be after any drop event has been generated export class DragCompleteEvent { - constructor(aborted: boolean, dragData: { [id: string]: any }) { + constructor(aborted: boolean, dragData: DocumentDragData | AnchorAnnoDragData | LinkDragData | ColumnDragData) { this.aborted = aborted; this.docDragData = dragData instanceof DocumentDragData ? dragData : undefined; this.annoDragData = dragData instanceof AnchorAnnoDragData ? dragData : undefined; @@ -167,6 +168,9 @@ export namespace DragManager { linkSourceGetAnchor: () => Doc; linkSourceDoc?: Doc; linkDragView: DocumentView; + get canEmbed() { + return true; + } } export class ColumnDragData { // constructor(colKey: SchemaHeaderField) { @@ -177,6 +181,9 @@ export namespace DragManager { this.colIndex = colIndex; } colIndex: number; + get canEmbed() { + return true; + } } // used by PDFs,Text,Image,Video,Web to conditionally (if the drop completes) create a text annotation when dragging the annotate button from the AnchorMenu when a text/region selection has been made. // this is pretty clunky and should be rethought out using linkDrag or DocumentDrag @@ -191,6 +198,9 @@ export namespace DragManager { offset: number[]; dropAction?: dropActionType; userDropAction?: dropActionType; + get canEmbed() { + return true; + } } const defaultPreDropFunc = (e: Event, de: DragManager.DropEvent, targetAction: dropActionType) => { @@ -208,7 +218,7 @@ export namespace DragManager { const handler = (e: Event) => dropFunc(e, (e as CustomEvent).detail); const preDropHandler = (e: Event) => { const de = (e as CustomEvent).detail; - (preDropFunc ?? defaultPreDropFunc)(e, de, doc.dropAction as any as dropActionType); + (preDropFunc ?? defaultPreDropFunc)(e, de, StrCast(doc.dropAction) as dropActionType); }; element.addEventListener('dashOnDrop', handler); element.addEventListener('dashPreDrop', preDropHandler); @@ -220,8 +230,8 @@ export namespace DragManager { } // drag a document and drop it (or make an embed/copy on drop) - export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions, onDropCompleted?: (e?: DragCompleteEvent) => any) { - const addAudioTag = (dropDoc: any) => { + export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions, onDropCompleted?: (e?: DragCompleteEvent) => unknown) { + const addAudioTag = (dropDoc: Doc) => { dropDoc && !dropDoc.author_date && (dropDoc.author_date = new DateField()); dropDoc instanceof Doc && CreateLinkToActiveAudio(() => dropDoc); return dropDoc; @@ -236,7 +246,7 @@ export namespace DragManager { await Promise.all( dragData.draggedDocuments.map(async d => !dragData.isDocDecorationMove && !dragData.userDropAction && ScriptCast(d.onDragStart) - ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) + ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result as Doc) : docDragData.dropAction === dropActionType.embed ? Doc.BestEmbedding(d) : docDragData.dropAction === dropActionType.add @@ -249,7 +259,7 @@ export namespace DragManager { ) ) ).filter(d => d); - ![dropActionType.same, dropActionType.proto].includes(docDragData.dropAction as any) && + ![dropActionType.same, dropActionType.proto].includes(StrCast(docDragData.dropAction) as dropActionType) && docDragData.droppedDocuments // .filter(drop => !drop.dragOnlyWithinContainer || ['embed', 'copy'].includes(docDragData.dropAction as any)) .forEach((drop: Doc, i: number) => { @@ -376,9 +386,18 @@ export namespace DragManager { options?.dragComplete?.(complete); endDrag?.(); } - export function StartDrag(elesIn: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void, dragUndoName?: string) { - if (dragData.dropAction === 'none' || SnappingManager.ExploreMode) return; - DocDragData = dragData as DocumentDragData; + export function StartDrag( + elesIn: HTMLElement[], + dragData: DocumentDragData | LinkDragData | ColumnDragData | AnchorAnnoDragData, + downX: number, + downY: number, + options?: DragOptions, + finishDrag?: (dropData: DragCompleteEvent) => void, + dragUndoName?: string + ) { + if (SnappingManager.ExploreMode) return; + const docDragData = dragData instanceof DocumentDragData ? dragData : undefined; + DraggedDocs = docDragData?.draggedDocuments; const batch = UndoManager.StartBatch(dragUndoName ?? 'document drag'); const eles = elesIn.filter(e => e); SnappingManager.SetCanEmbed(dragData.canEmbed || false); @@ -437,8 +456,9 @@ export namespace DragManager { next && children.push(...Array.from(next.children)); if (next) { ['marker-start', 'marker-mid', 'marker-end'].forEach(field => { - if (next.localName.startsWith('path') && (next.attributes as any)[field]) { - next.setAttribute(field, (next.attributes as any)[field].value.replace('#', '#X')); + if (next.localName.startsWith('path')) { + const item = next.attributes.getNamedItem(field); + item && next.setAttribute(field, item.value.replace('#', '#X')); } }); if (next.localName.startsWith('marker')) { @@ -495,7 +515,7 @@ export namespace DragManager { .map((pb, i) => pb.getContext('2d')!.drawImage(pdfBoxSrc[i], 0, 0)); } [dragElement, ...Array.from(dragElement.getElementsByTagName('*'))] - .map(dele => (dele as any).style) + .map(dele => (dele as HTMLElement)?.style) .forEach(style => { style && (style.pointerEvents = 'none'); }); @@ -536,34 +556,35 @@ export namespace DragManager { const yFromBottom = elesCont.bottom - downY; let scrollAwaiter: Opt; - let startWindowDragTimer: any; + let startWindowDragTimer: NodeJS.Timeout | undefined; const moveHandler = (e: PointerEvent) => { e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop - if (dragData instanceof DocumentDragData) { - dragData.userDropAction = e.ctrlKey && e.altKey ? dropActionType.copy : e.shiftKey ? dropActionType.move : e.ctrlKey ? dropActionType.embed : dragData.defaultDropAction; - } - if (['lm_tab', 'lm_title_wrap', 'lm_tabs', 'lm_header'].includes(typeof (e.target as any).className === 'string' ? (e.target as any)?.className : '') && dragData.draggedDocuments.length === 1) { - if (!startWindowDragTimer) { - startWindowDragTimer = setTimeout(async () => { - startWindowDragTimer = undefined; - dragData.dropAction = dragData.userDropAction || 'same'; - AbortDrag(); - await finishDrag?.(new DragCompleteEvent(true, dragData)); - DragManager.StartWindowDrag?.(e, dragData.droppedDocuments, aborted => { - if (!aborted && (dragData.dropAction === 'move' || dragData.dropAction === 'same')) { - dragData.removeDocument?.(dragData.draggedDocuments[0]); - } - }); - }, 500); + if (docDragData) { + docDragData.userDropAction = e.ctrlKey && e.altKey ? dropActionType.copy : e.shiftKey ? dropActionType.move : e.ctrlKey ? dropActionType.embed : docDragData.defaultDropAction; + const targClassName = e.target instanceof HTMLElement && typeof e.target.className === 'string' ? e.target.className : ''; + if (['lm_tab', 'lm_title_wrap', 'lm_tabs', 'lm_header'].includes(targClassName) && docDragData.draggedDocuments.length === 1) { + if (!startWindowDragTimer) { + startWindowDragTimer = setTimeout(async () => { + startWindowDragTimer = undefined; + docDragData.dropAction = docDragData.userDropAction || dropActionType.same; + AbortDrag(); + await finishDrag?.(new DragCompleteEvent(true, docDragData)); + DragManager.StartWindowDrag?.(e, docDragData.droppedDocuments, aborted => { + if (!aborted && (docDragData?.dropAction === 'move' || docDragData?.dropAction === 'same')) { + docDragData.removeDocument?.(docDragData?.draggedDocuments[0]); + } + }); + }, 500); + } + } else { + clearTimeout(startWindowDragTimer); + startWindowDragTimer = undefined; } - } else { - clearTimeout(startWindowDragTimer); - startWindowDragTimer = undefined; } const target = document.elementFromPoint(e.x, e.y); - if (target && !Doc.UserDoc()._noAutoscroll && !options?.noAutoscroll && !dragData.draggedDocuments?.some((d: any) => d._freeform_noAutoPan)) { + if (target && !Doc.UserDoc()._noAutoscroll && !options?.noAutoscroll && !(docDragData?.draggedDocuments as Doc[])?.some(d => d._freeform_noAutoPan)) { const autoScrollHandler = () => { target.dispatchEvent( new CustomEvent('dashDragMovePause', { @@ -587,7 +608,7 @@ export namespace DragManager { screenX: e.screenX, screenY: e.screenY, detail: e.detail, - view: e.view ? e.view : (new Window() as any), + view: { ...(e.view ?? new Window()), styleMedia: { type: '', matchMedium: () => false } }, // bcz: Ugh.. this looks wrong nativeEvent: new DragEvent('dashDragMovePause'), currentTarget: target, target: target, @@ -596,10 +617,10 @@ export namespace DragManager { defaultPrevented: true, eventPhase: e.eventPhase, isTrusted: true, - preventDefault: () => 'not implemented for this event' && false, - isDefaultPrevented: () => 'not implemented for this event' && false, - stopPropagation: () => 'not implemented for this event' && false, - isPropagationStopped: () => 'not implemented for this event' && false, + preventDefault: () => 'not implemented for this event', + isDefaultPrevented: () => false, + stopPropagation: () => 'not implemented for this event', + isPropagationStopped: () => false, persist: emptyFunction, timeStamp: e.timeStamp, type: 'dashDragMovePause', diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts index 0314af06b..eb2011b77 100644 --- a/src/client/util/DropConverter.ts +++ b/src/client/util/DropConverter.ts @@ -26,9 +26,10 @@ function makeTemplate(doc: Doc, first: boolean = true): boolean { if (layoutDoc.layout instanceof Doc) { return true; // its already a template } - const layout = StrCast(layoutDoc.layout).match(/fieldKey={'[^']*'}/)![0]; - const fieldKey = layout.replace("fieldKey={'", '').replace(/'}$/, ''); - const docs = DocListCast(layoutDoc[fieldKey]); + const layout = StrCast(layoutDoc.layout).match(/fieldKey={'[^']*'}/)?.[0]; + const fieldKey = layout?.replace("fieldKey={'", '').replace(/'}$/, ''); + const docData = fieldKey ? layoutDoc[fieldKey] : undefined; + const docs = DocListCast(docData); let isTemplate = false; docs.forEach(d => { if (!StrCast(d.title).startsWith('-')) { @@ -40,7 +41,7 @@ function makeTemplate(doc: Doc, first: boolean = true): boolean { if (first && !docs.length) { // bcz: feels hacky : if the root level document has items, it's not a field template isTemplate = Doc.MakeMetadataFieldTemplate(doc, layoutDoc[DocData], true) || isTemplate; - } else if (layoutDoc[fieldKey] instanceof RichTextField || layoutDoc[fieldKey] instanceof ImageField) { + } else if (docData instanceof RichTextField || docData instanceof ImageField) { if (!StrCast(layoutDoc.title).startsWith('-')) { isTemplate = Doc.MakeMetadataFieldTemplate(layoutDoc, layoutDoc[DocData], true); } @@ -110,8 +111,8 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) { } ScriptingGlobals.add( // eslint-disable-next-line prefer-arrow-callback - function convertToButtons(dragData: any) { - convertDropDataToButtons(dragData as DragManager.DocumentDragData); + function convertToButtons(dragData: DragManager.DocumentDragData) { + convertDropDataToButtons(dragData); }, 'converts the dropped data to buttons', '(dragData: any)' diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx index 5701a22c0..9d0817a06 100644 --- a/src/client/util/GroupManager.tsx +++ b/src/client/util/GroupManager.tsx @@ -1,8 +1,6 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button, IconButton, Size, Type } from 'browndash-components'; -import { action, computed, makeObservable, observable } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import Select from 'react-select'; @@ -31,7 +29,7 @@ export interface UserOptions { } @observer -export class GroupManager extends ObservableReactComponent<{}> { +export class GroupManager extends ObservableReactComponent { // eslint-disable-next-line no-use-before-define static Instance: GroupManager; @observable isOpen: boolean = false; // whether the GroupManager is to be displayed or not. @@ -44,7 +42,7 @@ export class GroupManager extends ObservableReactComponent<{}> { @observable private buttonColour: '#979797' | 'black' = '#979797'; @observable private groupSort: 'ascending' | 'descending' | 'none' = 'none'; - constructor(props: Readonly<{}>) { + constructor(props: Readonly) { super(props); makeObservable(this); GroupManager.Instance = this; @@ -226,15 +224,6 @@ export class GroupManager extends ObservableReactComponent<{}> { } } - /** - * Handles changes in the users selected in the "Select users" dropdown. - * @param selectedOptions - */ - @action - handleChange = (selectedOptions: any) => { - this.selectedUsers = selectedOptions as UserOptions[]; - }; - /** * Creates the group when the enter key has been pressed (when in the input). * @param e @@ -309,7 +298,6 @@ export class GroupManager extends ObservableReactComponent<{}> { { className="select-users" isMulti options={this.options} - onChange={this.handleChange} + onChange={selectedOptions => { + runInAction(() => (this.selectedUsers = Array.from(selectedOptions))); + }} placeholder="Select users" value={this.selectedUsers} closeMenuOnSelect={false} diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx index da9e1aa28..88d73d742 100644 --- a/src/client/util/GroupMemberView.tsx +++ b/src/client/util/GroupMemberView.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button, IconButton, Size, Type } from 'browndash-components'; import { action, observable } from 'mobx'; diff --git a/src/client/util/History.ts b/src/client/util/History.ts index 52d0223d5..067c28c6b 100644 --- a/src/client/util/History.ts +++ b/src/client/util/History.ts @@ -10,6 +10,7 @@ import { OmitKeys, ClientUtils } from '../../ClientUtils'; import { DocServer } from '../DocServer'; import { DashboardView } from '../views/DashboardView'; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace HistoryUtil { export interface DocInitializerList { [key: string]: string | number; @@ -85,7 +86,7 @@ export namespace HistoryUtil { const parsers: { [type: string]: (pathname: string[], opts: qs.ParsedQuery) => ParsedUrl | undefined } = {}; const stringifiers: { [type: string]: (state: ParsedUrl) => string } = {}; - type ParserValue = true | 'none' | 'json' | ((value: string) => any); + type ParserValue = true | 'none' | 'json' | ((value: string) => string | null | (string | null)[]); type Parser = { [key: string]: ParserValue; @@ -106,7 +107,7 @@ export namespace HistoryUtil { return value; } parsers[type] = (pathname, opts) => { - const current: any = { type }; + const current: DocUrl & { [key: string]: null | (string | null)[] | string } = { type: 'doc', docId: '' }; for (const required in requiredFields) { if (!(required in opts)) { return undefined; @@ -148,7 +149,7 @@ export namespace HistoryUtil { path = customStringifier(state, path); } const queryObj = OmitKeys(state, keys).extract; - const query: any = {}; + const query: { [key: string]: string | null } = {}; Object.keys(queryObj).forEach(key => { query[key] = queryObj[key] === null ? null : JSON.stringify(queryObj[key]); }); diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts index 8d4eefa7e..266e05f08 100644 --- a/src/client/util/Import & Export/ImageUtils.ts +++ b/src/client/util/Import & Export/ImageUtils.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import { ClientUtils } from '../../../ClientUtils'; import { Doc } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx index db1e3d6cd..63dedf820 100644 --- a/src/client/util/Import & Export/ImportMetadataEntry.tsx +++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable no-use-before-define */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed } from 'mobx'; diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index a07550e09..f3ede596d 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -1,8 +1,10 @@ +import { Property } from 'csstype'; import * as React from 'react'; import { Utils } from '../../Utils'; import { Gestures } from '../../pen-gestures/GestureTypes'; import './InteractionUtils.scss'; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace InteractionUtils { export const MOUSETYPE = 'mouse'; export const TOUCHTYPE = 'touch'; @@ -11,7 +13,7 @@ export namespace InteractionUtils { const ERASER_BUTTON = 5; - export function makePolygon(shape: string, points: { X: number; Y: number }[]) { + export function makePolygon(shape: Gestures, points: { X: number; Y: number }[]) { // if arrow/line/circle, the two end points should be the starting and the ending point let left = points[0].X; let top = points[0].Y; @@ -19,7 +21,7 @@ export namespace InteractionUtils { let bottom = points[1].Y; if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y + 1 === points[0].Y) { // pointer is up (first and last points are the same) - if (![Gestures.Arrow, Gestures.Line, Gestures.Circle].includes(shape as any as Gestures)) { + if (![Gestures.Arrow, Gestures.Line, Gestures.Circle].includes(shape)) { // otherwise take max and min const xs = points.map(p => p.X); const ys = points.map(p => p.Y); @@ -98,8 +100,8 @@ export namespace InteractionUtils { color: string, width: number, strokeWidth: number, - lineJoin: string, - strokeLineCap: string, + lineJoin: Property.StrokeLinejoin, + strokeLineCap: Property.StrokeLinecap, bezier: string, fill: string, arrowStart: string, @@ -108,8 +110,8 @@ export namespace InteractionUtils { dash: string | undefined, scalexIn: number, scaleyIn: number, - shape: string, - pevents: string, + shape: Gestures, + pevents: Property.PointerEvents, opacity: number, nodefs: boolean, downHdlr?: (e: React.PointerEvent) => void, @@ -154,7 +156,7 @@ export namespace InteractionUtils { @@ -184,10 +186,10 @@ export namespace InteractionUtils { filter: mask ? `url(#mask${defGuid})` : undefined, opacity: 1.0, // opacity: strokeWidth !== width ? 0.5 : undefined, - pointerEvents: (pevents as any) === 'all' ? 'visiblepainted' : (pevents as any), + pointerEvents: pevents === 'all' ? 'visiblePainted' : pevents, stroke: color ?? 'rgb(0, 0, 0)', strokeWidth, - strokeLinecap: strokeLineCap as any, + strokeLinecap: strokeLineCap, strokeDasharray: dashArray, transition: 'inherit', }} diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts index 9a0edcfec..0a3a0ba49 100644 --- a/src/client/util/LinkFollower.ts +++ b/src/client/util/LinkFollower.ts @@ -50,7 +50,7 @@ export class LinkFollower { const backLinks = linkDocs.filter(l => isAnchor(sourceDoc, l.link_anchor_2 as Doc)); // link docs where 'sourceDoc' is link_anchor_2 const fwdLinkWithoutTargetView = fwdLinks.find(l => !getView(DocCast(l.link_anchor_2))); const backLinkWithoutTargetView = backLinks.find(l => !getView(DocCast(l.link_anchor_1))); - const linkWithoutTargetDoc = traverseBacklink === undefined ? fwdLinkWithoutTargetView ?? backLinkWithoutTargetView : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView; + const linkWithoutTargetDoc = traverseBacklink === undefined ? (fwdLinkWithoutTargetView ?? backLinkWithoutTargetView) : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView; const linkDocList = linkWithoutTargetDoc && !sourceDoc.followAllLinks ? [linkWithoutTargetDoc] : traverseBacklink === undefined ? fwdLinks.concat(backLinks) : traverseBacklink ? backLinks : fwdLinks; const followLinks = sourceDoc.followLinkToggle || sourceDoc.followAllLinks ? linkDocList : linkDocList.slice(0, 1); let count = 0; @@ -82,7 +82,7 @@ export class LinkFollower { willZoomCentered: BoolCast(srcAnchor.followLinkZoom, false), zoomTime: NumCast(srcAnchor.followLinkTransitionTime, 500), zoomScale: Cast(srcAnchor.followLinkZoomScale, 'number', null), - easeFunc: StrCast(srcAnchor.followLinkEase, 'ease') as any, + easeFunc: StrCast(srcAnchor.followLinkEase, 'ease') as 'ease' | 'linear', openLocation: StrCast(srcAnchor.followLinkLocation, OpenWhere.lightbox) as OpenWhere, effect: srcAnchor, zoomTextSelections: BoolCast(srcAnchor.followLinkZoomText), diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 56d5dce4e..e11482572 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -31,13 +31,13 @@ export class LinkManager { @observable public currentLink: Opt = undefined; @observable public currentLinkAnchor: Opt = undefined; public static get Instance(): LinkManager { - return Doc.UserDoc() ? LinkManager._instance ?? new LinkManager() : (undefined as any as LinkManager); + return Doc.UserDoc() ? (LinkManager._instance ?? new LinkManager()) : (undefined as unknown as LinkManager); } public static Links(doc: Doc | undefined) { return doc ? LinkManager.Instance.getAllRelatedLinks(doc) : []; } - public addLinkDB = async (linkDb: any) => { + public addLinkDB = async (linkDb: Doc) => { await Promise.all( ((await DocListCastAsync(linkDb.data)) ?? []).map(link => // makes sure link anchors are loaded to avoid incremental updates to computedFns in LinkManager @@ -95,35 +95,24 @@ export class LinkManager { const watchUserLinkDB = (userLinkDBDoc: Doc) => { const toRealField = (field: FieldType) => (field instanceof ProxyField ? field.value : field); // see List.ts. data structure is not a simple list of Docs, but a list of ProxyField/Fields if (userLinkDBDoc.data) { + // observe pushes/splices on a user link DB 'data' field (should only happen for local changes) observe( - userLinkDBDoc.data, + userLinkDBDoc.data as unknown as Doc[], change => { - // observe pushes/splices on a user link DB 'data' field (should only happen for local changes) - switch (change.type as any) { + switch (change.type) { case 'splice': - (change as any).added.forEach((link: any) => addLinkToDoc(toRealField(link))); - (change as any).removed.forEach((link: any) => remLinkFromDoc(toRealField(link))); + change.added.forEach(link => addLinkToDoc(toRealField(link))); + change.removed.forEach(link => remLinkFromDoc(toRealField(link))); break; - case 'update': // let oldValue = change.oldValue; - default: - } - }, - true - ); - observe( - userLinkDBDoc, - 'data', // obsever when a new array of links is assigned as the link DB 'data' field (should happen whenever a remote user adds/removes a link) - change => { - switch (change.type as any) { case 'update': - Promise.all([...((change.oldValue as any as Doc[]) || []), ...((change.newValue as any as Doc[]) || [])]).then(doclist => { - const oldDocs = doclist.slice(0, ((change.oldValue as any as Doc[]) || []).length); - const newDocs = doclist.slice(((change.oldValue as any as Doc[]) || []).length, doclist.length); + Promise.all([...((change.oldValue as unknown as Doc[]) || []), ...((change.newValue as unknown as Doc[]) || [])]).then(doclist => { + const oldDocs = doclist.slice(0, ((change.oldValue as unknown as Doc[]) || []).length); + const newDocs = doclist.slice(((change.oldValue as unknown as Doc[]) || []).length, doclist.length); const added = newDocs?.filter(link => !(oldDocs || []).includes(link)); const removed = oldDocs?.filter(link => !(newDocs || []).includes(link)); - added?.forEach((link: any) => addLinkToDoc(toRealField(link))); - removed?.forEach((link: any) => remLinkFromDoc(toRealField(link))); + added?.forEach(link => addLinkToDoc(toRealField(link))); + removed?.forEach(link => remLinkFromDoc(toRealField(link))); }); break; default: @@ -136,9 +125,9 @@ export class LinkManager { observe( this.userLinkDBs, change => { - switch (change.type as any) { + switch (change.type) { case 'splice': - (change as any).added.forEach(watchUserLinkDB); + change.added.forEach(watchUserLinkDB); break; case 'update': // let oldValue = change.oldValue; default: @@ -188,7 +177,7 @@ export class LinkManager { return []; } - const dirLinks = Array.from(anchor[DocData][DirectLinks]).filter(l => Doc.GetProto(anchor) === anchor[DocData] || ['1', '2'].includes(LinkManager.anchorIndex(l, anchor) as any)); + const dirLinks = Array.from(anchor[DocData][DirectLinks]).filter(l => Doc.GetProto(anchor) === anchor[DocData] || ['1', '2'].includes(LinkManager.anchorIndex(l, anchor) as '0' | '1' | '2')); const anchorRoot = DocCast(anchor.rootDocument, anchor); // template Doc fields store annotations on the topmost root of a template (not on themselves since the template layout items are only for layout) const annos = DocListCast(anchorRoot[Doc.LayoutFieldKey(anchor) + '_annotations']); return Array.from( @@ -283,7 +272,7 @@ export function UPDATE_SERVER_CACHE() { ScriptingGlobals.add( // eslint-disable-next-line prefer-arrow-callback - function links(doc: any) { + function links(doc: Doc) { return new List(LinkManager.Links(doc)); }, 'returns all the links to the document or its annotations', diff --git a/src/client/util/ProsemirrorCopy/prompt.js b/src/client/util/ProsemirrorCopy/prompt.js deleted file mode 100644 index b9068195f..000000000 --- a/src/client/util/ProsemirrorCopy/prompt.js +++ /dev/null @@ -1,179 +0,0 @@ -const prefix = "ProseMirror-prompt" - -export function openPrompt(options) { - let wrapper = document.body.appendChild(document.createElement("div")) - wrapper.className = prefix - wrapper.style.zIndex = 1000; - wrapper.style.width = 250; - wrapper.style.textAlign = "center"; - - let mouseOutside = e => { if (!wrapper.contains(e.target)) close() } - setTimeout(() => window.addEventListener("mousedown", mouseOutside), 50) - let close = () => { - window.removeEventListener("mousedown", mouseOutside) - if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper) - } - - let domFields = [] - for (let name in options.fields) domFields.push(options.fields[name].render()) - - let submitButton = document.createElement("button") - submitButton.type = "submit" - submitButton.className = prefix + "-submit" - submitButton.textContent = "OK" - let cancelButton = document.createElement("button") - cancelButton.type = "button" - cancelButton.className = prefix + "-cancel" - cancelButton.textContent = "Cancel" - cancelButton.addEventListener("click", close) - - let form = wrapper.appendChild(document.createElement("form")) - let title = document.createElement("h5") - title.style.marginBottom = 15 - title.style.marginTop = 10 - if (options.title) form.appendChild(title).textContent = options.title - domFields.forEach(field => { - form.appendChild(document.createElement("div")).appendChild(field) - }) - let b = document.createElement("div"); - b.style.marginTop = 15; - let buttons = form.appendChild(b) - // buttons.className = prefix + "-buttons" - buttons.appendChild(submitButton) - buttons.appendChild(document.createTextNode(" ")) - buttons.appendChild(cancelButton) - - let box = wrapper.getBoundingClientRect() - wrapper.style.top = options.flyout_top + "px" - wrapper.style.left = options.flyout_left + "px" - - let submit = () => { - let params = getValues(options.fields, domFields) - if (params) { - close() - options.callback(params) - } - } - - form.addEventListener("submit", e => { - e.preventDefault() - submit() - }) - - form.addEventListener("keydown", e => { - if (e.keyCode == 27) { - e.preventDefault() - close() - } else if (e.keyCode == 13 && !(e.ctrlKey || e.metaKey || e.shiftKey)) { - e.preventDefault() - submit() - } else if (e.keyCode == 9) { - window.setTimeout(() => { - if (!wrapper.contains(document.activeElement)) close() - }, 500) - } - }) - - let input = form.elements[0] - if (input) input.focus() -} - -function getValues(fields, domFields) { - let result = Object.create(null), i = 0 - for (let name in fields) { - let field = fields[name], dom = domFields[i++] - let value = field.read(dom), bad = field.validate(value) - if (bad) { - reportInvalid(dom, bad) - return null - } - result[name] = field.clean(value) - } - return result -} - -function reportInvalid(dom, message) { - // FIXME this is awful and needs a lot more work - let parent = dom.parentNode - let msg = parent.appendChild(document.createElement("div")) - msg.style.left = (dom.offsetLeft + dom.offsetWidth + 2) + "px" - msg.style.top = (dom.offsetTop - 5) + "px" - msg.className = "ProseMirror-invalid" - msg.textContent = message - setTimeout(() => parent.removeChild(msg), 1500) -} - -// ::- The type of field that `FieldPrompt` expects to be passed to it. -export class Field { - // :: (Object) - // Create a field with the given options. Options support by all - // field types are: - // - // **`value`**`: ?any` - // : The starting value for the field. - // - // **`label`**`: string` - // : The label for the field. - // - // **`required`**`: ?bool` - // : Whether the field is required. - // - // **`validate`**`: ?(any) → ?string` - // : A function to validate the given value. Should return an - // error message if it is not valid. - constructor(options) { this.options = options } - - // render:: (state: EditorState, props: Object) → dom.Node - // Render the field to the DOM. Should be implemented by all subclasses. - - // :: (dom.Node) → any - // Read the field's value from its DOM node. - read(dom) { return dom.value } - - // :: (any) → ?string - // A field-type-specific validation function. - validateType(_value) { } - - validate(value) { - if (!value && this.options.required) - return "Required field" - return this.validateType(value) || (this.options.validate && this.options.validate(value)) - } - - clean(value) { - return this.options.clean ? this.options.clean(value) : value - } -} - -// ::- A field class for single-line text fields. -export class TextField extends Field { - render() { - let input = document.createElement("input") - input.type = "text" - input.placeholder = this.options.label - input.value = this.options.value || "" - input.autocomplete = "off" - input.style.marginBottom = 4 - input.style.border = "1px solid black" - input.style.padding = "4px 4px" - return input - } -} - - -// ::- A field class for dropdown fields based on a plain ` tag, but for some reason we do... @@ -211,13 +211,15 @@ export class ContextMenu extends ObservableReactComponent<{}> { return (
{ - if (r) { - this._width = DivWidth(r); - this._height = DivHeight(r); - } - this._searchRef.current?.focus(); - })} + ref={r => + runInAction(() => { + if (r) { + this._width = DivWidth(r); + this._height = DivHeight(r); + } + this._searchRef.current?.focus(); + }) + } style={{ display: this._display ? '' : 'none', left: this.pageX, @@ -239,7 +241,6 @@ export class ContextMenu extends ObservableReactComponent<{}> { value={this._searchString} onKeyDown={this.onKeyDown} onChange={this.onChange} - // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus /> diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index eb1030eec..3b87ea58b 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -10,8 +10,10 @@ import { ObservableReactComponent } from './ObservableReactComponent'; export interface OriginalMenuProps { description: string; - event: (stuff?: any) => void; + event: (stuff?: unknown) => void; undoable?: boolean; + noexpand?: boolean; + subitems?: ContextMenuProps[]; icon: IconProp | JSX.Element; // maybe should be optional (icon?) closeMenu?: () => void; } @@ -33,7 +35,7 @@ export class ContextMenuItem extends ObservableReactComponent = []; @observable private overItem = false; - constructor(props: any) { + constructor(props: ContextMenuProps & { selected?: boolean }) { super(props); makeObservable(this); } @@ -56,7 +58,7 @@ export class ContextMenuItem extends ObservableReactComponent { +export class DashboardView extends ObservableReactComponent { public static _urlState: HistoryUtil.DocUrl; public static makeDocumentConfig(document: Doc, panelName?: string, width?: number, keyValue?: boolean) { return { @@ -82,7 +80,7 @@ export class DashboardView extends ObservableReactComponent<{}> { }); return doc; } - constructor(props: any) { + constructor(props: object) { super(props); makeObservable(this); } diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index c97edd7f0..b11fa3bd5 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -1,6 +1,4 @@ /* eslint-disable react/jsx-props-no-spreading */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { action, computed, makeObservable, observable, ObservableMap } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -28,7 +26,7 @@ interface filterProps { export class FilterPanel extends ObservableReactComponent { @observable _selectedFacetHeaders = new Set(); - constructor(props: any) { + constructor(props: filterProps) { super(props); makeObservable(this); } @@ -41,7 +39,7 @@ export class FilterPanel extends ObservableReactComponent { } @computed get targetDocChildKey() { const targetView = DocumentView.getFirstDocumentView(this.Document); - return targetView?.ComponentView?.annotationKey ?? targetView?.ComponentView?.fieldKey ?? 'data'; + return targetView?.ComponentView?.annotationKey || (targetView?.ComponentView?.fieldKey ?? 'data'); } @computed get targetDocChildren() { return [...DocListCast(this.Document?.[this.targetDocChildKey] || Doc.ActiveDashboard?.data), ...DocListCast(this.Document[Doc.LayoutFieldKey(this.Document) + '_sidebar'])]; @@ -240,7 +238,7 @@ export class FilterPanel extends ObservableReactComponent { {Array.from(this.activeRenderedFacetInfos.keys()).map( // iterate over activeFacetRenderInfos ==> renderInfo which you can renderInfo.facetHeader renderInfo => ( -
+
{renderInfo.facetHeader.charAt(0).toUpperCase() + renderInfo.facetHeader.slice(1)} @@ -308,7 +306,7 @@ export class FilterPanel extends ObservableReactComponent { return this.facetValues(facetHeader).map(fval => { const facetValue = fval; return ( -
+
{
{handles.map(handle => ( // const value = i === 0 ? defaultValues[0] : defaultValues[1]; -
+
))} diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index e3e252593..804c41091 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -78,7 +78,7 @@ export class GestureOverlay extends ObservableReactComponent { - if (!(e.target as any)?.className?.toString().startsWith('lm_')) { + if (!(e.target as HTMLElement)?.className?.toString().startsWith('lm_')) { if ([InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) { this._points.push({ X: e.clientX, Y: e.clientY }); setupMoveUpEvents(this, e, this.onPointerMove, this.onPointerUp, emptyFunction); @@ -173,8 +173,8 @@ export class GestureOverlay extends ObservableReactComponent { + const bezierCurves = fitCurve.default(newPoints, 10); + Array.from(bezierCurves).forEach(curve => { controlPoints.push({ X: curve[0][0], Y: curve[0][1] }); controlPoints.push({ X: curve[1][0], Y: curve[1][1] }); controlPoints.push({ X: curve[2][0], Y: curve[2][1] }); @@ -351,7 +351,7 @@ export class GestureOverlay extends ObservableReactComponent { + dispatchGesture = (gesture: Gestures, stroke?: InkData, text?: string) => { const points = (stroke ?? this._points).slice(); return ( document.elementFromPoint(points[0].X, points[0].Y)?.dispatchEvent( @@ -411,7 +411,7 @@ export class GestureOverlay extends ObservableReactComponent { - GestureOverlay.Instance.Tool = tool; - }); -}); -// eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function setPen(width: any, color: any, fill: any, arrowStart: any, arrowEnd: any, dash: any) { +ScriptingGlobals.add(function setPen(width: string, color: string, fill: string, arrowStart: string, arrowEnd: string, dash: string) { runInAction(() => { GestureOverlay.Instance.SavedColor = ActiveInkColor(); SetActiveInkColor(color); @@ -543,8 +537,8 @@ ScriptingGlobals.add(function resetPen() { }, 'resets the pen tool'); ScriptingGlobals.add( // eslint-disable-next-line prefer-arrow-callback - function createText(text: any, x: any, y: any) { - GestureOverlay.Instance.dispatchGesture(Gestures.Text, [{ X: x, Y: y }], text); + function createText(text: string, X: number, Y: number) { + GestureOverlay.Instance.dispatchGesture(Gestures.Text, [{ X, Y }], text); }, 'creates a text document with inputted text and coordinates', '(text: any, x: any, y: any)' diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx index 1ed8de1be..33db72960 100644 --- a/src/client/views/InkTranscription.tsx +++ b/src/client/views/InkTranscription.tsx @@ -240,7 +240,8 @@ // const text = exports['text/plain']; // if (this.currGroup) { -// this.currGroup.transcription = text; +// this.currGroup.text = text; // transcription text +// this.currGroup.icon_fieldKey = 'transcription'; // use the transcription icon template when iconifying // this.currGroup.title = text.split('\n')[0]; // } diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 784d252a3..2e82371cb 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -20,6 +20,7 @@ Most of the operations that can be performed on an InkStroke (eg delete a point, rotate, stretch) are implemented in the InkStrokeProperties helper class */ +import { Property } from 'csstype'; import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -28,6 +29,7 @@ import { Doc } from '../../fields/Doc'; import { InkData, InkField } from '../../fields/InkField'; import { BoolCast, Cast, NumCast, RTFCast, StrCast } from '../../fields/Types'; import { TraceMobx } from '../../fields/util'; +import { Gestures } from '../../pen-gestures/GestureTypes'; import { CognitiveServices } from '../cognitive_services/CognitiveServices'; import { Docs } from '../documents/Documents'; import { DocumentType } from '../documents/DocumentTypes'; @@ -35,7 +37,6 @@ import { InteractionUtils } from '../util/InteractionUtils'; import { SnappingManager } from '../util/SnappingManager'; import { UndoManager } from '../util/UndoManager'; import { ContextMenu } from './ContextMenu'; -import { ViewBoxInterface } from './ViewBoxInterface'; import { ViewBoxAnnotatableComponent } from './DocComponent'; import { Colors } from './global/globalEnums'; import { InkControlPtHandles, InkEndPtHandles } from './InkControlPtHandles'; @@ -46,6 +47,7 @@ import { FieldView, FieldViewProps } from './nodes/FieldView'; import { FormattedTextBox, FormattedTextBoxProps } from './nodes/formattedText/FormattedTextBox'; import { PinDocView, PinProps } from './PinFuncs'; import { StyleProp } from './StyleProp'; +import { ViewBoxInterface } from './ViewBoxInterface'; // eslint-disable-next-line @typescript-eslint/no-var-requires const { INK_MASK_SIZE } = require('./global/globalCssVariables.module.scss'); // prettier-ignore @@ -318,8 +320,8 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() Colors.MEDIUM_BLUE, screenInkWidth[0], screenSpaceCenterlineStrokeWidth, - StrCast(inkDoc.stroke_lineJoin), - StrCast(this.layoutDoc.stroke_lineCap), + StrCast(inkDoc.stroke_lineJoin) as Property.StrokeLinejoin, + StrCast(this.layoutDoc.stroke_lineCap) as Property.StrokeLinecap, StrCast(inkDoc.stroke_bezier), 'none', startMarker, @@ -328,7 +330,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() StrCast(inkDoc.stroke_dash), 1, 1, - '', + '' as Gestures, 'none', 1.0, false @@ -383,8 +385,8 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() this.strokeColor, inkStrokeWidth, inkStrokeWidth, - StrCast(this.layoutDoc.stroke_lineJoin), - StrCast(this.layoutDoc.stroke_lineCap), + StrCast(this.layoutDoc.stroke_lineJoin) as Property.StrokeLinejoin, + StrCast(this.layoutDoc.stroke_lineCap) as Property.StrokeLinecap, StrCast(this.layoutDoc.stroke_bezier), !closed ? 'none' : fillColor === 'transparent' ? 'none' : fillColor, startMarker, @@ -393,7 +395,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() StrCast(this.layoutDoc.stroke_dash), inkScaleX, inkScaleY, - '', + '' as Gestures, 'none', 1.0, false, @@ -410,8 +412,8 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() mask && color === 'transparent' ? this.strokeColor : (highlightColor ?? color), inkStrokeWidth, inkStrokeWidth + NumCast(this.layoutDoc.stroke_borderWidth) + (fillColor ? (closed ? higlightMargin : (highlightIndex ?? 0) + higlightMargin) : higlightMargin), - StrCast(this.layoutDoc.stroke_lineJoin), - StrCast(this.layoutDoc.stroke_lineCap), + StrCast(this.layoutDoc.stroke_lineJoin) as Property.StrokeLinejoin, + StrCast(this.layoutDoc.stroke_lineCap) as Property.StrokeLinecap, StrCast(this.layoutDoc.stroke_bezier), !closed || !fillColor || DashColor(fillColor).alpha() === 0 ? 'none' : fillColor, startMarker, @@ -420,7 +422,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent() StrCast(this.layoutDoc.stroke_dash), inkScaleX, inkScaleY, - '', + '' as Gestures, this._props.pointerEvents?.() ?? 'visiblePainted', 0.0, false, diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 7198c7f05..adbe20a63 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -1,6 +1,4 @@ /* eslint-disable no-use-before-define */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Toggle, ToggleType, Type } from 'browndash-components'; @@ -12,7 +10,7 @@ import { emptyFunction } from '../../Utils'; import { CreateLinkToActiveAudio, Doc, DocListCast, FieldResult, Opt } from '../../fields/Doc'; import { Id } from '../../fields/FieldSymbols'; import { InkTool } from '../../fields/InkField'; -import { Cast, NumCast, toList } from '../../fields/Types'; +import { BoolCast, Cast, NumCast, toList } from '../../fields/Types'; import { SnappingManager } from '../util/SnappingManager'; import { Transform } from '../util/Transform'; import { GestureOverlay } from './GestureOverlay'; @@ -28,7 +26,7 @@ interface LightboxViewProps { PanelWidth: number; PanelHeight: number; maxBorder: number[]; - addSplit: (document: Doc, pullSide: OpenWhereMod, stack?: any, panelName?: string | undefined, keyValue?: boolean | undefined) => boolean; + addSplit: (document: Doc, pullSide: OpenWhereMod, stack?: unknown, panelName?: string | undefined, keyValue?: boolean | undefined) => boolean; } const savedKeys = ['freeform_panX', 'freeform_panY', 'freeform_scale', 'layout_scrollTop', 'layout_fieldKey']; @@ -63,7 +61,7 @@ export class LightboxView extends ObservableReactComponent { @computed get leftBorder() { return Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]); } // prettier-ignore @computed get topBorder() { return Math.min(this._props.PanelHeight / 4, this._props.maxBorder[1]); } // prettier-ignore - constructor(props: any) { + constructor(props: LightboxViewProps) { super(props); makeObservable(this); LightboxView.Instance = this; @@ -214,7 +212,7 @@ export class LightboxView extends ObservableReactComponent { lightboxDocTemplate = () => this._layoutTemplate; future = () => this._future; - renderNavBtn = (left: Opt, bottom: Opt, top: number, icon: IconProp, display: any, click: () => void, color?: string) => ( + renderNavBtn = (left: Opt, bottom: Opt, top: number, icon: IconProp, display: boolean, click: () => void, color?: string) => (
{ render() { let downx = 0; let downy = 0; - const toggleBtn = (classname: string, tooltip: string, toggleBackground: any, icon: IconProp, icon2: IconProp | string, onClick: () => void) => ( + const toggleBtn = (classname: string, tooltip: string, toggleBackground: boolean, icon: IconProp, icon2: IconProp | string, onClick: () => void) => (
{
- {this.renderNavBtn(0, undefined, this._props.PanelHeight / 2 - 12.5, 'chevron-left', this._doc && this._history.length, this.previous)} + {this.renderNavBtn(0, undefined, this._props.PanelHeight / 2 - 12.5, 'chevron-left', this._doc && this._history.length ? true : false, this.previous)} {this.renderNavBtn( this._props.PanelWidth - Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]), undefined, this._props.PanelHeight / 2 - 12.5, 'chevron-right', - this._doc && this._future.length, + this._doc && this._future.length ? true : false, this.next, this.future().length.toString() )} - {toggleBtn('lightboxView-navBtn', 'toggle reading view', this._doc?._layout_fitWidth, 'book-open', 'book', this.toggleFitWidth)} + {toggleBtn('lightboxView-navBtn', 'toggle reading view', BoolCast(this._doc?._layout_fitWidth), 'book-open', 'book', this.toggleFitWidth)} {toggleBtn('lightboxView-tabBtn', 'open document in a tab', false, 'file-download', '', this.downloadDoc)} {toggleBtn('lightboxView-penBtn', 'toggle pen annotation', Doc.ActiveTool === InkTool.Pen, 'pen', '', this.togglePen)} {toggleBtn('lightboxView-exploreBtn', 'toggle navigate only mode', SnappingManager.ExploreMode, 'globe-americas', '', this.toggleExplore)} @@ -326,7 +324,7 @@ export class LightboxView extends ObservableReactComponent { } } interface LightboxTourBtnProps { - navBtn: (left: Opt, bottom: Opt, top: number, icon: IconProp, display: any, click: () => void, color?: string) => JSX.Element; + navBtn: (left: Opt, bottom: Opt, top: number, icon: IconProp, display: boolean, click: () => void, color?: string) => JSX.Element; // eslint-disable-next-line react/no-unused-prop-types future: () => Opt; stepInto: () => void; @@ -335,7 +333,7 @@ interface LightboxTourBtnProps { @observer export class LightboxTourBtn extends React.Component { render() { - return this.props.navBtn('50%', 0, 0, 'chevron-down', this.props.lightboxDoc(), this.props.stepInto, ''); + return this.props.navBtn('50%', 0, 0, 'chevron-down', this.props.lightboxDoc() ? true : false, this.props.stepInto, ''); } } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 43b9a6b39..044162e4e 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -50,6 +50,7 @@ import { ScreenshotBox } from './nodes/ScreenshotBox'; import { ScriptingBox } from './nodes/ScriptingBox'; import { VideoBox } from './nodes/VideoBox'; import { WebBox } from './nodes/WebBox'; +import { CalendarBox } from './nodes/calendarBox/CalendarBox'; import { DashDocCommentView } from './nodes/formattedText/DashDocCommentView'; import { DashDocView } from './nodes/formattedText/DashDocView'; import { DashFieldView } from './nodes/formattedText/DashFieldView'; @@ -60,6 +61,8 @@ import { SummaryView } from './nodes/formattedText/SummaryView'; import { ImportElementBox } from './nodes/importBox/ImportElementBox'; import { PresBox, PresElementBox } from './nodes/trails'; import { SearchBox } from './search/SearchBox'; +import { Node } from 'prosemirror-model'; +import { EditorView } from 'prosemirror-view'; dotenv.config(); @@ -83,7 +86,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; setTimeout(() => { // prevent zooming browser document.getElementById('root')!.addEventListener('wheel', event => event.ctrlKey && event.preventDefault(), true); - const startload = (document as any).startLoad; + const startload = (document as unknown as { startLoad: number }).startLoad; // see index.html in deploy/ const loading = Date.now() - (startload ? Number(startload) : Date.now() - 3000); console.log('Loading Time = ' + loading); const d = new Date(); @@ -99,12 +102,12 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; // initialize plugins and classes that require plugins CollectionDockingView.Init(TabDocView); FormattedTextBox.Init((tbox: FormattedTextBox) => ({ - dashComment(node: any, view: any, getPos: any) { return new DashDocCommentView(node, view, getPos); }, // prettier-ignore - dashDoc(node: any, view: any, getPos: any) { return new DashDocView(node, view, getPos, tbox); }, // prettier-ignore - dashField(node: any, view: any, getPos: any) { return new DashFieldView(node, view, getPos, tbox); }, // prettier-ignore - equation(node: any, view: any, getPos: any) { return new EquationView(node, view, getPos, tbox); }, // prettier-ignore - summary(node: any, view: any, getPos: any) { return new SummaryView(node, view, getPos); }, // prettier-ignore - footnote(node: any, view: any, getPos: any) { return new FootnoteView(node, view, getPos); }, // prettier-ignore + dashComment(node: Node, view: EditorView, getPos: () => number | undefined) { return new DashDocCommentView(node, view, getPos); }, // prettier-ignore + dashDoc(node: Node, view: EditorView, getPos: () => number | undefined) { return new DashDocView(node, view, getPos, tbox); }, // prettier-ignore + dashField(node: Node, view: EditorView, getPos: () => number | undefined) { return new DashFieldView(node, view, getPos, tbox); }, // prettier-ignore + equation(node: Node, view: EditorView, getPos: () => number | undefined) { return new EquationView(node, view, getPos, tbox); }, // prettier-ignore + summary(node: Node, view: EditorView, getPos: () => number | undefined) { return new SummaryView(node, view, getPos); }, // prettier-ignore + footnote(node: Node, view: EditorView, getPos: () => number | undefined) { return new FootnoteView(node, view, getPos); }, // prettier-ignore })); CollectionFreeFormInfoUI.Init(); LinkFollower.Init(); @@ -141,6 +144,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; ChatBox, DiagramBox, HTMLtag, + CalendarBox, ComparisonBox, LoadingBox, PhysicsSimulationBox, diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index ef1bcfb64..ac30c5a14 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -1,4 +1,3 @@ -/* eslint-disable node/no-unpublished-import */ import { library } from '@fortawesome/fontawesome-svg-core'; import { faBuffer, faHireAHelper } from '@fortawesome/free-brands-svg-icons'; import * as far from '@fortawesome/free-regular-svg-icons'; @@ -7,7 +6,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, configure, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -// eslint-disable-next-line import/no-relative-packages +import ResizeObserver from 'resize-observer-polyfill'; import '../../../node_modules/browndash-components/dist/styles/global.min.css'; import { ClientUtils, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; @@ -58,7 +57,6 @@ import { ImageLabelHandler } from './collections/collectionFreeForm/ImageLabelHa import { MarqueeOptionsMenu } from './collections/collectionFreeForm/MarqueeOptionsMenu'; import { CollectionLinearView } from './collections/collectionLinear'; import { LinkMenu } from './linking/LinkMenu'; -import { AudioBox } from './nodes/AudioBox'; import { SchemaCSVPopUp } from './nodes/DataVizBox/SchemaCSVPopUp'; import { DocButtonState } from './nodes/DocumentLinksButton'; import { DocumentView, DocumentViewInternal } from './nodes/DocumentView'; @@ -77,11 +75,11 @@ import { AnchorMenu } from './pdf/AnchorMenu'; import { GPTPopup } from './pdf/GPTPopup/GPTPopup'; import { TopBar } from './topbar/TopBar'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore -const _global = (window /* browser */ || global) /* node */ as any; @observer -export class MainView extends ObservableReactComponent<{}> { +export class MainView extends ObservableReactComponent { // eslint-disable-next-line no-use-before-define public static Instance: MainView; public static Live: boolean = false; @@ -92,7 +90,7 @@ export class MainView extends ObservableReactComponent<{}> { @observable private _dashUIWidth: number = 0; // width of entire main dashboard region including left menu buttons and properties panel (but not including the dashboard selector button row) @observable private _dashUIHeight: number = 0; // height of entire main dashboard region including top menu buttons @observable private _panelContent: string = 'none'; - @observable private _sidebarContent: any = Doc.MyLeftSidebarPanel; + @observable private _sidebarContent: Doc = Doc.MyLeftSidebarPanel; @observable private _leftMenuFlyoutWidth: number = 0; @computed get _hideUI() { return this.mainDoc && this.mainDoc._type_collection !== CollectionViewType.Docking; @@ -152,7 +150,7 @@ export class MainView extends ObservableReactComponent<{}> { } }; headerBarDocWidth = () => this.mainDocViewWidth(); - headerBarDocHeight = () => (this._hideUI ? 0 : this.headerBarHeight ?? 0); + headerBarDocHeight = () => (this._hideUI ? 0 : (this.headerBarHeight ?? 0)); topMenuHeight = () => (this._hideUI ? 0 : 35); topMenuWidth = returnZero; // value is ignored ... leftMenuWidth = () => (this._hideUI ? 0 : Number(LEFT_MENU_WIDTH.replace('px', ''))); @@ -169,7 +167,7 @@ export class MainView extends ObservableReactComponent<{}> { reaction( // when a multi-selection occurs, remove focus from all active elements to allow keyboad input to go only to global key manager to act upon selection () => DocumentView.Selected().slice(), - views => views.length > 1 && (document.activeElement as any)?.blur !== undefined && (document.activeElement as any)!.blur() + views => views.length > 1 && document.activeElement instanceof HTMLElement && document.activeElement?.blur() ); reaction( () => Doc.MyDockedBtns.linearView_IsOpen, @@ -234,9 +232,9 @@ export class MainView extends ObservableReactComponent<{}> { tag.src = 'https://www.youtube.com/iframe_api'; const firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag); - document.addEventListener('dash', (e: any) => { + document.addEventListener('dash', (e: Event) => { // event used by chrome plugin to tell Dash which document to focus on - const id = GetDocFromUrl(e.detail); + const id = GetDocFromUrl((e as Event & { detail: string }).detail); DocServer.GetRefField(id).then(doc => (doc instanceof Doc ? DocumentView.showDocument(doc, { willPan: false }) : null)); }); document.addEventListener('linkAnnotationToDash', Hypothesis.linkListener); @@ -253,12 +251,12 @@ export class MainView extends ObservableReactComponent<{}> { // document.removeEventListener('linkAnnotationToDash', Hypothesis.linkListener); } - constructor(props: any) { + constructor(props: object) { super(props); makeObservable(this); DocumentViewInternal.addDocTabFunc = MainView.addDocTabFunc_impl; MainView.Instance = this; - DashboardView._urlState = HistoryUtil.parseUrl(window.location) || ({} as any); + DashboardView._urlState = HistoryUtil.parseUrl(window.location) ?? { type: 'doc', docId: '' }; // causes errors to be generated when modifying an observable outside of an action configure({ enforceActions: 'observed' }); @@ -293,7 +291,7 @@ export class MainView extends ObservableReactComponent<{}> { fa.faExternalLinkAlt, fa.faCalendar, fa.faSquare, - far.faSquare as any, + far.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, @@ -445,7 +443,7 @@ export class MainView extends ObservableReactComponent<{}> { fa.faHandPaper, fa.faMap, fa.faUser, - faHireAHelper as any, + faHireAHelper, fa.faTrashRestore, fa.faUsers, fa.faWrench, @@ -456,14 +454,14 @@ export class MainView extends ObservableReactComponent<{}> { fa.faArchive, fa.faBezierCurve, fa.faCircle, - far.faCircle as any, + far.faCircle, fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, fa.faAngleDoubleDown, fa.faAngleDoubleLeft, fa.faAngleDoubleUp, - faBuffer as any, + faBuffer, fa.faExpand, fa.faUndo, fa.faSlidersH, @@ -570,7 +568,6 @@ export class MainView extends ObservableReactComponent<{}> { ); DocumentManager.removeOverlayViews(); Doc.linkFollowUnhighlight(); - AudioBox.Enabled = true; const targets = document.elementsFromPoint(e.x, e.y); if (targets.length) { let targClass = targets[0].className.toString(); @@ -590,18 +587,6 @@ export class MainView extends ObservableReactComponent<{}> { document.addEventListener('pointerdown', this.globalPointerDown, true); document.addEventListener('pointermove', this.globalPointerMove, true); document.addEventListener('pointerup', this.globalPointerClick, true); - document.addEventListener( - 'click', - (e: MouseEvent) => { - if (!e.cancelBubble) { - const pathstr = (e as any)?.path?.map((p: any) => p.classList?.toString()).join(); - if (pathstr?.includes('libraryFlyout')) { - DocumentView.DeselectAll(); - } - } - }, - false - ); document.oncontextmenu = () => false; }; @@ -777,7 +762,7 @@ export class MainView extends ObservableReactComponent<{}> {
{ className="mainView-dashboardArea" ref={r => { r && - new _global.ResizeObserver( + new ResizeObserver( action(() => { this._dashUIWidth = r.getBoundingClientRect().width; this._dashUIHeight = r.getBoundingClientRect().height; @@ -976,11 +961,11 @@ export class MainView extends ObservableReactComponent<{}> { {[ ...SnappingManager.HorizSnapLines.map((l, i) => ( // eslint-disable-next-line react/no-array-index-key - + )), ...SnappingManager.VertSnapLines.map((l, i) => ( // eslint-disable-next-line react/no-array-index-key - + )), ]} @@ -1038,7 +1023,7 @@ export class MainView extends ObservableReactComponent<{}> { } ref={r => { r && - new _global.ResizeObserver( + new ResizeObserver( action(() => { this._windowWidth = r.getBoundingClientRect().width; this._windowHeight = r.getBoundingClientRect().height; diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index a7907a565..7bf10467e 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -3,6 +3,7 @@ import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; import * as React from 'react'; import ReactLoading from 'react-loading'; +import ResizeObserver from 'resize-observer-polyfill'; import { returnEmptyDoclist, returnEmptyFilter, returnTrue, setupMoveUpEvents } from '../../ClientUtils'; import { Utils, emptyFunction } from '../../Utils'; import { Doc } from '../../fields/Doc'; @@ -18,8 +19,6 @@ import './OverlayView.scss'; import { DefaultStyleProvider } from './StyleProvider'; import { DocumentView, DocumentViewInternal } from './nodes/DocumentView'; -const _global = (window /* browser */ || global) /* node */ as any; - export type OverlayDisposer = () => void; export type OverlayElementOptions = { @@ -109,19 +108,19 @@ export class OverlayWindow extends ObservableReactComponent } @observer -export class OverlayView extends ObservableReactComponent<{}> { +export class OverlayView extends ObservableReactComponent { // eslint-disable-next-line no-use-before-define public static Instance: OverlayView; @observable.shallow _elements: JSX.Element[] = []; - constructor(props: any) { + constructor(props: object) { super(props); makeObservable(this); if (!OverlayView.Instance) { OverlayView.Instance = this; - new _global.ResizeObserver( - action((entries: any) => { - Array.from(entries).forEach((entry: any) => { + new ResizeObserver( + action(entries => { + Array.from(entries).forEach(entry => { Doc.MyOverlayDocs.forEach(docIn => { const doc = docIn; if (NumCast(doc.overlayX) > entry.contentRect.width - 10) { @@ -162,17 +161,17 @@ export class OverlayView extends ObservableReactComponent<{}> { @action addWindow(contents: JSX.Element, options: OverlayElementOptions): OverlayDisposer { - const remove = action(() => { - const index = this._elements.indexOf(contents); + const remove = action((wincontents: JSX.Element) => { + const index = this._elements.indexOf(wincontents); if (index !== -1) this._elements.splice(index, 1); }); const wincontents = ( - + remove(wincontents)} key={Utils.GenerateGuid()} overlayOptions={options}> {contents} ); this._elements.push(wincontents); - return remove; + return () => remove(wincontents); } removeOverlayDoc = (docs: Doc | Doc[]) => toList(docs).every(Doc.RemFromMyOverlay); diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx index 1a2eb460f..2de867746 100644 --- a/src/client/views/ScriptingRepl.tsx +++ b/src/client/views/ScriptingRepl.tsx @@ -1,6 +1,4 @@ /* eslint-disable react/no-array-index-key */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; @@ -14,21 +12,26 @@ import { OverlayView } from './OverlayView'; import './ScriptingRepl.scss'; import { DocumentIconContainer } from './nodes/DocumentIcon'; import { DocumentView } from './nodes/DocumentView'; +import { returnFalse, setupMoveUpEvents } from '../../ClientUtils'; +import { emptyFunction } from '../../Utils'; +import { ObjectField } from '../../fields/ObjectField'; +import { RefField } from '../../fields/RefField'; +import { Doc, FieldResult, FieldType, Opt } from '../../fields/Doc'; interface replValueProps { scrollToBottom: () => void; - value: any; + value: Opt>; name?: string; } @observer export class ScriptingValueDisplay extends ObservableReactComponent { - constructor(props: any) { + constructor(props: replValueProps) { super(props); makeObservable(this); } render() { - const val = this._props.name ? this._props.value[this._props.name] : this._props.value; + const val = this._props.value instanceof Doc && this._props.name ? this._props.value[this._props.name] : this._props.value; const title = (name: string) => ( <> {this._props.name ? {this._props.name} : : <> } @@ -47,13 +50,14 @@ export class ScriptingValueDisplay extends ObservableReactComponent void; - value: { [key: string]: any }; + value: Opt>; name?: string; } +@observer export class ScriptingObjectDisplay extends ObservableReactComponent { @observable collapsed = true; - constructor(props: any) { + constructor(props: ReplProps) { super(props); makeObservable(this); } @@ -74,10 +78,12 @@ export class ScriptingObjectDisplay extends ObservableReactComponent {name} ); + if (val === undefined) return '--undefined--'; + if (val instanceof Promise) return '...Promise...'; if (this.collapsed) { return (
- + setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.toggle)} className="scriptingObject-icon scriptingObject-iconCollapsed"> {title} (+{Object.keys(val).length}) @@ -94,8 +100,7 @@ export class ScriptingObjectDisplay extends ObservableReactComponent
{Object.keys(val).map(key => ( - // eslint-disable-next-line react/jsx-props-no-spreading - + ))}
@@ -104,13 +109,13 @@ export class ScriptingObjectDisplay extends ObservableReactComponent } @observer -export class ScriptingRepl extends ObservableReactComponent<{}> { - constructor(props: any) { +export class ScriptingRepl extends ObservableReactComponent { + constructor(props: object) { super(props); makeObservable(this); } - @observable private commands: { command: string; result: any }[] = []; + @observable private commands: { command: string; result: unknown }[] = []; private commandsHistory: string[] = []; @observable private commandString: string = ''; @@ -120,13 +125,11 @@ export class ScriptingRepl extends ObservableReactComponent<{}> { private commandsRef = React.createRef(); - private args: any = {}; - getTransformer = (): Transformer => ({ transformer: context => { const knownVars: { [name: string]: number } = {}; const usedDocuments: number[] = []; - ScriptingGlobals.getGlobals().forEach((global: any) => { + ScriptingGlobals.getGlobals().forEach((global: string) => { knownVars[global] = 1; }); return root => { @@ -168,7 +171,7 @@ export class ScriptingRepl extends ObservableReactComponent<{}> { switch (e.key) { case 'Enter': { e.stopPropagation(); - const docGlobals: { [name: string]: any } = {}; + const docGlobals: { [name: string]: FieldType } = {}; DocumentView.allViews().forEach((dv, i) => { docGlobals[`d${i}`] = dv.Document; }); @@ -176,19 +179,20 @@ export class ScriptingRepl extends ObservableReactComponent<{}> { const script = CompileScript(this.commandString, { typecheck: false, addReturn: true, editable: true, params: { args: 'any' }, transformer: this.getTransformer(), globals }); if (!script.compiled) { this.commands.push({ command: this.commandString, result: script.errors }); + this.maybeScrollToBottom(); return; } - const result = undoable(() => script.run({ args: this.args }, () => this.commands.push({ command: this.commandString, result: e.toString() })), 'run:' + this.commandString)(); + const result = undoable(() => script.run({}, e => this.commands.push({ command: this.commandString, result: e as string })), 'run:' + this.commandString)(); if (result.success) { this.commands.push({ command: this.commandString, result: result.result }); this.commandsHistory.push(this.commandString); - this.maybeScrollToBottom(); - this.commandString = ''; this.commandBuffer = ''; this.historyIndex = -1; } + + this.maybeScrollToBottom(); break; } case 'ArrowUp': { @@ -232,7 +236,7 @@ export class ScriptingRepl extends ObservableReactComponent<{}> { private shouldScroll: boolean = false; private maybeScrollToBottom = () => { const ele = this.commandsRef.current; - if (ele && ele.scrollTop === ele.scrollHeight - ele.offsetHeight) { + if (ele && Math.abs(Math.ceil(ele.scrollTop) - (ele.scrollHeight - ele.offsetHeight)) < 2) { this.shouldScroll = true; this.forceUpdate(); } @@ -240,14 +244,14 @@ export class ScriptingRepl extends ObservableReactComponent<{}> { private scrollToBottom() { const ele = this.commandsRef.current; - ele && ele.scroll({ behavior: 'auto', top: ele.scrollHeight }); + ele?.scroll({ behavior: 'smooth', top: ele.scrollHeight }); } - componentDidUpdate(prevProps: Readonly<{}>) { + componentDidUpdate(prevProps: Readonly) { super.componentDidUpdate(prevProps); if (this.shouldScroll) { this.shouldScroll = false; - this.scrollToBottom(); + setTimeout(() => this.scrollToBottom(), 0); } } @@ -269,7 +273,7 @@ export class ScriptingRepl extends ObservableReactComponent<{}> { {command ||
}
- +
))} diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 8a07a6bd7..b111904f3 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -21,7 +21,7 @@ import { undoBatch, UndoManager } from '../util/UndoManager'; import { TreeSort } from './collections/TreeSort'; import { Colors } from './global/globalEnums'; import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; -import { FieldViewProps, StyleProviderFuncType } from './nodes/FieldView'; +import { FieldViewProps } from './nodes/FieldView'; import { StyleProp } from './StyleProp'; import './StyleProvider.scss'; @@ -46,7 +46,7 @@ export function styleFromLayoutString(doc: Doc, props: FieldViewProps, scale: nu // bcz: this executes a script to convert a property expression string: { script } into a value ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: doc, scale }).result?.toString() ?? ''; divKeys.forEach((prop: string) => { - const p = (props as any)[prop]; + const p = (props as FieldViewProps & { [key: string]: unknown })[prop]; typeof p === 'string' && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer)); }); return style; @@ -69,7 +69,7 @@ export function SetFilterOpener(func: () => void) { // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // -export function DefaultStyleProvider(doc: Opt, props: Opt, property: string) : StyleProviderFuncType { +export function DefaultStyleProvider(doc: Opt, props: Opt, property: string) { const remoteDocHeader = 'author;author_date;noMargin'; const isCaption = property.includes(':caption'); const isAnchor = property.includes(':anchor'); diff --git a/src/client/views/ViewBoxInterface.ts b/src/client/views/ViewBoxInterface.ts index c633f34fb..dce64ab92 100644 --- a/src/client/views/ViewBoxInterface.ts +++ b/src/client/views/ViewBoxInterface.ts @@ -18,6 +18,9 @@ export abstract class ViewBoxInterface

extends ObservableReactComponent void; // moves contents of collection to parent updateIcon?: () => void; // updates the icon representation of the document getAnchor?: (addAsAnnotation: boolean, pinData?: PinProps) => Doc; // returns an Anchor Doc that represents the current state of the doc's componentview (e.g., the current playhead location of a an audio/video box) diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx index a08a7c7c1..9eb16917b 100644 --- a/src/client/views/collections/CollectionCalendarView.tsx +++ b/src/client/views/collections/CollectionCalendarView.tsx @@ -6,11 +6,11 @@ import { dateRangeStrToDates, returnTrue } from '../../../ClientUtils'; import { Doc, DocListCast } from '../../../fields/Doc'; import { StrCast } from '../../../fields/Types'; import { CollectionStackingView } from './CollectionStackingView'; -import { CollectionSubView } from './CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; @observer export class CollectionCalendarView extends CollectionSubView() { - constructor(props: any) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); } diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index de46180e6..28a769896 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -18,7 +18,7 @@ import { StyleProp } from '../StyleProp'; import { DocumentView } from '../nodes/DocumentView'; import { GPTPopup, GPTPopupMode } from '../pdf/GPTPopup/GPTPopup'; import './CollectionCardDeckView.scss'; -import { CollectionSubView } from './CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; enum cardSortings { Time = 'time', @@ -68,7 +68,7 @@ export class CollectionCardView extends CollectionSubView() { } }; - constructor(props: any) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); } @@ -86,11 +86,11 @@ export class CollectionCardView extends CollectionSubView() { } @computed get cardSort_customField() { - return StrCast(this.Document.cardSort_customField) as any as 'chat' | 'star' | 'idea' | 'like'; + return StrCast(this.Document.cardSort_customField) as 'chat' | 'star' | 'idea' | 'like'; } @computed get cardSort() { - return StrCast(this.Document.cardSort) as any as cardSortings; + return StrCast(this.Document.cardSort) as cardSortings; } /** * how much to scale down the contents of the view so that everything will fit @@ -428,7 +428,6 @@ export class CollectionCardView extends CollectionSubView() { return (

{numberRange(amButtons).map(i => ( - // eslint-disable-next-line jsx-a11y/control-has-associated-label
); @@ -451,7 +453,7 @@ export class TableBox extends ObservableReactComponent { if (this._props.titleCol === col) colSelected = true; return ( -
{this._props.records[rowId][col]}
+
{this._props.records[rowId][col] as string | number}
); })} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 192c7875e..8a2c4e530 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -43,26 +43,37 @@ interface HTMLtagProps { @observer export class HTMLtag extends React.Component { click = () => { - const clickScript = (this.props as any).onClick as Opt; + const clickScript = this.props.onClick as Opt; clickScript?.script.run({ this: this.props.Document, scale: this.props.scaling }); }; - onInput = (e: React.FormEvent) => { - const onInputScript = (this.props as any).onInput as Opt; - onInputScript?.script.run({ this: this.props.Document, value: (e.target as any).textContent }); + onInput = (e: React.FormEvent) => { + const onInputScript = this.props.onInput as Opt; + onInputScript?.script.run({ this: this.props.Document, value: (e.target as HTMLElement).textContent }); }; render() { - const style: { [key: string]: any } = {}; - const divKeys = OmitKeys(this.props, ['children', 'dragStarting', 'dragEnding', 'htmltag', 'scaling', 'Document', 'key', 'onInput', 'onClick', '__proto__']).omit; - const replacer = (match: any, expr: string) => + const style: { [key: string]: unknown } = {}; + const divKeys = OmitKeys(this.props, [ + 'children', // + 'dragStarting', + 'dragEnding', + 'htmltag', + 'scaling', + 'Document', + 'key', + 'onInput', + 'onClick', + '__proto__', + ]).omit; + const replacer = (match: string, expr: string) => // bcz: this executes a script to convert a property expression string: { script } into a value (ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: this.props.Document, scale: this.props.scaling }).result as string) || ''; Object.keys(divKeys).forEach((prop: string) => { - const p = (this.props as any)[prop] as string; + const p = (this.props as unknown as { [key: string]: string })[prop] as string; style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer); }); const Tag = this.props.htmltag as keyof JSX.IntrinsicElements; return ( - + {this.props.children} ); @@ -78,12 +89,12 @@ export class DocumentContentsView extends ObservableReactComponent{content}< as in {this.title} - const replacer = (match: any, prefix: string, expr: string, postfix: string) => prefix + ((ScriptField.MakeFunction(expr, { this: Doc.name })?.script.run({ this: this._props.Document }).result as string) || '') + postfix; + const replacer = (match: string, prefix: string, expr: string, postfix: string) => prefix + ((ScriptField.MakeFunction(expr, { this: Doc.name })?.script.run({ this: this._props.Document }).result as string) || '') + postfix; layoutFrame = layoutFrame.replace(/(>[^{]*)[^=]\{([^.'][^<}]+)\}([^}]*<)/g, replacer); // replace HTML with corresponding HTML tag as in: becomes - const replacer2 = (match: any, p1: string) => ` ` with as in: becomes @@ -194,6 +205,7 @@ export class DocumentContentsView extends ObservableReactComponent { console.log('DocumentContentsView:' + test, bindings, layoutFrame); }} diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 0c5156339..c35a329c9 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { action, computed, makeObservable, observable, runInAction } from 'mobx'; @@ -55,7 +53,7 @@ export class DocumentLinksButton extends ObservableReactComponent> = undefined; // needs to be accessed from DocumentView wrapper class @observable _animateScaleTime: Opt = undefined; // milliseconds for animating between views. defaults to 300 if not uset @observable _animateScalingTo = 0; @@ -216,7 +217,7 @@ export class DocumentViewInternal extends DocComponent this.style(this.Document, StyleProp.PointerEvents) as 'all' | 'none' | 'visiblePainted' | undefined, + () => this.style(this.Document, StyleProp.PointerEvents) as Property.PointerEvents | undefined, pointerevents => { this._pointerEvents = pointerevents; }, @@ -243,7 +244,7 @@ export class DocumentViewInternal extends DocComponent disposer?.()); } - startDragging(x: number, y: number, dropAction: dropActionType, hideSource = false) { + startDragging(x: number, y: number, dropAction: dropActionType | undefined, hideSource = false) { const docView = this._docView; if (this._mainCont.current && docView) { const views = DocumentView.Selected().filter(dv => dv.ContentDiv); @@ -310,7 +311,8 @@ export class DocumentViewInternal extends DocComponent { if (this.onDoubleClickHdlr?.script) { - this.onDoubleClickHdlr.script.run(scriptProps, console.log).result?.select && this._props.select(false); + const res = this.onDoubleClickHdlr.script.run(scriptProps, console.log).result as { select: boolean }; + res.select && this._props.select(false); } else if (!Doc.IsSystem(this.Document) && defaultDblclick !== 'ignore') { this._props.addDocTab(this.Document, OpenWhere.lightboxAlways); DocumentView.DeselectAll(); @@ -558,7 +560,7 @@ export class DocumentViewInternal extends DocComponent DocumentView.SetLightboxDoc(this.Document), icon: 'external-link-alt' }); @@ -574,7 +576,7 @@ export class DocumentViewInternal extends DocComponent { this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'hover'; }, icon: 'hand-point-up' }); // prettier-ignore revealItems.push({ description: 'Flip', event: () => { this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'flip'; }, icon: 'rotate' }); // prettier-ignore !revealOptions && cm.addItem({ description: 'Reveal Options', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' }); @@ -582,15 +584,16 @@ export class DocumentViewInternal extends DocComponent DocumentView.Selected().forEach(dv => dv._props.bringToFront?.(dv.Document, false)), icon: 'arrow-up' }); zorderItems.push({ description: 'Send to Back', event: () => DocumentView.Selected().forEach(dv => dv._props.bringToFront?.(dv.Document, true)), icon: 'arrow-down' }); zorderItems.push({ description: !this.layoutDoc._keepZDragged ? 'Keep ZIndex when dragged' : 'Allow ZIndex to change when dragged', - event: undoBatch( + event: undoable( action(() => { this.layoutDoc._keepZWhenDragged = !this.layoutDoc._keepZWhenDragged; - }) + }), + 'set zIndex drag' ), icon: 'hand-point-up', }); @@ -599,7 +602,7 @@ export class DocumentViewInternal extends DocComponent DocUtils.makeIntoPortal(this.Document, this.layoutDoc, this._allLinks), 'make into portal'), icon: 'window-restore' }); !Doc.noviceMode && onClicks.push({ description: 'Toggle Detail', event: this.setToggleDetail, icon: 'concierge-bell' }); @@ -624,7 +627,7 @@ export class DocumentViewInternal extends DocComponent Doc.MakeMetadataFieldTemplate(this.Document, this._props.TemplateDataDocument), icon: 'concierge-bell' }); @@ -648,7 +651,7 @@ export class DocumentViewInternal extends DocComponent this._props.addDocTab(Docs.Create.PdfDocument('/assets/cheat-sheet.pdf', { _width: 300, _height: 300 }), OpenWhere.addRight), icon: 'keyboard' }); !Doc.noviceMode && helpItems.push({ description: 'Print Document in Console', event: () => console.log(this.Document), icon: 'hand-point-right' }); !Doc.noviceMode && helpItems.push({ description: 'Print DataDoc in Console', event: () => console.log(this.dataDoc), icon: 'hand-point-right' }); @@ -844,7 +847,7 @@ export class DocumentViewInternal extends DocComponent Field.toKeyValueString(this.Document, field)) .join('\\') } - SetValue={undoBatch((input: string) => { + SetValue={undoable((input: string) => { if (input?.startsWith('$')) { if (this.layoutDoc.layout_showTitle) { this.layoutDoc._layout_showTitle = input?.substring(1) ? input.substring(1) : undefined; @@ -855,7 +858,7 @@ export class DocumentViewInternal extends DocComponent @@ -1245,7 +1248,7 @@ export class DocumentView extends DocComponent() { public setToggleDetail = (scriptFieldKey = 'onClick') => this._docViewInternal?.setToggleDetail(scriptFieldKey); public onContextMenu = (e?: React.MouseEvent, pageX?: number, pageY?: number) => this._docViewInternal?.onContextMenu?.(e, pageX, pageY); public cleanupPointerEvents = () => this._docViewInternal?.cleanupPointerEvents(); - public startDragging = (x: number, y: number, dropAction: dropActionType, hideSource = false) => this._docViewInternal?.startDragging(x, y, dropAction, hideSource); + public startDragging = (x: number, y: number, dropAction: dropActionType | undefined, hideSource = false) => this._docViewInternal?.startDragging(x, y, dropAction, hideSource); public showContextMenu = (pageX: number, pageY: number) => this._docViewInternal?.onContextMenu(undefined, pageX, pageY); public toggleNativeDimensions = () => this._docViewInternal && this.Document.type !== DocumentType.INK && Doc.toggleNativeDimensions(this.layoutDoc, this.NativeDimScaling() ?? 1, this._props.PanelWidth(), this._props.PanelHeight()); @@ -1288,7 +1291,7 @@ export class DocumentView extends DocComponent() { this.dataDoc.audioAnnoState = AudioAnnoState.playing; break; case AudioAnnoState.playing: - this.dataDoc[AudioPlay]?.stop(); + (this.dataDoc[AudioPlay] as Howl)?.stop(); this.dataDoc.audioAnnoState = AudioAnnoState.stopped; break; default: diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index 1f5c9b84b..fefe25764 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -1,4 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ import { action, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -50,8 +49,8 @@ export class EquationBox extends ViewBoxBaseComponent() { () => this._props.isSelected(), selected => { if (this._ref.current) { - if (selected) this._ref.current.element.current.children[0].addEventListener('keydown', this.keyPressed, true); - else this._ref.current.element.current.children[0].removeEventListener('keydown', this.keyPressed); + if (selected) (this._ref.current.element.current?.children[0] as HTMLElement).addEventListener('keydown', this.keyPressed, true); + else (this._ref.current.element.current?.children[0] as HTMLElement).removeEventListener('keydown', this.keyPressed); } }, { fireImmediately: true } @@ -60,8 +59,8 @@ export class EquationBox extends ViewBoxBaseComponent() { @action keyPressed = (e: KeyboardEvent) => { - const _height = DivHeight(this._ref.current!.element.current); - const _width = DivWidth(this._ref.current!.element.current); + const _height = DivHeight(this._ref.current!.element?.current); + const _width = DivWidth(this._ref.current!.element?.current); if (e.key === 'Enter') { const nextEq = Docs.Create.EquationDocument(e.shiftKey ? StrCast(this.dataDoc.text) : 'x', { title: '# math', @@ -95,7 +94,7 @@ export class EquationBox extends ViewBoxBaseComponent() { }; updateSize = () => { - const style = this._ref.current && getComputedStyle(this._ref.current.element.current); + const style = this._ref.current?.element.current && getComputedStyle(this._ref.current.element.current); if (style?.width.endsWith('px') && style?.height.endsWith('px')) { if (this.layoutDoc._nativeWidth) { // if equation has been scaled then editing the expression must also edit the native dimensions to keep the aspect ratio diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index fc59e9e26..dd71fd946 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -1,5 +1,6 @@ /* eslint-disable react/no-unused-prop-types */ /* eslint-disable react/require-default-props */ +import { Property } from 'csstype'; import { computed } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -95,7 +96,7 @@ export interface FieldViewSharedProps { bringToFront?: (doc: Doc, sendToBack?: boolean) => void; waitForDoubleClickToClick?: () => 'never' | 'always' | undefined; defaultDoubleClick?: () => 'default' | 'ignore' | undefined; - pointerEvents?: () => Opt<'none' | 'all' | 'visiblePainted'>; + pointerEvents?: () => Opt; suppressSetHeight?: boolean; } diff --git a/src/client/views/nodes/FontIconBox/ButtonInterface.ts b/src/client/views/nodes/FontIconBox/ButtonInterface.ts deleted file mode 100644 index 0d0d7b1c3..000000000 --- a/src/client/views/nodes/FontIconBox/ButtonInterface.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { IconProp } from '@fortawesome/fontawesome-svg-core'; -import { Doc } from '../../../../fields/Doc'; -import { ButtonType } from './FontIconBox'; - -export interface IButtonProps { - type: string | ButtonType; - Document: Doc; - label: any; - icon: IconProp; - color: string; - backgroundColor: string; -} diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index ffb668b03..f2f7f39bb 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -73,12 +73,12 @@ export class FontIconBox extends ViewBoxBaseComponent() { Icon = (color: string, iconFalse?: boolean) => { let icon; if (iconFalse) { - icon = StrCast(this.dataDoc[this.fieldKey ?? 'iconFalse'] ?? this.dataDoc.icon, 'user') as any; + icon = StrCast(this.dataDoc[this.fieldKey ?? 'iconFalse'] ?? this.dataDoc.icon, 'user') as IconProp; if (icon) return ; return null; } - icon = StrCast(this.dataDoc[this.fieldKey ?? 'icon'] ?? this.dataDoc.icon, 'user') as any; - return !icon ? null : icon === 'pres-trail' ? TrailsIcon(color) : ; + icon = StrCast(this.dataDoc[this.fieldKey ?? 'icon'] ?? this.dataDoc.icon, 'user') as IconProp; + return !icon ? null : icon === ('pres-trail' as IconProp) ? TrailsIcon(color) : ; }; @computed get dropdown() { return BoolCast(this.Document.dropDownOpen); @@ -117,7 +117,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { break; } // prettier-ignore const numScript = (value?: number) => ScriptCast(this.Document.script).script.run({ this: this.Document, value, _readOnly_: value === undefined }); - const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); + const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; // Script for checking the outcome of the toggle const checkResult = Number(Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3))); @@ -142,7 +142,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { setupMoveUpEvents( this, e, - () => ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, value: { doc: value, e } }).result, + () => ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, value: { doc: value, e } }).result as boolean, emptyFunction, emptyFunction ); // prettier-ignore @@ -157,11 +157,11 @@ export class FontIconBox extends ViewBoxBaseComponent() { let noviceList: string[] = []; let text: string | undefined; - let getStyle: (val: string) => any = () => {}; + let getStyle: (val: string) => { [key: string]: string } = () => ({}); let icon: IconProp = 'caret-down'; const isViewDropdown = script?.script.originalScript.startsWith('{ return setView'); if (isViewDropdown) { - const selected = Array.from(script?.script.run({ _readOnly_: true }).result) as Doc[]; + const selected = Array.from(script?.script.run({ _readOnly_: true }).result as Doc[]); // const selected = DocumentView.SelectedDocs(); if (selected.lastElement()) { if (StrCast(selected.lastElement().type) === DocumentType.COL) { @@ -190,7 +190,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { } noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Carousel3D, CollectionViewType.Stacking, CollectionViewType.NoteTaking]; } else { - text = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result; + text = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result as string; // text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily); getStyle = (val: string) => ({ fontFamily: val }); } @@ -231,8 +231,8 @@ export class FontIconBox extends ViewBoxBaseComponent() { * Color button */ @computed get colorButton() { - const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); - const curColor = this.colorScript?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result ?? 'transparent'; + const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; + const curColor = (this.colorScript?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result as string) ?? 'transparent'; const tooltip: string = StrCast(this.Document.toolTip); return ( @@ -251,7 +251,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { type={Type.PRIM} color={color} background={SnappingManager.userBackgroundColor} - icon={this.Icon(color)!} + icon={this.Icon(color) ?? undefined} tooltip={tooltip} label={this.label} /> @@ -262,9 +262,9 @@ export class FontIconBox extends ViewBoxBaseComponent() { const tooltip: string = StrCast(this.Document.toolTip); const script = ScriptCast(this.Document.onClick)?.script; - const toggleStatus = script?.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result; + const toggleStatus = script?.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result as boolean; // Colors - const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); + const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; const items = DocListCast(this.dataDoc.data); const multiDoc = this.Document; return ( @@ -272,13 +272,13 @@ export class FontIconBox extends ViewBoxBaseComponent() { tooltip={`Toggle ${tooltip}`} type={Type.PRIM} color={color} - onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => script.run({ this: multiDoc, value: undefined, _readOnly_: false }))} + onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => script.run({ this: multiDoc, value: undefined, _readOnly_: false }))} isToggle={script ? true : false} toggleStatus={toggleStatus} //background={SnappingManager.userBackgroundColor} label={this.label} items={DocListCast(this.dataDoc.data).map(item => ({ - icon: , + icon: , tooltip: StrCast(item.toolTip), val: StrCast(item.toolType), }))} @@ -300,9 +300,9 @@ export class FontIconBox extends ViewBoxBaseComponent() { const script = ScriptCast(this.Document.onClick); const double = ScriptCast(this.Document.onDoubleClick); - const toggleStatus = script?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result ?? false; + const toggleStatus = (script?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result as boolean) ?? false; // Colors - const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); + const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; // const backgroundColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor); return ( @@ -337,30 +337,30 @@ export class FontIconBox extends ViewBoxBaseComponent() { * Default */ @computed get defaultButton() { - const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); - const tooltip: string = StrCast(this.Document.toolTip); + const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; + const tooltip = StrCast(this.Document.toolTip); - return ; + return ; } @computed get editableText() { const script = ScriptCast(this.Document.script); const checkResult = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result; - const setValue = (value: string): boolean => script?.script.run({ this: this.Document, value, _readOnly_: false }).result; + const setValue = (value: string) => script?.script.run({ this: this.Document, value, _readOnly_: false }).result as boolean; return (
- script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result} SetValue={setValue} oneLine contents={checkResult} /> + script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result as string} SetValue={setValue} oneLine contents={checkResult} />
); } renderButton = () => { - const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); + const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; const tooltip = StrCast(this.Document.toolTip); const scriptFunc = () => ScriptCast(this.Document.onClick)?.script.run({ this: this.Document, _readOnly_: false }); const btnProps = { tooltip, icon: this.Icon(color)!, label: this.label }; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index ce7552047..51dd494da 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -35,6 +35,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { FocusViewOptions } from './FocusViewOptions'; import './ImageBox.scss'; import { OpenWhere } from './OpenWhere'; +import { SnappingManager } from '../../util/SnappingManager'; export class ImageEditorData { // eslint-disable-next-line no-use-before-define @@ -73,7 +74,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { private _marqueeref = React.createRef(); private _mainCont: React.RefObject = React.createRef(); private _annotationLayer: React.RefObject = React.createRef(); - @observable _savedAnnotations = new ObservableMap(); + @observable _savedAnnotations = new ObservableMap(); @observable _curSuffix = ''; @observable _error = ''; @observable _isHovering = false; // flag to switch between primary and alternate images on hover @@ -328,7 +329,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { }) } style={{ - display: (this._props.isContentActive() !== false && DragManager.DocDragData?.canEmbed) || this.dataDoc[this.fieldKey + '_alternates'] ? 'block' : 'none', + display: (this._props.isContentActive() !== false && SnappingManager.CanEmbed) || this.dataDoc[this.fieldKey + '_alternates'] ? 'block' : 'none', width: 'min(10%, 25px)', height: 'min(10%, 25px)', background: usePath === undefined ? 'white' : usePath === 'alternate' ? 'black' : 'gray', @@ -346,7 +347,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { const defaultUrl = new URL(ClientUtils.prepend('/assets/unknown-file-icon-hi.png')); const altpaths = alts - ?.map(doc => (doc instanceof Doc ? ImageCast(doc[Doc.LayoutFieldKey(doc)])?.url ?? defaultUrl : defaultUrl)) + ?.map(doc => (doc instanceof Doc ? (ImageCast(doc[Doc.LayoutFieldKey(doc)])?.url ?? defaultUrl) : defaultUrl)) .filter(url => url) .map(url => this.choosePath(url)) ?? []; // acc ess the primary layout data of the alternate documents const paths = field ? [this.choosePath(field.url), ...altpaths] : altpaths; @@ -356,7 +357,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { @computed get content() { TraceMobx(); - const backColor = DashColor(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string ?? Colors.WHITE); + const backColor = DashColor((this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string) ?? Colors.WHITE); const backAlpha = backColor.red() === 0 && backColor.green() === 0 && backColor.blue() === 0 ? backColor.alpha() : 1; const srcpath = this.layoutDoc.hideImage ? '' : this.paths[0]; const fadepath = this.layoutDoc.hideImage ? '' : this.paths.lastElement(); diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 66e210c03..9e77e0973 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -1,4 +1,3 @@ -/* eslint-disable jsx-a11y/control-has-associated-label */ import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -35,7 +34,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { public static LayoutString() { return FieldView.LayoutString(KeyValueBox, 'data'); } - constructor(props: any) { + constructor(props: FieldViewProps) { super(props); makeObservable(this); } @@ -88,7 +87,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { const type: 'computed' | 'script' | false = rawvalue.startsWith(':=') ? 'computed' : rawvalue.startsWith('$=') ? 'script' : false; rawvalue = type ? rawvalue.substring(2) : rawvalue; rawvalue = rawvalue.replace(/.*\(\((.*)\)\)/, 'dashCallChat(_setCacheResult_, this, `$1`)'); - const value = ["'", '"', '`'].includes(rawvalue.length ? rawvalue[0] : '') || !isNaN(rawvalue as any) ? rawvalue : '`' + rawvalue + '`'; + const value = ["'", '"', '`'].includes(rawvalue.length ? rawvalue[0] : '') || !isNaN(+rawvalue) ? rawvalue : '`' + rawvalue + '`'; let script = ScriptField.CompileScript(rawvalue, {}, true, undefined, DocumentIconContainer.getTransformer()); if (!script.compiled) { @@ -116,7 +115,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { if (key) target[key] = script.originalScript; return false; } - field === undefined && (field = res.result instanceof Array ? new List(res.result) : res.result); + field === undefined && (field = res.result instanceof Array ? new List(res.result) : (res.result as FieldType)); } } if (!key) return false; @@ -165,7 +164,6 @@ export class KeyValueBox extends ViewBoxBaseComponent() { const rows: JSX.Element[] = []; let i = 0; - const self = this; const keys = Object.keys(ids).slice(); // for (const key of [...keys.filter(id => id !== 'layout' && !id.includes('_')).sort(), ...keys.filter(id => id === 'layout' || id.includes('_')).sort()]) { const sortedKeys = keys.sort((a: string, b: string) => { @@ -184,12 +182,12 @@ export class KeyValueBox extends ViewBoxBaseComponent() { addDocTab={this._props.addDocTab} PanelWidth={this._props.PanelWidth} PanelHeight={this.rowHeight} - ref={(function () { + ref={(() => { let oldEl: KeyValuePair | undefined; return (el: KeyValuePair) => { - if (oldEl) self.rows.splice(self.rows.indexOf(oldEl), 1); + if (oldEl) this.rows.splice(this.rows.indexOf(oldEl), 1); oldEl = el; - if (el) self.rows.push(el); + if (el) this.rows.push(el); }; })()} keyWidth={100 - this._splitPercentage} diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 0956be3e9..3023716b1 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -1,4 +1,3 @@ -/* eslint-disable jsx-a11y/control-has-associated-label */ import { Tooltip } from '@mui/material'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; @@ -9,7 +8,7 @@ import { Doc, Field } from '../../../fields/Doc'; import { DocCast } from '../../../fields/Types'; import { DocumentOptions, FInfo } from '../../documents/Documents'; import { Transform } from '../../util/Transform'; -import { undoBatch } from '../../util/UndoManager'; +import { undoable } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { EditableView } from '../EditableView'; import { ObservableReactComponent } from '../ObservableReactComponent'; @@ -34,7 +33,7 @@ export class KeyValuePair extends ObservableReactComponent { @observable private isPointerOver = false; @observable public isChecked = false; private checkbox = React.createRef(); - constructor(props: any) { + constructor(props: KeyValuePairProps) { super(props); makeObservable(this); } @@ -91,11 +90,11 @@ export class KeyValuePair extends ObservableReactComponent { type="button" style={hover} className="keyValuePair-td-key-delete" - onClick={undoBatch(() => { + onClick={undoable(() => { if (Object.keys(this._props.doc).indexOf(this._props.keyName) !== -1) { delete this._props.doc[this._props.keyName]; } else delete DocCast(this._props.doc.proto)?.[this._props.keyName]; - })}> + }, 'set key value')}> X diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 8d6ae9f73..4d9d2460e 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -27,6 +27,7 @@ export class LinkBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string = 'link') { return FieldView.LayoutString(LinkBox, fieldKey); } + _hackToSeeIfDeleted: NodeJS.Timeout | undefined; _disposers: { [name: string]: IReactionDisposer } = {}; @observable _forceAnimate: number = 0; // forces xArrow to animate when a transition animation is detected on something that affects an anchor @observable _hide = false; // don't render if anchor is not visible since that breaks xAnchor @@ -43,7 +44,6 @@ export class LinkBox extends ViewBoxBaseComponent() { const anchor = anch?.layout_unrendered ? DocCast(anch.annotationOn) : anch; return DocumentView.getDocumentView(anchor, this.DocumentView?.().containerViewPath?.().lastElement()); }; - _hackToSeeIfDeleted: any; componentWillUnmount() { this._hackToSeeIfDeleted && clearTimeout(this._hackToSeeIfDeleted); Object.keys(this._disposers).forEach(key => this._disposers[key]()); @@ -68,7 +68,7 @@ export class LinkBox extends ViewBoxBaseComponent() { let a1 = a && document.getElementById(a.ViewGuid); let a2 = b && document.getElementById(b.ViewGuid); // test whether the anchors themselves are hidden,... - if (!a1 || !a2 || (a?.ContentDiv as any)?.hidden || (b?.ContentDiv as any)?.hidden) this._hide = true; + if (!a1 || !a2 || a?.ContentDiv?.hidden || b?.ContentDiv?.hidden) this._hide = true; else { // .. or whether any of their DOM parents are hidden for (; a1 && !a1.hidden; a1 = a1.parentElement); @@ -151,11 +151,11 @@ export class LinkBox extends ViewBoxBaseComponent() { this._forceAnimate += 0.01; }) ); // this forces an update during a transition animation - const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting); + const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting) as { highlightStyle: string; highlightColor: string; highlightIndex: number; highlightStroke: boolean }; const highlightColor = highlight?.highlightIndex ? highlight?.highlightColor : undefined; - const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); - const fontFamily = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily); - const fontSize = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize); + const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; + const fontFamily = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily) as string; + const fontSize = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize) as number; const fontColor = (c => (c !== 'transparent' ? c : undefined))(StrCast(this.layoutDoc.link_fontColor)); // eslint-disable-next-line camelcase const { stroke_markerScale: strokeMarkerScale, stroke_width: strokeRawWidth, stroke_startMarker: strokeStartMarker, stroke_endMarker: strokeEndMarker, stroke_dash: strokeDash } = this.Document; @@ -248,7 +248,7 @@ export class LinkBox extends ViewBoxBaseComponent() { 2 ); return ( -
+
= undefined; @observable _toolTipText = ''; @observable _hrefInd = 0; - constructor(props: any) { + constructor(props: LinkDocPreviewProps) { super(props); makeObservable(this); } @@ -104,7 +104,7 @@ export class LinkDocPreview extends ObservableReactComponent { - !this._linkDocRef.current?.contains(e.target as any) && LinkInfo.Clear(); // close preview when not clicking anywhere other than the info bar of the preview + !this._linkDocRef.current?.contains(e.target as HTMLElement) && LinkInfo.Clear(); // close preview when not clicking anywhere other than the info bar of the preview }; @action @@ -144,7 +144,7 @@ export class LinkDocPreview extends ObservableReactComponent() { return FieldView.LayoutString(LoadingBox, fieldKey); } - _timer: any; + _timer: NodeJS.Timeout | undefined; @observable progress = ''; componentDidMount() { if (!Doc.CurrentlyLoading?.includes(this.Document)) { diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index d7687e03e..c66f7c726 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { IconLookup, faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, FormControlLabel, TextField } from '@mui/material'; @@ -481,8 +479,8 @@ export class MapBox extends ViewBoxAnnotatableComponent() { console.log('deleting'); if (this._selectedPinOrRoute) { // Removes filter - Doc.setDocFilter(this.Document, 'latitude', this._selectedPinOrRoute.latitude, 'remove'); - Doc.setDocFilter(this.Document, 'longitude', this._selectedPinOrRoute.longitude, 'remove'); + Doc.setDocFilter(this.Document, 'latitude', NumCast(this._selectedPinOrRoute.latitude), 'remove'); + Doc.setDocFilter(this.Document, 'longitude', NumCast(this._selectedPinOrRoute.longitude), 'remove'); Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(DocCast(this._selectedPinOrRoute))}`, 'remove'); this.removePushpinOrRoute(this._selectedPinOrRoute); @@ -1152,7 +1150,7 @@ export class MapBox extends ViewBoxAnnotatableComponent() { _textRef = React.createRef(); render() { const scale = this._props.NativeDimScaling?.() || 1; - const parscale = scale === 1 ? 1 : this.ScreenToLocalBoxXf().Scale ?? 1; + const parscale = scale === 1 ? 1 : (this.ScreenToLocalBoxXf().Scale ?? 1); return (
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 8db68ddfe..c03694dd9 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/control-has-associated-label */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -76,7 +74,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { }); else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then( - action((pdf: any) => { + action(pdf => { this._pdf = pdf; }) ); @@ -108,7 +106,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { }; crop = (region: Doc | undefined, addCrop?: boolean) => { - if (!region) return undefined; + const docViewContent = this.DocumentView?.().ContentDiv; + if (!region || !docViewContent) return undefined; const cropping = Doc.MakeCopy(region, true); cropping.layout_unrendered = false; // text selection have this cropping.text_inlineAnnotations = undefined; // text selections have this -- it causes them not to be rendered. @@ -120,7 +119,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { regionData.followLinkToggle = true; this.addDocument(region); - const docViewContent = this.DocumentView?.().ContentDiv!; const newDiv = docViewContent.cloneNode(true) as HTMLDivElement; newDiv.style.width = NumCast(this.layoutDoc._width).toString(); newDiv.style.height = NumCast(this.layoutDoc._height).toString(); @@ -162,7 +160,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { (NumCast(region.x) * this._props.PanelWidth()) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']), 4 ) - .then((dataUrl: any) => { + .then(dataUrl => { ClientUtils.convertDataUri(dataUrl, region[Id]).then(returnedfilename => setTimeout( action(() => { @@ -172,7 +170,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { ) ); }) - .catch((error: any) => { + .catch(error => { console.error('oops, something went wrong!', error); }); @@ -181,9 +179,10 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { updateIcon = () => { // currently we render pdf icons as text labels - const docViewContent = this.DocumentView?.().ContentDiv!; + const docViewContent = this.DocumentView?.().ContentDiv; const filename = this.layoutDoc[Id] + '-icon' + new Date().getTime(); this._pdfViewer?._mainCont.current && + docViewContent && UpdateIcon( filename, docViewContent, @@ -475,6 +474,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { const cm = ContextMenu.Instance; const options = cm.findByDescription('Options...'); const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : []; + !Doc.noviceMode && optionItems.push({ description: 'Toggle Sidebar Type', event: this.toggleSidebarType, icon: 'expand-arrows-alt' }); !Doc.noviceMode && optionItems.push({ description: 'update icon', event: () => this.pdfUrl && this.updateIcon(), icon: 'expand-arrows-alt' }); // optionItems.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" }); @@ -656,7 +656,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { else { if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise); PDFBox.pdfpromise.get(href)?.then( - action((pdf: any) => { + action(pdf => { PDFBox.pdfcache.set(href, (this._pdf = pdf)); }) ); diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx index f88eb3bca..31a1a398b 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx @@ -1,8 +1,5 @@ /* eslint-disable camelcase */ -/* eslint-disable jsx-a11y/control-has-associated-label */ /* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable react/no-array-index-key */ /* eslint-disable react/jsx-props-no-spreading */ /* eslint-disable no-return-assign */ @@ -1009,7 +1006,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent (this.dataDoc.hintDialogueOpen = false)}> Hints - {this.selectedQuestion.hints?.map((hint: any, index: number) => ( + {this.selectedQuestion.hints?.map((hint: { description: string; content: string }, index: number) => (
@@ -1985,7 +1982,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent() { this.dataDoc[this._props.fieldKey] = new VideoField(this.result.accessPaths.client); // stringify the presentation and store it if (presentation?.movements) { - const presCopy = { ...presentation }; - presCopy.movements = presentation.movements.map(movement => ({ ...movement, doc: movement.doc[Id] })) as any; + const presCopy = { ...presentation, movements: presentation.movements.map(movement => ({ ...movement, doc: (movement.doc as Doc)[Id] })) }; this.dataDoc[this.fieldKey + '_presentation'] = JSON.stringify(presCopy); } }; @@ -210,7 +209,7 @@ ScriptingGlobals.add(function getCurrentRecording() { }); // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function getWorkspaceRecordings() { - return new List(['Record Workspace', `Record Webcam`, ...DocListCast(Doc.UserDoc().workspaceRecordings)]); + return new List(['Record Workspace', `Record Webcam`, ...DocListCast(Doc.UserDoc().workspaceRecordings)]); }); // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function isWorkspaceRecording() { diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 9ef1071f7..6289470b6 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -20,7 +20,7 @@ import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; import { CaptureManager } from '../../util/CaptureManager'; import { SettingsManager } from '../../util/SettingsManager'; -import { TrackMovements } from '../../util/TrackMovements'; +import { Movement, TrackMovements } from '../../util/TrackMovements'; import { ContextMenu } from '../ContextMenu'; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { DocViewUtils } from '../DocViewUtils'; @@ -31,10 +31,11 @@ import { FieldView, FieldViewProps } from './FieldView'; import './ScreenshotBox.scss'; import { VideoBox } from './VideoBox'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; -declare class MediaRecorder { - constructor(e: any, options?: any); // whatever MediaRecorder has -} +// declare class MediaRecorder { +// constructor(e: any, options?: any); // whatever MediaRecorder has +// } // interface VideoTileProps { // raised: { coord: Vector2, off: Vector3 }[]; @@ -117,8 +118,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent() public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ScreenshotBox, fieldKey); } - private _audioRec: any; - private _videoRec: any; + private _audioRec: MediaRecorder | undefined; + private _videoRec: MediaRecorder | undefined; @observable private _videoRef: HTMLVideoElement | null = null; @observable _screenCapture = false; @computed get recordingStart() { @@ -136,7 +137,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent() }; videoLoad = () => { - const aspect = this._videoRef!.videoWidth / this._videoRef!.videoHeight; + const aspect = (this._videoRef?.videoWidth || 0) / (this._videoRef?.videoHeight || 1); const nativeWidth = Doc.NativeWidth(this.layoutDoc); const nativeHeight = Doc.NativeHeight(this.layoutDoc); if (!nativeWidth || !nativeHeight) { @@ -166,7 +167,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent() } specificContextMenu = (): void => { - const subitems = [{ description: 'Screen Capture', event: this.toggleRecording, icon: 'expand-arrows-alt' as any }]; + const subitems = [{ description: 'Screen Capture', event: this.toggleRecording, icon: 'expand-arrows-alt' as IconProp }]; ContextMenu.Instance.addItem({ description: 'Options...', subitems, icon: 'video' }); }; @@ -221,29 +222,29 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent() Pause = () => this._screenCapture && this.toggleRecording(); toggleRecording = async () => { - if (!this._screenCapture) { + if (!this._screenCapture && this._videoRef) { this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true })); - const audChunks: any = []; - this._audioRec.ondataavailable = (e: any) => audChunks.push(e.data); + const audChunks: Blob[] = []; + this._audioRec.ondataavailable = e => audChunks.push(e.data); this._audioRec.onstop = async () => { - const [{ result }] = await Networking.UploadFilesToServer(audChunks.map((file: any) => ({ file }))); + const [{ result }] = await Networking.UploadFilesToServer(audChunks.map(file => ({ file }))); if (!(result instanceof Error)) { this.dataDoc[this._props.fieldKey + '_audio'] = new AudioField(result.accessPaths.agnostic.client); } }; - this._videoRef!.srcObject = await (navigator.mediaDevices as any).getDisplayMedia({ video: true }); - this._videoRec = new MediaRecorder(this._videoRef!.srcObject); - const vidChunks: any = []; + this._videoRef.srcObject = await navigator.mediaDevices.getDisplayMedia({ video: true }); + this._videoRec = new MediaRecorder(this._videoRef.srcObject); + const vidChunks: Blob[] = []; this._videoRec.onstart = () => { if (this.dataDoc[this._props.fieldKey + '_trackScreen']) TrackMovements.Instance.start(); this.dataDoc[this._props.fieldKey + '_recordingStart'] = new DateField(new Date()); }; - this._videoRec.ondataavailable = (e: any) => vidChunks.push(e.data); + this._videoRec.ondataavailable = e => vidChunks.push(e.data); this._videoRec.onstop = async () => { const presentation = TrackMovements.Instance.yieldPresentation(); if (presentation?.movements) { const presCopy = { ...presentation }; - presCopy.movements = presentation.movements.map(movement => ({ ...movement, doc: movement.doc[Id] })) as any; + presCopy.movements = presentation.movements.map(movement => ({ ...movement, doc: (movement.doc as Doc)[Id] }) as Movement); this.dataDoc[this.fieldKey + '_presentation'] = JSON.stringify(presCopy); } TrackMovements.Instance.finish(); diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index bc19d7ad1..8da422039 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -1,8 +1,8 @@ /* eslint-disable react/button-has-type */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import ResizeObserver from 'resize-observer-polyfill'; import { returnAlways, returnEmptyString } from '../../../ClientUtils'; import { Doc } from '../../../fields/Doc'; import { List } from '../../../fields/List'; @@ -10,21 +10,26 @@ import { listSpec } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; +import { DocumentType } from '../../documents/DocumentTypes'; +import { Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { ScriptManager } from '../../util/ScriptManager'; -import { CompileScript, ScriptParam } from '../../util/Scripting'; +import { CompileError, CompileScript, ScriptParam } from '../../util/Scripting'; import { ScriptingGlobals } from '../../util/ScriptingGlobals'; import { ContextMenu } from '../ContextMenu'; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { EditableView } from '../EditableView'; import { OverlayView } from '../OverlayView'; -import { FieldView, FieldViewProps } from './FieldView'; import { DocumentIconContainer } from './DocumentIcon'; +import { FieldView, FieldViewProps } from './FieldView'; import './ScriptingBox.scss'; -import { Docs } from '../../documents/Documents'; -import { DocumentType } from '../../documents/DocumentTypes'; +import * as ts from 'typescript'; +import { FieldType } from '../../../fields/ObjectField'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const getCaretCoordinates = require('textarea-caret'); -const _global = (window /* browser */ || global) /* node */ as any; +// eslint-disable-next-line @typescript-eslint/no-var-requires const ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default; @observer @@ -41,9 +46,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() @observable private _function: boolean = false; @observable private _spaced: boolean = false; - @observable private _scriptKeys: any = ScriptingGlobals.getGlobals(); - @observable private _scriptingDescriptions: any = ScriptingGlobals.getDescriptions(); - @observable private _scriptingParams: any = ScriptingGlobals.getParameters(); + @observable private _scriptKeys = ScriptingGlobals.getGlobals(); + @observable private _scriptingDescriptions = ScriptingGlobals.getDescriptions(); + @observable private _scriptingParams = ScriptingGlobals.getParameters(); @observable private _currWord: string = ''; @observable private _suggestions: string[] = []; @@ -52,20 +57,20 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() @observable private _suggestionBoxY: number = 0; @observable private _lastChar: string = ''; - @observable private _suggestionRef: any = React.createRef(); - @observable private _scriptTextRef: any = React.createRef(); + @observable private _suggestionRef = React.createRef(); + @observable private _scriptTextRef = React.createRef(); - @observable private _selection: any = 0; + @observable private _selection = 0; @observable private _paramSuggestion: boolean = false; - @observable private _scriptSuggestedParams: any = ''; - @observable private _scriptParamsText: any = ''; + @observable private _scriptSuggestedParams: JSX.Element | string = ''; + @observable private _scriptParamsText = ''; constructor(props: FieldViewProps) { super(props); makeObservable(this); if (!this.compileParams.length) { - const params = ScriptCast(this.dataDoc[this._props.fieldKey])?.script.options.params as { [key: string]: any }; + const params = ScriptCast(this.dataDoc[this._props.fieldKey])?.script.options.params as { [key: string]: string }; if (params) { this.compileParams = Array.from(Object.keys(params)) .filter(p => !p.startsWith('_')) @@ -106,26 +111,16 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() this.dataDoc[this.fieldKey + '-params'] = new List(value); } - getValue(result: any, descrip: boolean) { - if (typeof result === 'object') { - const text = descrip ? result[1] : result[2]; - return text !== undefined ? text : ''; - } - return ''; - } - onClickScriptDisable = returnAlways; @action componentDidMount() { this._props.setContentViewBox?.(this); this.rawText = this.rawScript; - const resizeObserver = new _global.ResizeObserver( + const resizeObserver = new ResizeObserver( action(() => { const area = document.querySelector('textarea'); if (area) { - // eslint-disable-next-line global-require - const getCaretCoordinates = require('textarea-caret'); const caret = getCaretCoordinates(area, this._selection); this.resetSuggestionPos(caret); } @@ -135,12 +130,12 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() } @action - resetSuggestionPos(caret: any) { + resetSuggestionPos(caret: { top: number; left: number; height: number }) { if (!this._suggestionRef.current || !this._scriptTextRef.current) return; const suggestionWidth = this._suggestionRef.current.offsetWidth; const scriptWidth = this._scriptTextRef.current.offsetWidth; const { top } = caret; - const { x } = this.dataDoc; + const x = NumCast(this.layoutDoc.x); let { left } = caret; if (left + suggestionWidth > x + scriptWidth) { const diff = left + suggestionWidth - (x + scriptWidth); @@ -171,8 +166,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() // displays error message @action - onError = (error: any) => { - this._errorMessage = error?.message ? error.message : error?.map((entry: any) => entry.messageText).join(' ') || ''; + onError = (errors: ts.Diagnostic[] | string) => { + this._errorMessage = typeof errors === 'string' ? errors : errors.map(entry => entry.toString()).join(' ') || ''; }; // checks if the script compiles using CompileScript method and inputting params @@ -184,7 +179,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() }); const result = !this.rawText.trim() - ? ({ compiled: false, errors: undefined } as any) + ? ({ compiled: false, errors: [] } as CompileError) : CompileScript(this.rawText, { editable: true, transformer: DocumentIconContainer.getTransformer(), @@ -192,7 +187,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() typecheck: false, }); this.dataDoc[this.fieldKey] = result.compiled ? new ScriptField(result, undefined, this.rawText) : undefined; - this.onError(result.compiled ? undefined : result.errors); + this.onError(result.compiled ? [] : result.errors); return result.compiled; }; @@ -200,7 +195,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() @action onRun = () => { if (this.onCompile()) { - const bindings: { [name: string]: any } = {}; + const bindings: { [name: string]: unknown } = {}; this.paramsNames.forEach(key => { bindings[key] = this.dataDoc[key]; }); @@ -294,8 +289,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() // sets field of the param name to the selected value in drop down box @action - viewChanged = (e: React.ChangeEvent, name: string) => { - const val = (e.target as any).selectedOptions[0].value; + viewChanged = (e: React.ChangeEvent, name: string) => { + const val = e.target.selectedOptions[0].value; this.dataDoc[name] = val[0] === 'S' ? val.substring(1) : val[0] === 'N' ? parseInt(val.substring(1)) : val.substring(1) === 'true'; }; @@ -309,7 +304,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() // adds option to create a copy to the context menu specificContextMenu = (): void => { const existingOptions = ContextMenu.Instance.findByDescription('Options...'); - const options = existingOptions && 'subitems' in existingOptions ? existingOptions.subitems : []; + const options = existingOptions?.subitems ?? []; options.push({ description: 'Create a Copy', event: this.onCopy, icon: 'copy' }); !existingOptions && ContextMenu.Instance.addItem({ description: 'Options...', subitems: options, icon: 'hand-point-right' }); }; @@ -381,7 +376,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() const results = script.compiled && script.run(); if (results && results.success) { this._errorMessage = ''; - this.dataDoc[parameter] = results.result; + this.dataDoc[parameter] = results.result as FieldType; return true; } this._errorMessage = 'invalid document'; @@ -524,18 +519,17 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() @action suggestionPos = () => { - // eslint-disable-next-line global-require - const getCaretCoordinates = require('textarea-caret'); + // eslint-disable-next-line @typescript-eslint/no-this-alias const This = this; document.querySelector('textarea')?.addEventListener('input', function () { - const caret = getCaretCoordinates(this, this.selectionEnd); - This._selection = this; + const caret = getCaretCoordinates(this, this.selectionEnd) as { top: number; left: number; height: number }; + // This._selection = this; This.resetSuggestionPos(caret); }); }; @action - keyHandler(e: any, pos: number) { + keyHandler(e: React.KeyboardEvent, pos: number) { e.stopPropagation(); if (this._lastChar === 'Enter') { this.rawText += ' '; @@ -602,7 +596,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() } @action - handlePosChange(number: any) { + handlePosChange(number: number) { this._caretPos = number; if (this._caretPos === 0) { this.rawText = ' ' + this.rawText; @@ -625,7 +619,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() placeholder="write your script here" onFocus={this.onFocus} onBlur={() => this._overlayDisposer?.()} - onChange={action((e: any) => { + onChange={action((e: React.ChangeEvent) => { this.rawText = e.target.value; })} value={this.rawText} @@ -633,24 +627,24 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent() loadingComponent={() => Loading} trigger={{ ' ': { - dataProvider: (token: any) => this.handleToken(token), - component: (blob: any) => this.renderFuncListElement(blob.entity), - output: (item: any, trigger: any) => { + dataProvider: this.handleToken, + component: (blob: { entity: string }) => this.renderFuncListElement(blob.entity), + output: (item: string, trigger: string) => { this._spaced = true; return trigger + item.trim(); }, }, '.': { - dataProvider: (token: any) => this.handleToken(token), - component: (blob: any) => this.renderFuncListElement(blob.entity), - output: (item: any, trigger: any) => { + dataProvider: this.handleToken, + component: (blob: { entity: string }) => this.renderFuncListElement(blob.entity), + output: (item: string, trigger: string) => { this._spaced = true; return trigger + item.trim(); }, }, }} onKeyDown={(e: React.KeyboardEvent) => this.keyHandler(e, this._caretPos)} - onCaretPositionChange={(number: any) => this.handlePosChange(number)} + onCaretPositionChange={this.handlePosChange} />
); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 1f285b300..4933869a7 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -125,8 +125,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { } override PlayerTime = () => this.player?.currentTime; - override Pause = (update: boolean = true) => { - this.pause(update); + override Pause = () => { + this.pause(true); !this._keepCurrentlyPlaying && this.removeCurrentlyPlaying(); }; @@ -157,7 +157,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { }; // plays video - @action public Play = (update: boolean = true) => { + @action public Play = () => { if (this._playRegionTimer) return; this._playing = true; @@ -172,8 +172,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { } try { this._audioPlayer && this.player && (this._audioPlayer.currentTime = this.player?.currentTime); - update && this.player && this.playFrom(start, undefined, true); - update && this._audioPlayer?.play(); + this.player && this.playFrom(start, undefined, true); + this._audioPlayer?.play(); } catch (e) { console.log('Video Play Exception:', e); } @@ -384,7 +384,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { getVideoThumbnails = () => { if (this.dataDoc[this.fieldKey + '_thumbnails'] !== undefined) return; this.dataDoc[this.fieldKey + '_thumbnails'] = new List(); - const thumbnailPromises: Promise[] = []; + const thumbnailPromises: Promise[] = []; const video = document.createElement('video'); video.onloadedmetadata = () => { @@ -467,7 +467,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { runInAction(() => { this._screenCapture = !this._screenCapture; }); - this._videoRef!.srcObject = !this._screenCapture ? null : await (navigator.mediaDevices).getDisplayMedia({ video: true }); + this._videoRef!.srcObject = !this._screenCapture ? null : await navigator.mediaDevices.getDisplayMedia({ video: true }); }, icon: 'expand-arrows-alt', }); @@ -557,9 +557,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { style={this._fullScreen ? this.fullScreenSize() : this.isCropped ? { width: 'max-content', height: 'max-content', transform: `scale(${1 / NumCast(this.layoutDoc._freeform_scale)})`, transformOrigin: 'top left' } : {}} onCanPlay={this.videoLoad} controls={false} - onPlay={() => this.Play()} + onPlay={this.Play} onSeeked={this.updateTimecode} - onPause={() => this.Pause()} + onPause={this.Pause} onClick={this._fullScreen ? () => (this.playing() ? this.Pause() : this.Play()) : e => e.preventDefault()}> Not supported. diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index be7e0f483..1fd73c226 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -1,4 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Property } from 'csstype'; import { htmlToText } from 'html-to-text'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -21,7 +22,7 @@ import { DocumentType } from '../../documents/DocumentTypes'; import { DocUtils } from '../../documents/DocUtils'; import { ScriptingGlobals } from '../../util/ScriptingGlobals'; import { SnappingManager } from '../../util/SnappingManager'; -import { undoBatch, UndoManager } from '../../util/UndoManager'; +import { undoable, UndoManager } from '../../util/UndoManager'; import { MarqueeOptionsMenu } from '../collections/collectionFreeForm'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { ContextMenu } from '../ContextMenu'; @@ -83,7 +84,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { this._marqueeing = val; } @observable private _iframe: HTMLIFrameElement | null = null; - @observable private _savedAnnotations = new ObservableMap(); + @observable private _savedAnnotations = new ObservableMap(); @observable private _scrollHeight = NumCast(this.layoutDoc.scrollHeight); @computed get _url() { return this.webField?.toString() || ''; @@ -121,11 +122,12 @@ export class WebBox extends ViewBoxAnnotatableComponent() { }); } try { + const contentWindow = this._iframe?.contentWindow; if (clear) { - this._iframe?.contentWindow?.getSelection()?.empty(); + contentWindow?.getSelection()?.empty(); } - if (searchString) { - (this._iframe?.contentWindow as any)?.find(searchString, false, bwd, true); + if (searchString && contentWindow && 'find' in contentWindow) { + (contentWindow.find as (str: string, caseSens?: boolean, backward?: boolean, wrapAround?: boolean) => void)(searchString, false, bwd, true); } } catch (e) { console.log('WebBox search error', e); @@ -142,7 +144,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { } }; - updateThumb = async () => { + updateIcon = async () => { if (!this._iframe) return; const scrollTop = NumCast(this.layoutDoc._layout_scrollTop); const nativeWidth = NumCast(this.layoutDoc.nativeWidth); @@ -154,7 +156,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { this.layoutDoc.thumb = undefined; this.Document.thumbLockout = true; // lock to prevent multiple thumb updates. CreateImage(this._webUrl.endsWith('/') ? this._webUrl.substring(0, this._webUrl.length - 1) : this._webUrl, this._iframe.contentDocument?.styleSheets ?? [], htmlString, nativeWidth, nativeHeight, scrollTop) - .then((dataUrl: any) => { + .then((dataUrl: string) => { if (dataUrl.includes('() { ) ); }) - .catch((error: any) => { + .catch((error: object) => { console.error('oops, something went wrong!', error); }); }; @@ -359,8 +361,8 @@ export class WebBox extends ViewBoxAnnotatableComponent() { return anchor; }; - _textAnnotationCreator: (() => ObservableMap) | undefined; - savedAnnotationsCreator: () => ObservableMap = () => this._textAnnotationCreator?.() || this._savedAnnotations; + _textAnnotationCreator: (() => ObservableMap) | undefined; + savedAnnotationsCreator: () => ObservableMap = () => this._textAnnotationCreator?.() || this._savedAnnotations; @action iframeMove = (e: PointerEvent) => { @@ -424,11 +426,11 @@ export class WebBox extends ViewBoxAnnotatableComponent() { sel.empty(); // Chrome else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox // bcz: NEED TO unrotate e.clientX and e.clientY - const word = getWordAtPoint(e.target, e.clientX, e.clientY); + const target = e.target as HTMLElement; + const word = target && getWordAtPoint(target, e.clientX, e.clientY); this._setPreviewCursor?.(e.clientX, e.clientY, false, true, this.Document); MarqueeAnnotator.clearAnnotations(this._savedAnnotations); - const target = e.target as HTMLElement; if (!word && !target?.className?.includes('rangeslider') && !target?.onclick && !target?.parentElement?.onclick) { if (e.button !== 2) this.marqueeing = [e.clientX, e.clientY]; e.preventDefault(); @@ -468,8 +470,8 @@ export class WebBox extends ViewBoxAnnotatableComponent() { .inverse() .transformPoint(e.clientX, e.clientY - NumCast(this.layoutDoc.layout_scrollTop)); MarqueeAnnotator.clearAnnotations(this._savedAnnotations); - const word = getWordAtPoint(e.target, e.clientX, e.clientY); const target = e.target as HTMLElement; + const word = target && getWordAtPoint(target, e.clientX, e.clientY); if (!word && !target?.className?.includes('rangeslider') && !target?.onclick && !target?.parentElement?.onclick) { this.marqueeing = theclick; this._marqueeref.current?.onInitiateSelection(this.marqueeing); @@ -488,7 +490,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { } return undefined; } - addWebStyleSheetRule(sheet: CSSStyleSheet | null | undefined, selector: string, css: {[key:string]: string}, selectorPrefix = '.') { + addWebStyleSheetRule(sheet: CSSStyleSheet | null | undefined, selector: string, css: { [key: string]: string }, selectorPrefix = '.') { const propText = typeof css === 'string' ? css @@ -498,7 +500,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { return sheet?.insertRule(selectorPrefix + selector + '{' + propText + '}', sheet.cssRules.length); } - _iframetimeout: NodeJS.Timeout|undefined = undefined; + _iframetimeout: NodeJS.Timeout | undefined = undefined; @observable _warning = 0; @action iframeLoaded = () => { @@ -520,7 +522,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { if (requrlraw !== this._url.toString()) { if (requrlraw.match(/q=.*&/)?.length && this._url.toString().match(/q=.*&/)?.length) { const matches = requrlraw.match(/[^a-zA-z]q=[^&]*/g); - const newsearch = matches?.lastElement() || ""; + const newsearch = matches?.lastElement() || ''; if (matches) { requrlraw = requrlraw.substring(0, requrlraw.indexOf(newsearch)); for (let i = 1; i < Array.from(matches)?.length; i++) { @@ -567,12 +569,12 @@ export class WebBox extends ViewBoxAnnotatableComponent() { ); iframeContent.addEventListener( 'click', - undoBatch( + undoable( action((e: MouseEvent) => { let eleHref = ''; for (let ele = e.target as HTMLElement | Element | null; ele; ele = ele.parentElement) { if (ele instanceof HTMLAnchorElement) { - eleHref = (typeof ele.href === 'string' ? ele.href : eleHref) || (ele.parentElement && ("href" in ele.parentElement) ? ele.parentElement.href as string: eleHref); + eleHref = (typeof ele.href === 'string' ? ele.href : eleHref) || (ele.parentElement && 'href' in ele.parentElement ? (ele.parentElement.href as string) : eleHref); } } const origin = this.webField?.origin; @@ -588,7 +590,8 @@ export class WebBox extends ViewBoxAnnotatableComponent() { this._outerRef.current.scrollLeft = 0; } } - }) + }), + 'follow web link' ) ); iframe.contentDocument.addEventListener('wheel', this.iframeWheel, { passive: false }); @@ -792,7 +795,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { }, icon: 'snowflake', }); - funcs.push({ description: 'Create Thumbnail', event: () => this.updateThumb(), icon: 'portrait' }); + !Doc.noviceMode && funcs.push({ description: 'Update Icon', event: () => this.updateIcon(), icon: 'portrait' }); cm.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' }); } }; @@ -1085,7 +1088,7 @@ export class WebBox extends ViewBoxAnnotatableComponent() { @computed get webpage() { TraceMobx(); const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; - const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as "none" | "all" | "visiblePainted" | undefined) + const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as Property.PointerEvents | undefined); const scale = previewScale * (this._props.NativeDimScaling?.() || 1); return (
() { render() { TraceMobx(); const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; - const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as 'none' | 'all' | 'visiblePainted' | undefined); + const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as Property.PointerEvents); const scale = previewScale * (this._props.NativeDimScaling?.() || 1); return (
new Promise(resolve => { - const img = new Image(); - img.onload = function () { - console.log(`IMAGE SVG created: ${webUrl}`); - resolve(img); - }; console.log(`BUILDING SVG for: ${webUrl}`); buildSvgDataUri(webUrl, html, width, height, scroll, xoff).then(uri => { + const img = new Image(); img.src = uri; - return img; + img.onload = () => { + console.log(`IMAGE SVG created: ${webUrl}`); + resolve(img); + }; }); }); @@ -272,7 +269,7 @@ const ForeignHtmlRenderer = function (styleSheets) { * @return {Promise} */ this.renderToCanvas = (webUrl, html, width, height, scroll, xoff, oversample) => - self.renderToImage(webUrl, html, width, height, scroll, xoff).then(img => { + this.renderToImage(webUrl, html, width, height, scroll, xoff).then(img => { const canvas = document.createElement('canvas'); canvas.width = img.width * oversample; canvas.height = img.height * oversample; @@ -290,8 +287,7 @@ const ForeignHtmlRenderer = function (styleSheets) { * @return {Promise} */ this.renderToBase64Png = (webUrl, html, width, height, scroll, xoff, oversample) => - self - .renderToCanvas(webUrl, html, width, height, scroll, xoff, oversample) // + this.renderToCanvas(webUrl, html, width, height, scroll, xoff, oversample) // .then(canvas => canvas.toDataURL('image/png')); }; diff --git a/src/client/views/nodes/audio/AudioWaveform.tsx b/src/client/views/nodes/audio/AudioWaveform.tsx index 2d1d3d7db..297deb575 100644 --- a/src/client/views/nodes/audio/AudioWaveform.tsx +++ b/src/client/views/nodes/audio/AudioWaveform.tsx @@ -39,7 +39,7 @@ export class AudioWaveform extends ObservableReactComponent public static NUMBER_OF_BUCKETS = 100; // number of buckets data is divided into to draw waveform lines _disposer: IReactionDisposer | undefined; - constructor(props: any) { + constructor(props: AudioWaveformProps) { super(props); makeObservable(this); } diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx index 3ec49fa27..0304ddc86 100644 --- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx +++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx @@ -5,18 +5,20 @@ import { IReactionDisposer, computed, reaction } from 'mobx'; import { Doc } from '../../../../fields/Doc'; import { DocServer } from '../../../DocServer'; import { NumCast } from '../../../../fields/Types'; +import { Node } from 'prosemirror-model'; +import { EditorView } from 'prosemirror-view'; interface IDashDocCommentViewInternal { docId: string; - view: any; - getPos: any; + view: EditorView; + getPos: () => number; setHeight: (height: number) => void; } export class DashDocCommentViewInternal extends React.Component { _reactionDisposer: IReactionDisposer | undefined; - constructor(props: any) { + constructor(props: IDashDocCommentViewInternal) { super(props); this.onPointerLeaveCollapsed = this.onPointerLeaveCollapsed.bind(this); this.onPointerEnterCollapsed = this.onPointerEnterCollapsed.bind(this); @@ -43,19 +45,19 @@ export class DashDocCommentViewInternal extends React.Component { + onPointerLeaveCollapsed = (e: React.PointerEvent) => { this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight()); e.preventDefault(); e.stopPropagation(); }; - onPointerEnterCollapsed = (e: any) => { + onPointerEnterCollapsed = (e: React.PointerEvent) => { this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false)); e.preventDefault(); e.stopPropagation(); }; - onPointerUpCollapsed = (e: any) => { + onPointerUpCollapsed = (e: React.PointerEvent) => { const target = this.targetNode(); if (target) { @@ -65,7 +67,7 @@ export class DashDocCommentViewInternal extends React.Component { expand && this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)); try { - this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, this.props.getPos() + (expand ? 2 : 1)))); + this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, (this.props.getPos() ?? 0) + (expand ? 2 : 1)))); } catch (err) { /* empty */ } @@ -74,7 +76,7 @@ export class DashDocCommentViewInternal extends React.Component { + onPointerDownCollapsed = (e: React.PointerEvent) => { e.stopPropagation(); }; @@ -84,7 +86,7 @@ export class DashDocCommentViewInternal extends React.Component number | undefined) { this.node = node; this.dom = document.createElement('div'); this.dom.style.width = node.attrs.width; @@ -130,22 +132,22 @@ export class DashDocCommentView { this.dom.style.fontWeight = 'bold'; this.dom.style.position = 'relative'; this.dom.style.display = 'inline-block'; - this.dom.onkeypress = function (e: any) { + this.dom.onkeypress = function (e) { e.stopPropagation(); }; - this.dom.onkeydown = function (e: any) { + this.dom.onkeydown = function (e) { e.stopPropagation(); }; - this.dom.onkeyup = function (e: any) { + this.dom.onkeyup = function (e) { e.stopPropagation(); }; - this.dom.onmousedown = function (e: any) { + this.dom.onmousedown = function (e) { e.stopPropagation(); }; + const getPosition = () => getPos() ?? 0; this.root = ReactDOM.createRoot(this.dom); - this.root.render(); - (this as any).dom = this.dom; + this.root.render(); } setHeight = (hgt: number) => { diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index 93371685d..e7f2cdba8 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -1,4 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { NodeSelection } from 'prosemirror-state'; @@ -16,6 +15,8 @@ import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocumentView } from '../DocumentView'; import { FocusViewOptions } from '../FocusViewOptions'; import { FormattedTextBox } from './FormattedTextBox'; +import { EditorView } from 'prosemirror-view'; +import { Node } from 'prosemirror-model'; const horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side. interface IDashDocViewInternal { @@ -26,9 +27,9 @@ interface IDashDocViewInternal { height: string; hidden: boolean; fieldKey: string; - view: any; - node: any; - getPos: any; + view: EditorView; + node: Node; + getPos: () => number; } @observer @@ -109,7 +110,7 @@ export class DashDocViewInternal extends ObservableReactComponent this._textBox.focus(target, options); // ideally, this would scroll to show the focus target - onKeyDown = (e: any) => { + onKeyDown = (e: React.KeyboardEvent) => { e.stopPropagation(); if (e.key === 'Tab' || e.key === 'Enter') { e.preventDefault(); @@ -176,29 +177,31 @@ export class DashDocViewInternal extends ObservableReactComponent number | undefined, tbox: FormattedTextBox) { this.dom = document.createElement('span'); this.dom.style.position = 'relative'; this.dom.style.textIndent = '0'; this.dom.style.width = (+node.attrs.width.toString().replace('px', '') + horizPadding).toString(); this.dom.style.height = node.attrs.height; this.dom.style.display = node.attrs.hidden ? 'none' : 'inline-block'; - (this.dom.style as any).float = node.attrs.float; - this.dom.onkeypress = function (e: any) { + this.dom.style.float = node.attrs.float; + this.dom.onkeypress = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onkeydown = function (e: any) { + this.dom.onkeydown = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onkeyup = function (e: any) { + this.dom.onkeyup = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onmousedown = function (e: any) { + this.dom.onmousedown = function (e: MouseEvent) { e.stopPropagation(); }; + const getPosition = () => getPos() ?? 0; + this.root = ReactDOM.createRoot(this.dom); this.root.render( ); } diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index 9903d0e8a..f0313fba4 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -1,6 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -/* eslint-disable jsx-a11y/control-has-associated-label */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; @@ -26,6 +23,8 @@ import { ObservableReactComponent } from '../../ObservableReactComponent'; import { OpenWhere } from '../OpenWhere'; import './DashFieldView.scss'; import { FormattedTextBox } from './FormattedTextBox'; +import { Node } from 'prosemirror-model'; +import { EditorView } from 'prosemirror-view'; @observer export class DashFieldViewMenu extends AntimodeMenu { @@ -34,7 +33,7 @@ export class DashFieldViewMenu extends AntimodeMenu { static createFieldView: (e: React.MouseEvent) => void = emptyFunction; static toggleFieldHide: () => void = emptyFunction; static toggleValueHide: () => void = emptyFunction; - constructor(props: any) { + constructor(props: AntimodeMenuProps) { super(props); DashFieldViewMenu.Instance = this; } @@ -100,8 +99,8 @@ interface IDashFieldViewInternal { height: number; editable: boolean; nodeSelected: () => boolean; - node: any; - getPos: any; + node: Node; + getPos: () => number; unclickable: () => boolean; } @@ -274,7 +273,9 @@ export class DashFieldViewInternal extends ObservableReactComponent {this.values.map(val => ( - + ))} )} @@ -284,16 +285,17 @@ export class DashFieldViewInternal extends ObservableReactComponent number | undefined; @observable _nodeSelected = false; NodeSelected = () => this._nodeSelected; - unclickable = () => !this.tbox._props.rootSelected?.() && this.node.marks.some((m: any) => m.type === this.tbox.EditorView?.state.schema.marks.linkAnchor && m.attrs.noPreview); - constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { + unclickable = () => !this.tbox._props.rootSelected?.() && this.node.marks.some(m => m.type === this.tbox.EditorView?.state.schema.marks.linkAnchor && m.attrs.noPreview); + constructor(node: Node, view: EditorView, getPos: () => number | undefined, tbox: FormattedTextBox) { makeObservable(this); + const getPosition = () => getPos() ?? 0; this.node = node; this.tbox = tbox; this.getpos = getPos; @@ -312,7 +314,7 @@ export class DashFieldView { const editor = tbox.EditorView; if (editor) { const { state } = editor; - for (let i = this.getpos() + 1; i < state.doc.content.size; i++) { + for (let i = getPosition() + 1; i < state.doc.content.size; i++) { if (state.doc.nodeAt(i)?.type.name === state.schema.nodes.dashField.name) { editor.dispatch(state.tr.setSelection(new NodeSelection(state.doc.resolve(i)))); return; @@ -321,10 +323,10 @@ export class DashFieldView { } } }; - this.dom.onkeyup = function (e: any) { + this.dom.onkeyup = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onmousedown = function (e: any) { + this.dom.onmousedown = function (e: MouseEvent) { e.stopPropagation(); }; @@ -333,7 +335,7 @@ export class DashFieldView { } */ class EquationEditor extends Component { - element: any; + element: React.RefObject; + // eslint-disable-next-line @typescript-eslint/no-explicit-any mathField: any; ignoreEditEvents: number; // Element needs to be in the class format and thus requires a constructor. The steps that are run // in the constructor is to make sure that React can succesfully communicate with the equation // editor. - constructor(props: any) { + constructor(props: EquationEditorProps) { super(props); - this.element = createRef(); + this.element = createRef(); this.mathField = null; // MathJax apparently fire 2 edit events on startup. @@ -74,6 +72,7 @@ class EquationEditor extends Component { autoOperatorNames, }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any this.mathField = (window as any).MathQuill.MathField(this.element.current, config); this.mathField.latex(value || ''); } diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index 5167c8f2a..4d0e9efee 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -1,15 +1,16 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ import { IReactionDisposer } from 'mobx'; import { observer } from 'mobx-react'; +import { Node } from 'prosemirror-model'; import { TextSelection } from 'prosemirror-state'; +import { EditorView } from 'prosemirror-view'; import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import { Doc } from '../../../../fields/Doc'; +import { DocData } from '../../../../fields/DocSymbols'; import { StrCast } from '../../../../fields/Types'; import './DashFieldView.scss'; import EquationEditor from './EquationEditor'; import { FormattedTextBox } from './FormattedTextBox'; -import { DocData } from '../../../../fields/DocSymbols'; interface IEquationViewInternal { fieldKey: string; @@ -27,7 +28,7 @@ export class EquationViewInternal extends React.Component _fieldKey: string; _ref: React.RefObject = React.createRef(); - constructor(props: any) { + constructor(props: IEquationViewInternal) { super(props); this._fieldKey = props.fieldKey; this._textBoxDoc = props.tbox.Document; @@ -63,7 +64,7 @@ export class EquationViewInternal extends React.Component { + onChange={str => { this._textBoxDoc[DocData][this._fieldKey] = str; }} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" @@ -77,25 +78,27 @@ export class EquationViewInternal extends React.Component export class EquationView { dom: HTMLDivElement; // container for label and value - root: any; + root: ReactDOM.Root; tbox: FormattedTextBox; - view: any; - constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { + view: EditorView; + _editor: EquationEditor | undefined; + getPos: () => number; + constructor(node: Node, view: EditorView, getPos: () => number, tbox: FormattedTextBox) { this.tbox = tbox; this.view = view; + this.getPos = getPos; this.dom = document.createElement('div'); this.dom.style.width = node.attrs.width; this.dom.style.height = node.attrs.height; this.dom.style.position = 'relative'; this.dom.style.display = 'inline-block'; - this.dom.onmousedown = function (e: any) { + this.dom.onmousedown = (e: MouseEvent) => { e.stopPropagation(); }; this.root = ReactDOM.createRoot(this.dom); this.root.render(); } - _editor: EquationEditor | undefined; setEditor = (editor?: EquationEditor) => { this._editor = editor; }; @@ -106,6 +109,7 @@ export class EquationView { this._editor?.mathField.focus(); } selectNode() { + this.view.dispatch(this.view.state.tr.setSelection(new TextSelection(this.view.state.doc.resolve(this.getPos())))); this.tbox._applyingChange = this.tbox.fieldKey; // setting focus will make prosemirror lose focus, which will cause it to change its selection to a text selection, which causes this view to get rebuilt but it's no longer node selected, so the equationview won't have focus setTimeout(() => { this._editor?.mathField.focus(); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 39e237986..c8b25e184 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -96,7 +96,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent(); private _ref: React.RefObject = React.createRef(); private _scrollRef: HTMLDivElement | null = null; - private _editorView: Opt; + private _editorView: Opt; public _applyingChange: string = ''; private _inDrop = false; private _finishingLink = false; @@ -113,7 +113,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent new FormattedTextBoxComment() }), - ] }; + return { + schema, + plugins: [ + inputRules(this._rules.inpRules), + this.richTextMenuPlugin(), + history(), + keymap(this._keymap), + keymap(baseKeymap), + new Plugin({ props: { attributes: { class: 'ProseMirror-example-setup-style' } } }), + new Plugin({ view: () => new FormattedTextBoxComment() }), + ], + }; } - public get EditorView() { return this._editorView; } - public get SidebarKey() { return this.fieldKey + '_sidebar'; } + public get EditorView() { + return this._editorView; + } + public get SidebarKey() { + return this.fieldKey + '_sidebar'; + } public makeAIFlashcards: () => void = unimplementedFunction; public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined; @@ -777,7 +785,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { const cm = ContextMenu.Instance; - let target:Element|HTMLElement|null = e.target as HTMLElement; // hrefs are stored on the database of the node that wraps the hyerlink + let target: Element | HTMLElement | null = e.target as HTMLElement; // hrefs are stored on the database of the node that wraps the hyerlink while (target && (!(target instanceof HTMLElement) || !target.dataset?.targethrefs)) target = target.parentElement; const editor = this._editorView; if (editor && target && !(e.nativeEvent instanceof simMouseEvent ? e.nativeEvent.dash : false)) { @@ -789,10 +797,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + const deleteMarkups = undoable(() => { const { selection } = editor.state; editor.dispatch(editor.state.tr.removeMark(selection.from, selection.to, editor.state.schema.marks.linkAnchor)); - }); + }, 'delete markups'); e.persist(); anchorDoc && DocServer.GetRefField(anchorDoc).then( @@ -816,21 +824,21 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + event: undoable(() => { Doc.setNativeView(this.Document); this.layoutDoc.layout_autoHeightMargins = undefined; - }), + }, 'set plain view'), icon: 'eye', }); changeItems.push({ description: 'metadata', - event: undoBatch(() => { + event: undoable(() => { this.dataDoc.layout_meta = Cast(Doc.UserDoc().emptyHeader, Doc, null)?.layout; this.Document.layout_fieldKey = 'layout_meta'; setTimeout(() => { this.layoutDoc._header_height = this.layoutDoc._layout_autoHeightMargins = 50; }, 50); - }), + }, 'set metadata view'), icon: 'eye', }); const noteTypesDoc = Cast(Doc.UserDoc().template_notes, Doc, null); @@ -838,11 +846,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - this.layoutDoc.layout_autoHeightMargins = undefined; - Doc.setNativeView(this.Document); - DocUtils.makeCustomViewClicked(this.Document, Docs.Create.TreeDocument, StrCast(note.title), note); - }), + event: undoable( + () => { + this.layoutDoc.layout_autoHeightMargins = undefined; + Doc.setNativeView(this.Document); + DocUtils.makeCustomViewClicked(this.Document, Docs.Create.TreeDocument, StrCast(note.title), note); + }, + `set ${StrCast(note.title)} view}` + ), icon: icon, }); }); @@ -1229,9 +1240,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent= layoutTime ? (protoTime >= dataTime ? protoData : dataData) : layoutTime >= protoTime ? layoutData : protoData; const whichData = recentData ?? (this.layoutDoc.isTemplateDoc ? layoutData : protoData) ?? protoData; return !whichData ? undefined : { data: RTFCast(whichData), str: Field.toString(DocCast(whichData) ?? StrCast(whichData)) }; @@ -1370,11 +1381,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + return new Plugin({ + view: action((newView: EditorView) => { this._props.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView); return new RichTextMenuPlugin({ editorProps: this._props }); - })}); - }; + }), + }); + } _didScroll = false; _scrollStopper: undefined | (() => void); // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -1509,7 +1522,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + DocServer.GetRefField(target.dataset?.audioid || '').then(anchor => { if (anchor instanceof Doc) { // const timecode = NumCast(anchor.timecodeToShow, 0); const audiodoc = anchor.annotationOn as Doc; @@ -1549,8 +1562,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent node that wraps the hyerlink - for (let target:HTMLElement|Element|null = clickTarget as HTMLElement; target instanceof HTMLElement && !target.dataset?.targethrefs; target = target.parentElement); + let clickTarget: HTMLElement | Element | null = e.target as HTMLElement; // hrefs are stored on the dataset of the node that wraps the hyerlink + for (let target: HTMLElement | Element | null = clickTarget as HTMLElement; target instanceof HTMLElement && !target.dataset?.targethrefs; target = target.parentElement); while (clickTarget instanceof HTMLElement && !clickTarget.dataset?.targethrefs) clickTarget = clickTarget.parentElement; const dataset = clickTarget instanceof HTMLElement ? clickTarget?.dataset : undefined; FormattedTextBoxComment.update(this, this.EditorView!, undefined, dataset?.targethrefs, dataset?.linkdoc, dataset?.nopreview === 'true'); @@ -1588,7 +1601,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { if (!this._props.isContentActive()) return; const editorView = this._editorView; - const editorRoot = editorView?.root instanceof Document ?editorView.root : undefined; + const editorRoot = editorView?.root instanceof Document ? editorView.root : undefined; if (editorView && (!this._forceUncollapse || editorRoot?.getSelection()?.isCollapsed)) { // this is a hack to allow the cursor to be placed at the end of a document when the document ends in an inline dash comment. Apparently Chrome on Windows has a bug/feature which breaks this when clicking after the end of the text. const pcords = editorView.posAtCoords({ left: e.clientX, top: e.clientY }); @@ -1834,7 +1847,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent d?.author).length; const color = !annotated ? Colors.WHITE : Colors.BLACK; - const backgroundColor = !annotated ? (this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK) : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.WidgetColor + (annotated ? ':annotated' : '')) as string; + const backgroundColor = !annotated ? (this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK) : (this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.WidgetColor + (annotated ? ':annotated' : '')) as string); return !annotated && (!this._props.isContentActive() || SnappingManager.IsDragging || Doc.ActiveTool !== InkTool.None) ? null : (
{ - const { textBox, startUserMarkRegion, endUserMarkRegion, userMark } = FormattedTextBoxComment; - false && startUserMarkRegion !== undefined && textBox?.adoptAnnotation(startUserMarkRegion, endUserMarkRegion, userMark); + // const { textBox, startUserMarkRegion, endUserMarkRegion, userMark } = FormattedTextBoxComment; + // startUserMarkRegion !== undefined && textBox?.adoptAnnotation(startUserMarkRegion, endUserMarkRegion, userMark); e.stopPropagation(); e.preventDefault(); }; diff --git a/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts b/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts index 8799964b3..d41938698 100644 --- a/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts +++ b/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts @@ -1,18 +1,18 @@ -import { Node, DOMOutputSpec } from 'prosemirror-model'; +import { Node, DOMOutputSpec, AttributeSpec, TagParseRule } from 'prosemirror-model'; import clamp from '../../../util/clamp'; import convertToCSSPTValue from '../../../util/convertToCSSPTValue'; import toCSSLineSpacing from '../../../util/toCSSLineSpacing'; // import type { NodeSpec } from './Types'; type NodeSpec = { - attrs?: { [key: string]: any }; + attrs?: { [key: string]: AttributeSpec }; content?: string; draggable?: boolean; group?: string; inline?: boolean; name?: string; - parseDOM?: Array; - toDOM?: (node: any) => DOMOutputSpec; + parseDOM?: Array; + toDOM?: (node: Node) => DOMOutputSpec; }; // This assumes that every 36pt maps to one indent level. @@ -30,7 +30,7 @@ function convertMarginLeftToIndentValue(marginLeft: string): number { return clamp(MIN_INDENT_LEVEL, Math.floor(ptValue / INDENT_MARGIN_PT_SIZE), MAX_INDENT_LEVEL); } -function getAttrs(dom: HTMLElement): Object { +export function getAttrs(dom: HTMLElement): object { const { lineHeight, textAlign, marginLeft, paddingTop, paddingBottom } = dom.style; let align = dom.getAttribute('align') || textAlign || ''; @@ -50,9 +50,31 @@ function getAttrs(dom: HTMLElement): Object { return { align, indent, lineSpacing, paddingTop, paddingBottom, id }; } -function toDOM(node: Node): DOMOutputSpec { +export function getHeadingAttrs(dom: HTMLElement): { align?: string; indent?: number; lineSpacing?: string; paddingTop?: string; paddingBottom?: string; id: string; level?: number } { + const { lineHeight, textAlign, marginLeft, paddingTop, paddingBottom } = dom.style; + + let align = dom.getAttribute('align') || textAlign || ''; + align = ALIGN_PATTERN.test(align) ? align : ''; + + let indent = parseInt(dom.getAttribute(ATTRIBUTE_INDENT) || '', 10); + + if (!indent && marginLeft) { + indent = convertMarginLeftToIndentValue(marginLeft); + } + + indent = indent || MIN_INDENT_LEVEL; + + const lineSpacing = lineHeight ? toCSSLineSpacing(lineHeight) : undefined; + + const level = Number(dom.nodeName.substring(1)) || 1; + + const id = dom.getAttribute('id') || ''; + return { align, indent, lineSpacing, paddingTop, paddingBottom, id, level }; +} + +export function toDOM(node: Node): DOMOutputSpec { const { align, indent, inset, lineSpacing, paddingTop, paddingBottom, id } = node.attrs; - const attrs: { [key: string]: any } | null = {}; + const attrs: { [key: string]: unknown } | null = {}; let style = ''; if (align && align !== 'left') { diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 247b7c097..738f6d699 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -1,8 +1,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; -import { lift, wrapIn } from 'prosemirror-commands'; +import { lift, toggleMark, wrapIn } from 'prosemirror-commands'; import { Mark, MarkType } from 'prosemirror-model'; import { wrapInList } from 'prosemirror-schema-list'; import { EditorState, NodeSelection, TextSelection, Transaction } from 'prosemirror-state'; @@ -22,8 +22,6 @@ import { updateBullets } from './ProsemirrorExampleTransfer'; import './RichTextMenu.scss'; import { schema } from './schema_rts'; -const { toggleMark } = require('prosemirror-commands'); - @observer export class RichTextMenu extends AntimodeMenu { // eslint-disable-next-line no-use-before-define @@ -35,8 +33,8 @@ export class RichTextMenu extends AntimodeMenu { private _linkToRef = React.createRef(); layoutDoc: Doc | undefined; - @observable public view?: EditorView & { TextView ?: FormattedTextBox } = undefined; - public editorProps: FieldViewProps | AntimodeMenuProps |undefined; + @observable public view?: EditorView & { TextView?: FormattedTextBox } = undefined; + public editorProps: FieldViewProps | AntimodeMenuProps | undefined; public _brushMap: Map> = new Map(); @@ -124,7 +122,7 @@ export class RichTextMenu extends AntimodeMenu { } @action - public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: FormattedTextBoxProps|AntimodeMenuProps|undefined, layoutDoc: Doc | undefined) { + public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: FormattedTextBoxProps | AntimodeMenuProps | undefined, layoutDoc: Doc | undefined) { if (this._linkToRef.current?.getBoundingClientRect().width) { return; } @@ -158,7 +156,7 @@ export class RichTextMenu extends AntimodeMenu { this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle)); } - setMark = (mark: Mark, state: EditorState, dispatch: (tr:Transaction) => void, dontToggle: boolean = false) => { + setMark = (mark: Mark, state: EditorState, dispatch: (tr: Transaction) => void, dontToggle: boolean = false) => { if (mark) { const newPos = state.selection.$anchor.node()?.type === schema.nodes.ordered_list ? state.selection.from : state.selection.from; const node = (state.selection as NodeSelection).node ?? (newPos >= 0 ? state.doc.nodeAt(newPos) : undefined); @@ -177,7 +175,7 @@ export class RichTextMenu extends AntimodeMenu { toggleMark(mark.type, mark.attrs)(state, dispatch); } } - // this.updateMenu(this.view, undefined, undefined, this.layoutDoc); + // this.updateMenu(this.view, undefined, undefined, this.layoutDoc); } }; @@ -193,7 +191,7 @@ export class RichTextMenu extends AntimodeMenu { } } return 'left'; - } + }; // finds font sizes and families in selection getActiveListStyle = () => { @@ -208,7 +206,7 @@ export class RichTextMenu extends AntimodeMenu { } } return ''; - } + }; // finds font sizes and families in selection getActiveFontStylesOnSelection() { @@ -365,7 +363,7 @@ export class RichTextMenu extends AntimodeMenu { this.view.focus(); } else { Doc.UserDoc()[fontField] = value; - // this.updateMenu(this.view, undefined, this.props, this.layoutDoc); + // this.updateMenu(this.view, undefined, this.props, this.layoutDoc); } }; @@ -391,10 +389,10 @@ export class RichTextMenu extends AntimodeMenu { this.view!.dispatch(tx3); }); this.view.focus(); - // this.updateMenu(this.view, undefined, this.props, this.layoutDoc); + // this.updateMenu(this.view, undefined, this.props, this.layoutDoc); }; - insertSummarizer(state: EditorState, dispatch: (tr:Transaction) => void) { + insertSummarizer(state: EditorState, dispatch: (tr: Transaction) => void) { if (state.selection.empty) return false; const mark = state.schema.marks.summarize.create(); const { tr } = state; @@ -408,7 +406,7 @@ export class RichTextMenu extends AntimodeMenu { vcenterToggle = () => { this.layoutDoc && (this.layoutDoc._layout_centered = !this.layoutDoc._layout_centered); }; - align = (view: EditorView, dispatch: (tr:Transaction) => void, alignment: 'left' | 'right' | 'center') => { + align = (view: EditorView, dispatch: (tr: Transaction) => void, alignment: 'left' | 'right' | 'center') => { if (this.TextView?._props.rootSelected?.()) { let { tr } = view.state; view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos) => { @@ -424,7 +422,7 @@ export class RichTextMenu extends AntimodeMenu { } }; - paragraphSetup(state: EditorState, dispatch: (tr:Transaction) => void, field: 'inset' | 'indent', value?: 0 | 10 | -10) { + paragraphSetup(state: EditorState, dispatch: (tr: Transaction) => void, field: 'inset' | 'indent', value?: 0 | 10 | -10) { let { tr } = state; state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => { if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) { @@ -440,8 +438,8 @@ export class RichTextMenu extends AntimodeMenu { return true; } - insertBlockquote(state: EditorState, dispatch: (tr:Transaction) => void) { - const node = state.selection.$from.depth ? state.selection.$from.node(state.selection.$from.depth-1): undefined; + insertBlockquote(state: EditorState, dispatch: (tr: Transaction) => void) { + const node = state.selection.$from.depth ? state.selection.$from.node(state.selection.$from.depth - 1) : undefined; if (node?.type === schema.nodes.blockquote) { lift(state, dispatch); } else { @@ -450,7 +448,7 @@ export class RichTextMenu extends AntimodeMenu { return true; } - insertHorizontalRule(state: EditorState, dispatch: (tr:Transaction) => void) { + insertHorizontalRule(state: EditorState, dispatch: (tr: Transaction) => void) { dispatch(state.tr.replaceSelectionWith(state.schema.nodes.horizontal_rule.create()).scrollIntoView()); return true; } @@ -516,7 +514,7 @@ export class RichTextMenu extends AntimodeMenu { const onLinkChange = (e: React.ChangeEvent) => { this.TextView?.endUndoTypingBatch(); UndoManager.RunInBatch(() => this.setCurrentLink(e.target.value), 'link change'); - } + }; const link = this.currentLink ? this.currentLink : ''; @@ -595,7 +593,7 @@ export class RichTextMenu extends AntimodeMenu { if (this.view) { const linkAnchor = this.view.state.selection.$from.nodeAfter?.marks.find(m => m.type === this.view!.state.schema.marks.linkAnchor); if (linkAnchor) { - const allAnchors = (linkAnchor.attrs.allAnchors as { href: string; title: string; linkId: string; targetId: string; }[]).slice(); + const allAnchors = (linkAnchor.attrs.allAnchors as { href: string; title: string; linkId: string; targetId: string }[]).slice(); this.TextView?.RemoveAnchorFromSelection(allAnchors); // bcz: Argh ... this will remove the link from the document even it's anchored somewhere else in the text which happens if only part of the anchor text was selected. allAnchors @@ -698,7 +696,7 @@ interface RichTextMenuPluginProps { } export class RichTextMenuPlugin extends React.Component { // eslint-disable-next-line react/no-unused-class-component-methods - update(view: EditorView & {TextView ?: FormattedTextBox}, lastState: EditorState | undefined) { + update(view: EditorView & { TextView?: FormattedTextBox }, lastState: EditorState | undefined) { RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps, view.TextView?.layoutDoc); } render() { diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index bf11dfe62..39f589b1e 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -1,4 +1,5 @@ import { ellipsis, emDash, InputRule, smartQuotes, textblockTypeInputRule } from 'prosemirror-inputrules'; +import { NodeType } from 'prosemirror-model'; import { NodeSelection, TextSelection } from 'prosemirror-state'; import { ClientUtils } from '../../../../ClientUtils'; import { Doc, DocListCast, FieldResult, StrListCast } from '../../../../fields/Doc'; @@ -6,7 +7,7 @@ import { DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { Utils } from '../../../../Utils'; +import { emptyFunction, Utils } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; import { CollectionViewType } from '../../../documents/DocumentTypes'; import { DocUtils } from '../../../documents/DocUtils'; @@ -35,13 +36,7 @@ export class RichTextRules { wrappingInputRule(/%>$/, schema.nodes.blockquote), // 1. create numerical ordered list - wrappingInputRule( - /^1\.\s$/, - schema.nodes.ordered_list, - () => ({ mapStyle: 'decimal', bulletStyle: 1 }), - (match: any, node: any) => node.childCount + node.attrs.order === +match[1], - ((type: any) => ({ type: type, attrs: { mapStyle: 'decimal', bulletStyle: 1 } })) as any - ), + wrappingInputRule(/^1\.\s$/, schema.nodes.ordered_list, () => ({ mapStyle: 'decimal', bulletStyle: 1 }), emptyFunction, ((type: unknown) => ({ type, attrs: { mapStyle: 'decimal', bulletStyle: 1 } })) as unknown as null), // A. create alphabetical ordered list wrappingInputRule( @@ -49,9 +44,8 @@ export class RichTextRules { schema.nodes.ordered_list, // match => { () => ({ mapStyle: 'multi', bulletStyle: 1 }), - // return ({ order: +match[1] }) - (match: any, node: any) => node.childCount + node.attrs.order === +match[1], - ((type: any) => ({ type: type, attrs: { mapStyle: 'multi', bulletStyle: 1 } })) as any + emptyFunction, + ((type: NodeType) => ({ type, attrs: { mapStyle: 'multi', bulletStyle: 1 } })) as unknown as null ), // * + - create bullet list @@ -60,8 +54,8 @@ export class RichTextRules { schema.nodes.ordered_list, // match => { () => ({ mapStyle: 'bullet' }), // ({ order: +match[1] }) - (match: any, node: any) => node.childCount + node.attrs.order === +match[1], - ((type: any) => ({ type: type, attrs: { mapStyle: 'bullet' } })) as any + emptyFunction, + ((type: NodeType) => ({ type: type, attrs: { mapStyle: 'bullet' } })) as unknown as null ), // ``` create code block @@ -93,7 +87,7 @@ export class RichTextRules { const textDoc = this.Document[DocData]; const numInlines = NumCast(textDoc.inlineTextCount); textDoc.inlineTextCount = numInlines + 1; - const node = (state.doc.resolve(start) as any).nodeAfter; + const node = state.doc.resolve(start).nodeAfter; const newNode = schema.nodes.dashComment.create({ docId: doc[Id], reflow: false }); const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docId: doc[Id], float: 'right' }); const sm = state.storedMarks || undefined; @@ -137,7 +131,7 @@ export class RichTextRules { textDocInline.proto = textDoc; // make the annotation inherit from the outer text doc so that it can resolve any nested field references, e.g., [[field]] textDoc[inlineLayoutKey] = FormattedTextBox.LayoutString(inlineFieldKey); // create a layout string for the layout key that will render the annotation text textDoc[inlineFieldKey] = ''; // set a default value for the annotation - const node = (state.doc.resolve(start) as any).nodeAfter; + const node = state.doc.resolve(start).nodeAfter; const newNode = schema.nodes.dashComment.create({ docId: textDocInline[Id], reflow: true }); const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docId: textDocInline[Id], float: 'right' }); const sm = state.storedMarks || undefined; @@ -154,8 +148,8 @@ export class RichTextRules { // set the First-line indent node type for the selection's paragraph (assumes % was used to initiate an EnteringStyle mode) new InputRule(/(%d|d)$/, (state, match, start, end) => { if (!match[0].startsWith('%') && !this.EnteringStyle) return null; - const pos = state.doc.resolve(start) as any; - for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) { + const pos = state.doc.resolve(start); + for (let depth = pos.depth; depth >= 0; depth--) { const node = pos.node(depth); if (node.type === schema.nodes.paragraph) { const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, indent: node.attrs.indent === 25 ? undefined : 25 }); @@ -169,8 +163,8 @@ export class RichTextRules { // set the Hanging indent node type for the current selection's paragraph (assumes % was used to initiate an EnteringStyle mode) new InputRule(/(%h|h)$/, (state, match, start, end) => { if (!match[0].startsWith('%') && !this.EnteringStyle) return null; - const pos = state.doc.resolve(start) as any; - for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) { + const pos = state.doc.resolve(start); + for (let depth = pos.depth; depth >= 0; depth--) { const node = pos.node(depth); if (node.type === schema.nodes.paragraph) { const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, indent: node.attrs.indent === -25 ? undefined : -25 }); @@ -184,12 +178,12 @@ export class RichTextRules { // set the Quoted indent node type for the current selection's paragraph (assumes % was used to initiate an EnteringStyle mode) new InputRule(/(%q|q)$/, (state, match, start, end) => { if (!match[0].startsWith('%') && !this.EnteringStyle) return null; - const pos = state.doc.resolve(start) as any; + const pos = state.doc.resolve(start); if (state.selection instanceof NodeSelection && state.selection.node.type === schema.nodes.ordered_list) { const { node } = state.selection; return state.tr.setNodeMarkup(pos.pos, node.type, { ...node.attrs, indent: node.attrs.indent === 30 ? undefined : 30 }); } - for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) { + for (let depth = pos.depth; depth >= 0; depth--) { const node = pos.node(depth); if (node.type === schema.nodes.paragraph) { const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, inset: node.attrs.inset === 30 ? undefined : 30 }); @@ -202,9 +196,9 @@ export class RichTextRules { // center justify text new InputRule(/%\^/, (state, match, start, end) => { - const resolved = state.doc.resolve(start) as any; + const resolved = state.doc.resolve(start); if (resolved?.parent.type.name === 'paragraph') { - return state.tr.deleteRange(start, end).setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); + return state.tr.deleteRange(start, end).setNodeMarkup(resolved.start() - 1, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); } const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -214,9 +208,9 @@ export class RichTextRules { // left justify text new InputRule(/%\[/, (state, match, start, end) => { - const resolved = state.doc.resolve(start) as any; + const resolved = state.doc.resolve(start); if (resolved?.parent.type.name === 'paragraph') { - return state.tr.deleteRange(start, end).setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); + return state.tr.deleteRange(start, end).setNodeMarkup(resolved.start() - 1, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); } const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -226,9 +220,9 @@ export class RichTextRules { // right justify text new InputRule(/%\]/, (state, match, start, end) => { - const resolved = state.doc.resolve(start) as any; + const resolved = state.doc.resolve(start); if (resolved?.parent.type.name === 'paragraph') { - return state.tr.deleteRange(start, end).setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); + return state.tr.deleteRange(start, end).setNodeMarkup(resolved.start() - 1, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); } const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -426,9 +420,9 @@ export class RichTextRules { if (state.selection.to === state.selection.from || !this.EnteringStyle) return null; const tag = match[0] === 't' ? 'todo' : match[0] === 'i' ? 'ignore' : match[0] === 'x' ? 'disagree' : match[0] === '!' ? 'important' : '??'; - const node = (state.doc.resolve(start) as any).nodeAfter; + const node = state.doc.resolve(start).nodeAfter; - if (node?.marks.findIndex((m: any) => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag); + if (node?.marks.findIndex(m => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag); return node ? state.tr .removeMark(start, end, schema.marks.user_mark) @@ -438,7 +432,7 @@ export class RichTextRules { }), new InputRule(/%\(/, (state, match, start, end) => { - const node = (state.doc.resolve(start) as any).nodeAfter; + const node = state.doc.resolve(start).nodeAfter; const sm = state.storedMarks?.slice() || []; const mark = state.schema.marks.summarizeInclusive.create(); @@ -447,7 +441,7 @@ export class RichTextRules { const content = selected.selection.content(); const replaced = node ? selected.replaceRangeWith(start, end, schema.nodes.summary.create({ visibility: true, text: content, textslice: content.toJSON() })) : state.tr; - return replaced.setSelection(new TextSelection(replaced.doc.resolve(end))).setStoredMarks([...node.marks, ...sm]); + return replaced.setSelection(new TextSelection(replaced.doc.resolve(end))).setStoredMarks([...(node?.marks ?? []), ...sm]); }), new InputRule(/%\)/, (state, match, start, end) => state.tr.deleteRange(start, end).removeStoredMark(state.schema.marks.summarizeInclusive.create())), diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts index 6e1f325cf..ba8e4faed 100644 --- a/src/client/views/nodes/formattedText/marks_rts.ts +++ b/src/client/views/nodes/formattedText/marks_rts.ts @@ -34,14 +34,14 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'a[href]', - getAttrs(dom: any) { + getAttrs: dom => { return { title: dom.getAttribute('title'), }; }, }, ], - toDOM(node: any) { + toDOM: node => { const targethrefs = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.href : item.href), ''); const anchorids = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.anchorId : item.anchorId), ''); return ['a', { id: Utils.GenerateGuid(), class: anchorids, 'data-targethrefs': targethrefs, /* 'data-noPreview': 'true', */ 'data-linkdoc': node.attrs.linkDoc, title: node.attrs.title, style: `background: lightBlue` }, 0]; @@ -53,7 +53,7 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'div', - getAttrs(dom: any) { + getAttrs: dom => { return { noAutoLink: dom.getAttribute('data-noAutoLink'), }; @@ -80,7 +80,7 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'a[href]', - getAttrs(dom: any) { + getAttrs: dom => { return { title: dom.getAttribute('title'), noPreview: dom.getAttribute('noPreview'), @@ -88,7 +88,7 @@ export const marks: { [index: string]: MarkSpec } = { }, }, ], - toDOM(node: any) { + toDOM: node => { const targethrefs = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.href : item.href), ''); const anchorids = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.anchorId : item.anchorId), ''); return node.attrs.docref && node.attrs.title @@ -117,7 +117,7 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'span', - getAttrs(dom: any) { + getAttrs: dom => { return { fontSize: dom.style.fontSize ? dom.style.fontSize.toString() : '' }; }, }, @@ -131,7 +131,7 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'span', - getAttrs(dom: any) { + getAttrs: dom => { const cstyle = getComputedStyle(dom); if (cstyle.font) { if (cstyle.font.indexOf('Times New Roman') !== -1) return { fontFamily: 'Times New Roman' }; @@ -154,7 +154,7 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'span', - getAttrs(dom: any) { + getAttrs: dom => { return { color: dom.getAttribute('color') }; }, }, @@ -170,12 +170,12 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'span', - getAttrs(dom: any) { + getAttrs: dom => { return { fontHighlight: dom.getAttribute('background-color') }; }, }, ], - toDOM(node: any) { + toDOM: node => { return node.attrs.fontHighlight ? ['span', { style: 'background-color:' + node.attrs.fontHighlight }] : ['span', { style: 'background-color: transparent' }]; }, }, @@ -224,7 +224,7 @@ export const marks: { [index: string]: MarkSpec } = { attrs: { bulletType: { default: 'decimal' }, }, - toDOM(node: any) { + toDOM: node => { return [ 'span', { @@ -238,11 +238,11 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'span', - getAttrs: (p: any) => { + getAttrs: p => { if (typeof p !== 'string') { const style = getComputedStyle(p); if (style.textDecoration === 'underline') return null; - if (p.parentElement.outerHTML.indexOf('text-decoration: underline') !== -1 && p.parentElement.outerHTML.indexOf('text-decoration-style: solid') !== -1) { + if (p.parentElement?.outerHTML.indexOf('text-decoration: underline') !== -1 && p.parentElement?.outerHTML.indexOf('text-decoration-style: solid') !== -1) { return null; } } @@ -266,11 +266,11 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'span', - getAttrs: (p: any) => { + getAttrs: p => { if (typeof p !== 'string') { const style = getComputedStyle(p); if (style.textDecoration === 'underline') return null; - if (p.parentElement.outerHTML.indexOf('text-decoration: underline') !== -1 && p.parentElement.outerHTML.indexOf('text-decoration-style: dotted') !== -1) { + if (p.parentElement?.outerHTML.indexOf('text-decoration: underline') !== -1 && p.parentElement?.outerHTML.indexOf('text-decoration-style: dotted') !== -1) { return null; } } @@ -292,10 +292,10 @@ export const marks: { [index: string]: MarkSpec } = { parseDOM: [ { tag: 'span', - getAttrs: (p: any) => { + getAttrs: p => { if (typeof p !== 'string') { const style = getComputedStyle(p); - if (style.textDecoration === 'underline' || p.parentElement.outerHTML.indexOf('text-decoration-style:line') !== -1) { + if (style.textDecoration === 'underline' || p.parentElement?.outerHTML.indexOf('text-decoration-style:line') !== -1) { return null; } } @@ -317,7 +317,7 @@ export const marks: { [index: string]: MarkSpec } = { selected: { default: false }, }, parseDOM: [{ style: 'background: yellow' }], - toDOM(node: any) { + toDOM: node => { return ['span', { style: `background: ${node.attrs.selected ? 'orange' : 'yellow'}` }]; }, }, @@ -330,7 +330,7 @@ export const marks: { [index: string]: MarkSpec } = { }, excludes: 'user_mark', group: 'inline', - toDOM(node: any) { + toDOM: node => { const uid = node.attrs.userid.replace(/\./g, '').replace(/@/g, ''); const min = Math.round(node.attrs.modified / 60); const hr = Math.round(min / 60); @@ -348,7 +348,7 @@ export const marks: { [index: string]: MarkSpec } = { }, group: 'inline', inclusive: false, - toDOM(node: any) { + toDOM: node => { const uid = node.attrs.userid.replace('.', '').replace('@', ''); return ['span', { class: 'UT-' + uid + ' UT-' + node.attrs.tag }, 0]; }, diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts index 5bf942218..02ded3103 100644 --- a/src/client/views/nodes/formattedText/nodes_rts.ts +++ b/src/client/views/nodes/formattedText/nodes_rts.ts @@ -1,6 +1,6 @@ import { DOMOutputSpec, Node, NodeSpec } from 'prosemirror-model'; import { listItem, orderedList } from 'prosemirror-schema-list'; -import { ParagraphNodeSpec, toParagraphDOM, getParagraphNodeAttrs } from './ParagraphNodeSpec'; +import { ParagraphNodeSpec, toParagraphDOM, getHeadingAttrs } from './ParagraphNodeSpec'; import { DocServer } from '../../../DocServer'; import { Doc, Field, FieldType } from '../../../../fields/Doc'; import { schema } from './schema_rts'; @@ -53,7 +53,7 @@ export const nodes: { [index: string]: NodeSpec } = { parseDOM: [ { tag: 'audiotag', - getAttrs(dom: any) { + getAttrs: dom => { return { timeCode: dom.getAttribute('data-timecode'), audioId: dom.getAttribute('data-audioid'), @@ -123,24 +123,57 @@ export const nodes: { [index: string]: NodeSpec } = { level: { default: 1 }, }, parseDOM: [ - { tag: 'h1', attrs: { level: 1 } }, - { tag: 'h2', attrs: { level: 2 } }, - { tag: 'h3', attrs: { level: 3 } }, - { tag: 'h4', attrs: { level: 4 } }, - { tag: 'h5', attrs: { level: 5 } }, - { tag: 'h6', attrs: { level: 6 } }, + { + tag: 'h1', + attrs: { level: 1 }, + getAttrs(dom) { + return getHeadingAttrs(dom); + }, + }, + { + tag: 'h2', + attrs: { level: 2 }, + getAttrs(dom) { + return getHeadingAttrs(dom); + }, + }, + { + tag: 'h3', + attrs: { level: 3 }, + getAttrs(dom) { + return getHeadingAttrs(dom); + }, + }, + { + tag: 'h4', + attrs: { level: 4 }, + getAttrs(dom) { + return getHeadingAttrs(dom); + }, + }, + { + tag: 'h5', + attrs: { level: 5 }, + getAttrs(dom) { + return getHeadingAttrs(dom); + }, + }, + { + tag: 'h6', + attrs: { level: 6 }, + getAttrs(dom) { + return getHeadingAttrs(dom); + }, + }, ], toDOM(node) { - const dom = toParagraphDOM(node) as any; - dom[0] = `h${node.attrs.level || 1}`; + const dom = toParagraphDOM(node); + if (dom instanceof Array) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (dom as any)[0] = `h${node.attrs.level || 1}`; // [0] is readonly so cast away to any + } return dom; }, - getAttrs(dom: any) { - const attrs = getParagraphNodeAttrs(dom) as any; - const level = Number(dom.nodeName.substring(1)) || 1; - attrs.level = level; - return attrs; - }, }, // :: NodeSpec A code listing. Disallows marks or non-text inline @@ -221,7 +254,7 @@ export const nodes: { [index: string]: NodeSpec } = { parseDOM: [ { tag: 'img[src]', - getAttrs(dom: any) { + getAttrs: dom => { return { src: dom.getAttribute('src'), title: dom.getAttribute('title'), @@ -300,7 +333,7 @@ export const nodes: { [index: string]: NodeSpec } = { parseDOM: [ { tag: 'video[src]', - getAttrs(dom: any) { + getAttrs: dom => { return { src: dom.getAttribute('src'), title: dom.getAttribute('title'), @@ -341,33 +374,31 @@ export const nodes: { [index: string]: NodeSpec } = { parseDOM: [ { tag: 'ul', - getAttrs(dom: any) { + getAttrs: dom => { return { bulletStyle: dom.getAttribute('data-bulletStyle'), mapStyle: dom.getAttribute('data-mapStyle'), fontColor: dom.style.color, - fontSize: dom.style['font-size'], - fontFamily: dom.style['font-family'], - indent: dom.style['margin-left'], + fontSize: dom.style.fontSize, + fontFamily: dom.style.fontFamily, + indent: dom.style.marginLeft, }; }, }, { style: 'list-style-type=disc', - getAttrs() { - return { mapStyle: 'bullet' }; - }, + getAttrs: () => ({ mapStyle: 'bullet' }), }, { tag: 'ol', - getAttrs(dom: any) { + getAttrs: dom => { return { bulletStyle: dom.getAttribute('data-bulletStyle'), mapStyle: dom.getAttribute('data-mapStyle'), fontColor: dom.style.color, - fontSize: dom.style['font-size'], - fontFamily: dom.style['font-family'], - indent: dom.style['margin-left'], + fontSize: dom.style.fontSize, + fontFamily: dom.style.fontFamily, + indent: dom.style.marginLeft, }; }, }, @@ -416,7 +447,7 @@ export const nodes: { [index: string]: NodeSpec } = { parseDOM: [ { tag: 'li', - getAttrs(dom: any) { + getAttrs: dom => { return { mapStyle: dom.getAttribute('data-mapStyle'), bulletStyle: dom.getAttribute('data-bulletStyle') }; }, }, diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index cb5aad32d..0920b1bd3 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -1,4 +1,3 @@ -/* eslint-disable jsx-a11y/label-has-associated-control */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button, IconButton, Type } from 'browndash-components'; import { action, makeObservable, observable } from 'mobx'; @@ -150,7 +149,7 @@ export class GPTPopup extends ObservableReactComponent { } public addDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean = () => false; - public createFilteredDoc: (axes?: any) => boolean = () => false; + public createFilteredDoc: (axes?: string[]) => boolean = () => false; public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined; /** @@ -371,8 +370,8 @@ export class GPTPopup extends ObservableReactComponent {
{this.heading('GENERATED IMAGE')}
- {this.imgUrls.map(rawSrc => ( -
+ {this.imgUrls.map((rawSrc, i) => ( +
dalle generation
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 1279563ef..dee0edfae 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -1,8 +1,8 @@ import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as Pdfjs from 'pdfjs-dist'; -import 'pdfjs-dist/web/pdf_viewer.css'; import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs'; +import 'pdfjs-dist/webpack.mjs'; // sets the PDF workerSrc import * as React from 'react'; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, returnAll, returnFalse, returnNone, returnZero, smoothScroll } from '../../../ClientUtils'; import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc'; @@ -28,10 +28,8 @@ import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; import './PDFViewer.scss'; - -// pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`; // The workerSrc property shall be specified. -Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.4.168/build/pdf.worker.mjs'; +// Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.4.168/build/pdf.worker.mjs'; interface IViewerProps extends FieldViewProps { pdfBox: PDFBox; @@ -62,7 +60,7 @@ export class PDFViewer extends ObservableReactComponent { } @observable _pageSizes: { width: number; height: number }[] = []; - @observable _savedAnnotations = new ObservableMap(); + @observable _savedAnnotations = new ObservableMap(); @observable _textSelecting = true; @observable _showWaiting = true; @observable Index: number = -1; @@ -214,7 +212,7 @@ export class PDFViewer extends ObservableReactComponent { this._disposers.scale = reaction( () => NumCast(this._props.layoutDoc._freeform_scale, 1), scale => { - this._pdfViewer.currentScaleValue = scale+""; + this._pdfViewer.currentScaleValue = scale + ''; }, { fireImmediately: true } ); @@ -483,7 +481,7 @@ export class PDFViewer extends ObservableReactComponent { e.stopPropagation(); if (e.ctrlKey) { const curScale = Number(this._pdfViewer.currentScaleValue); - this._pdfViewer.currentScaleValue = Math.max(1, Math.min(10, curScale - (curScale * e.deltaY) / 1000)) + ""; + this._pdfViewer.currentScaleValue = Math.max(1, Math.min(10, curScale - (curScale * e.deltaY) / 1000)) + ''; this._props.layoutDoc._freeform_scale = Number(this._pdfViewer.currentScaleValue); } } diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 2792f3aba..e6a95fd30 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-namespace */ /* eslint-disable default-param-last */ /* eslint-disable no-use-before-define */ @@ -19,7 +18,7 @@ import { import { Copy, FieldChanged, HandleUpdate, Id, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols'; import { InkTool } from './InkField'; import { List } from './List'; -import { ObjectField } from './ObjectField'; +import { ObjectField, serverOpType } from './ObjectField'; import { PrefetchProxy, ProxyField } from './Proxy'; import { FieldId, RefField } from './RefField'; import { RichTextField } from './RichTextField'; @@ -28,6 +27,15 @@ import { ComputedField, ScriptField } from './ScriptField'; import { BoolCast, Cast, DocCast, FieldValue, NumCast, StrCast, ToConstructor, toList } from './Types'; import { containedFieldChangedHandler, deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, setter, SharingPermissions } from './util'; +export let ObjGetRefField: (id: string, force?: boolean) => Promise; +export let ObjGetRefFields: (ids: string[]) => Promise>; + +export function SetObjGetRefField(func: (id: string, force?: boolean) => Promise) { + ObjGetRefField = func; +} +export function SetObjGetRefFields(func: (ids: string[]) => Promise>) { + ObjGetRefFields = func; +} export const LinkedTo = '-linkedTo'; export namespace Field { /** @@ -91,18 +99,19 @@ export namespace Field { }); return script; } - export function toString(field: FieldType) { + export function toString(fieldIn: unknown) { + const field = fieldIn as FieldType; if (typeof field === 'string' || typeof field === 'number' || typeof field === 'boolean') return String(field); return field?.[ToString]?.() || ''; } - export function IsField(field: any): field is FieldType; - export function IsField(field: any, includeUndefined: true): field is FieldType | undefined; - export function IsField(field: any, includeUndefined: boolean = false): field is FieldType | undefined { + export function IsField(field: unknown): field is FieldType; + export function IsField(field: unknown, includeUndefined: true): field is FieldType | undefined; + export function IsField(field: unknown, includeUndefined: boolean = false): field is FieldType | undefined { return ['string', 'number', 'boolean'].includes(typeof field) || field instanceof ObjectField || field instanceof RefField || (includeUndefined && field === undefined); } // eslint-disable-next-line @typescript-eslint/no-shadow - export function Copy(field: any) { - return field instanceof ObjectField ? ObjectField.MakeCopy(field) : field; + export function Copy(field: unknown) { + return field instanceof ObjectField ? ObjectField.MakeCopy(field) : (field as FieldType); } UndoManager.SetFieldPrinter(toString); } @@ -157,7 +166,7 @@ export const ReverseHierarchyMap: Map { key.startsWith('acl_') && (permissions[key] = ReverseHierarchyMap.get(StrCast(target[key]))!.acl); @@ -177,7 +186,7 @@ export function updateCachedAcls(doc: Doc) { } @scriptingGlobal -@Deserializable('Doc', updateCachedAcls, ['id']) +@Deserializable('Doc', (obj: unknown) => updateCachedAcls(obj as Doc), ['id']) export class Doc extends RefField { @observable public static RecordingEvent = 0; @observable public static GuestDashboard: Doc | undefined = undefined; @@ -328,12 +337,15 @@ export class Doc extends RefField { } [key: string]: FieldResult; + [key2: symbol]: unknown; @serializable(alias('fields', map(autoObject(), { afterDeserialize: afterDocDeserialize }))) - private get __fieldTuples() { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + get __fieldTuples(): any { + // __fieldTuples does not follow the index signature pattern which requires a FieldResult return value -- so this hack suppresses the error return this[FieldTuples]; } - private set __fieldTuples(value) { + set __fieldTuples(value) { // called by deserializer to set all fields in one shot this[FieldTuples] = value; Object.keys(value).forEach(key => { @@ -348,33 +360,33 @@ export class Doc extends RefField { }); } - @observable private [FieldTuples]: any = {}; - @observable private [FieldKeys]: any = {}; + @observable private [FieldTuples]: { [key: string]: FieldResult } = {}; + @observable private [FieldKeys]: { [key: string]: boolean } = {}; /// all of the raw acl's that have been set on this document. Use GetEffectiveAcl to determine the actual ACL of the doc for editing @observable public [DocAcl]: { [key: string]: symbol } = {}; @observable public [DocCss]: number = 0; // incrementer denoting a change to CSS layout @observable public [DirectLinks] = new ObservableSet(); - @observable public [AudioPlay]: any = undefined; // meant to store sound object from Howl + @observable public [AudioPlay]: unknown = undefined; // meant to store sound object from Howl @observable public [Animation]: Opt = undefined; @observable public [Highlight]: boolean = false; @observable public [Brushed]: boolean = false; - @observable public [DocViews] = new ObservableSet(); + @observable public [DocViews] = new ObservableSet(); private [Self] = this; - private [SelfProxy]: any; + private [SelfProxy]: Doc; private [UpdatingFromServer]: boolean = false; private [ForceServerWrite]: boolean = false; - private [CachedUpdates]: { [key: string]: () => void | Promise } = {}; + private [CachedUpdates]: { [key: string]: () => void | Promise } = {}; public [Initializing]: boolean = false; - public [FieldChanged] = (diff: undefined | { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: any }, serverOp: any) => { + public [FieldChanged] = (diff: { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: unknown } | undefined, serverOp: serverOpType) => { if (!this[UpdatingFromServer] || this[ForceServerWrite]) { DocServer.UpdateField(this[Id], serverOp); } }; public [Width] = () => NumCast(this[SelfProxy]._width); public [Height] = () => NumCast(this[SelfProxy]._height); - public [TransitionTimer]: any = undefined; + public [TransitionTimer]: NodeJS.Timeout | undefined = undefined; public [ToJavascriptString] = () => `idToDoc("${this[Self][Id]}")`; // what should go here? public [ToScriptString] = () => `idToDoc("${this[Self][Id]}")`; public [ToString] = () => `Doc(${GetEffectiveAcl(this[SelfProxy]) === AclPrivate ? '-inaccessible-' : this[SelfProxy].title})`; @@ -387,7 +399,7 @@ export class Doc extends RefField { const self = this[SelfProxy]; const templateLayoutDoc = Cast(Doc.LayoutField(self), Doc, null); if (templateLayoutDoc) { - let renderFieldKey: any; + let renderFieldKey: string = ''; const layoutField = templateLayoutDoc[StrCast(templateLayoutDoc.layout_fieldKey, 'layout')]; if (typeof layoutField === 'string') { [renderFieldKey] = layoutField.split("fieldKey={'")[1].split("'"); // layoutField.split("'")[1]; @@ -399,16 +411,17 @@ export class Doc extends RefField { return undefined; } - public async [HandleUpdate](diff: any) { - const set = diff.$set; + public async [HandleUpdate](diff: { $set: { [key: string]: FieldType } } | { $unset?: unknown }) { + const $set = '$set' in diff ? diff.$set : undefined; + const $unset = '$unset' in diff ? diff.$unset : undefined; const sameAuthor = this.author === ClientUtils.CurrentUserEmail(); const fprefix = 'fields.'; - Object.keys(set ?? {}) + Object.keys($set ?? {}) .filter(key => key.startsWith(fprefix)) .forEach(async key => { const fKey = key.substring(fprefix.length); const fn = async () => { - const value = await SerializationHelper.Deserialize(set[key]); + const value = (await SerializationHelper.Deserialize($set?.[key])) as FieldType; const prev = GetEffectiveAcl(this); this[UpdatingFromServer] = true; this[fKey] = value; @@ -429,8 +442,7 @@ export class Doc extends RefField { this[CachedUpdates][fKey] = fn; } }); - const unset = diff.$unset; - Object.keys(unset ?? {}) + Object.keys($unset ?? {}) .filter(key => key.startsWith(fprefix)) .forEach(async key => { const fKey = key.substring(7); @@ -451,12 +463,10 @@ export class Doc extends RefField { // eslint-disable-next-line no-redeclare export namespace Doc { - // eslint-disable-next-line import/no-mutable-exports export let SelectOnLoad: Doc | undefined; export function SetSelectOnLoad(doc: Doc | undefined) { SelectOnLoad = doc; } - // eslint-disable-next-line import/no-mutable-exports export let DocDragDataName: string = ''; export function SetDocDragDataName(name: string) { DocDragDataName = name; @@ -474,7 +484,7 @@ export namespace Doc { delete doc[CachedUpdates][field]; } } - export function AddCachedUpdate(doc: Doc, field: string, oldValue: any) { + export function AddCachedUpdate(doc: Doc, field: string, oldValue: FieldType) { const val = oldValue; doc[CachedUpdates][field] = () => { doc[UpdatingFromServer] = true; @@ -493,7 +503,7 @@ export namespace Doc { export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldResult { try { - return getField(doc[Self], key, ignoreProto); + return getField(doc[Self], key, ignoreProto) as FieldResult; } catch { return doc; } @@ -558,9 +568,12 @@ export namespace Doc { export function assign(doc: Doc, fields: Partial>>, skipUndefineds: boolean = false, isInitializing = false) { isInitializing && (doc[Initializing] = true); Object.keys(fields).forEach(key => { - const value = (fields as any)[key]; + const value = (fields as { [key: string]: Opt })[key]; if (!skipUndefineds || value !== undefined) { // Do we want to filter out undefineds? + if (typeof value === 'object' && 'values' in value) { + console.log(value); + } doc[key] = value; } }); @@ -712,7 +725,7 @@ export namespace Doc { await Promise.all( Object.keys(doc).map(async key => { if (filter.includes(key)) return; - const assignKey = (val: any) => { + const assignKey = (val: Opt) => { copy[key] = val; }; const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); @@ -735,7 +748,7 @@ export namespace Doc { .trim() ); const results = docids && (await DocServer.GetRefFields(docids)); - const rdocs = results && Array.from(Object.keys(results)).map(rkey => DocCast(results[rkey])); + const rdocs = results && Array.from(Object.keys(results)).map(rkey => DocCast(results.get(rkey))); rdocs?.map(d => d && Doc.makeClone(d, cloneMap, linkMap, rtfs, exclusions, pruneDocs, cloneLinks, cloneTemplates)); rtfs.push({ copy, key, field: objField }); } @@ -818,11 +831,11 @@ export namespace Doc { const linkedDocs = Array.from(linkMap.values()); linkedDocs.forEach(link => Doc.AddLink?.(link, true)); rtfMap.forEach(({ copy, key, field }) => { - const replacer = (match: any, attr: string, id: string /* , offset: any, string: any */) => { + const replacer = (match: string, attr: string, id: string /* , offset: any, string: any */) => { const mapped = cloneMap.get(id); return attr + '"' + (mapped ? mapped[Id] : id) + '"'; }; - const replacer2 = (match: any, href: string, id: string /* , offset: any, string: any */) => { + const replacer2 = (match: string, href: string, id: string /* , offset: any, string: any */) => { const mapped = cloneMap.get(id); return href + (mapped ? mapped[Id] : id); }; @@ -874,7 +887,7 @@ export namespace Doc { newLayoutDoc.embedContainer = targetDoc; newLayoutDoc.resolvedDataDoc = dataDoc; newLayoutDoc.acl_Guest = SharingPermissions.Edit; - if (dataDoc[templateField] === undefined && (templateLayoutDoc[templateField] as any)?.length) { + if (dataDoc[templateField] === undefined && (templateLayoutDoc[templateField] as List)?.length) { dataDoc[templateField] = ObjectField.MakeCopy(templateLayoutDoc[templateField] as List); // ComputedField.MakeFunction(`ObjectField.MakeCopy(templateLayoutDoc["${templateField}"])`, { templateLayoutDoc: Doc.name }, { templateLayoutDoc }); } @@ -901,7 +914,7 @@ export namespace Doc { return { layout: Doc.expandTemplateLayout(childDoc, templateRoot), data: resolvedDataDoc }; } - export function FindReferences(infield: Doc | List, references: Set, system: boolean | undefined) { + export function FindReferences(infield: Doc | List, references: Set, system: boolean | undefined) { if (infield instanceof Promise) return; if (!(infield instanceof Doc)) { infield?.forEach(val => (val instanceof Doc || val instanceof List) && FindReferences(val, references, system)); @@ -976,9 +989,10 @@ export namespace Doc { } else if (cfield instanceof ComputedField) { copy[key] = cfield[Copy](); // ComputedField.MakeFunction(cfield.script.originalScript); } else if (field instanceof ObjectField) { + const docAtKey = doc[key]; copy[key] = - doc[key] instanceof Doc && key.includes('layout[') - ? new ProxyField(Doc.MakeCopy(doc[key] as any)) // copy the expanded render template + docAtKey instanceof Doc && key.includes('layout[') + ? new ProxyField(Doc.MakeCopy(docAtKey)) // copy the expanded render template : ObjectField.MakeCopy(field); } else if (field instanceof Promise) { // eslint-disable-next-line no-debugger @@ -1235,7 +1249,7 @@ export namespace Doc { } const UnhighlightWatchers: (() => void)[] = []; - let UnhighlightTimer: any; + let UnhighlightTimer: NodeJS.Timeout | undefined; export function IsUnhighlightTimerSet() { return UnhighlightTimer; } // prettier-ignore export function AddUnHighlightWatcher(watcher: () => void) { if (UnhighlightTimer) { @@ -1244,7 +1258,7 @@ export namespace Doc { } export function linkFollowUnhighlight() { clearTimeout(UnhighlightTimer); - UnhighlightTimer = 0; + UnhighlightTimer = undefined; UnhighlightWatchers.forEach(watcher => watcher()); UnhighlightWatchers.length = 0; highlightedDocs.forEach(doc => Doc.UnHighlightDoc(doc)); @@ -1258,10 +1272,7 @@ export namespace Doc { if (UnhighlightTimer) clearTimeout(UnhighlightTimer); const presTransition = Number(presentationEffect?.presentation_transition); const duration = isNaN(presTransition) ? 5000 : presTransition; - UnhighlightTimer = window.setTimeout(() => { - linkFollowUnhighlight(); - UnhighlightTimer = 0; - }, duration); + UnhighlightTimer = setTimeout(linkFollowUnhighlight, duration); } export const highlightedDocs = new ObservableSet(); @@ -1319,7 +1330,7 @@ export namespace Doc { StrCast(doc.layout_fieldKey).split('_')[1] === 'icon' && setNativeView(doc); } - export function setNativeView(doc: any) { + export function setNativeView(doc: Doc) { const prevLayout = StrCast(doc.layout_fieldKey).split('_')[1]; const deiconify = prevLayout === 'icon' && StrCast(doc.deiconifyLayout) ? 'layout_' + StrCast(doc.deiconifyLayout) : ''; prevLayout === 'icon' && (doc.deiconifyLayout = undefined); @@ -1356,15 +1367,15 @@ export namespace Doc { // filters document in a container collection: // all documents with the specified value for the specified key are included/excluded // based on the modifiers :"check", "x", undefined - export function setDocFilter(container: Opt, key: string, value: any, modifiers: 'remove' | 'match' | 'check' | 'x' | 'exists' | 'unset', toggle?: boolean, fieldPrefix?: string, append: boolean = true) { + export function setDocFilter(container: Opt, key: string, value: FieldType | undefined, modifiers: 'remove' | 'match' | 'check' | 'x' | 'exists' | 'unset', toggle?: boolean, fieldPrefix?: string, append: boolean = true) { if (!container) return; const filterField = '_' + (fieldPrefix ? fieldPrefix + '_' : '') + 'childFilters'; const childFilters = StrListCast(container[filterField]); runInAction(() => { for (let i = 0; i < childFilters.length; i++) { const fields = childFilters[i].split(FilterSep); // split key:value:modifier - if (fields[0] === key && (fields[1] === value.toString() || modifiers === 'match' || (fields[2] === 'match' && modifiers === 'remove'))) { - if (fields[2] === modifiers && modifiers && fields[1] === value.toString()) { + if (fields[0] === key && (fields[1] === value?.toString() || modifiers === 'match' || (fields[2] === 'match' && modifiers === 'remove'))) { + if (fields[2] === modifiers && modifiers && fields[1] === value?.toString()) { // eslint-disable-next-line no-param-reassign if (toggle) modifiers = 'remove'; else return; @@ -1393,7 +1404,7 @@ export namespace Doc { return undefined; } export function assignDocToField(doc: Doc, field: string, id: string) { - DocServer.GetRefField(id).then(layout => { + DocServer.GetRefField(id)?.then(layout => { layout instanceof Doc && (doc[field] = layout); }); return id; @@ -1460,7 +1471,6 @@ export namespace Doc { case DocumentType.BUTTON: return 'bolt'; case DocumentType.PRES: return 'route'; case DocumentType.SCRIPTING: return 'terminal'; - case DocumentType.IMPORT: return 'cloud-upload-alt'; case DocumentType.VID: return 'video'; case DocumentType.INK: return 'pen-nib'; case DocumentType.PDF: return 'file-pdf'; @@ -1494,7 +1504,7 @@ export namespace Doc { const doc = DocCast(await DocServer.GetRefField(json.id)); const links = await DocServer.GetRefFields(json.linkids as string[]); Array.from(Object.keys(links)) - .map(key => links[key]) + .map(key => links.get(key)) .forEach(link => link instanceof Doc && Doc.AddLink?.(link)); return doc; } @@ -1506,7 +1516,7 @@ export namespace Doc { const primitives = ['string', 'number', 'boolean']; export interface JsonConversionOpts { - data: any; + data: unknown; title?: string; appendToExisting?: { targetDoc: Doc; fieldKey?: string }; excludeEmptyObjects?: boolean; @@ -1561,7 +1571,7 @@ export namespace Doc { if (data === undefined || data === null || ![...primitives, 'object'].includes(typeof data)) { return undefined; } - let resolved: any; + let resolved: unknown; try { resolved = JSON.parse(typeof data === 'string' ? data : JSON.stringify(data)); } catch (e) { @@ -1569,7 +1579,7 @@ export namespace Doc { } let output: Opt; if (typeof resolved === 'object' && !(resolved instanceof Array)) { - output = convertObject(resolved, excludeEmptyObjects, title, appendToExisting?.targetDoc); + output = convertObject(resolved as { [key: string]: FieldType }, excludeEmptyObjects, title, appendToExisting?.targetDoc); } else { // give the proper types to the data extracted from the JSON const result = toField(resolved, excludeEmptyObjects); @@ -1590,7 +1600,7 @@ export namespace Doc { * @returns the object mapped from JSON to field values, where each mapping * might involve arbitrary recursion (since toField might itself call convertObject) */ - const convertObject = (object: any, excludeEmptyObjects: boolean, title?: string, target?: Doc): Opt => { + const convertObject = (object: { [key: string]: FieldType }, excludeEmptyObjects: boolean, title?: string, target?: Doc): Opt => { const hasEntries = Object.keys(object).length; if (hasEntries || !excludeEmptyObjects) { const resolved = target ?? new Doc(); @@ -1618,7 +1628,7 @@ export namespace Doc { * @returns the list mapped from JSON to field values, where each mapping * might involve arbitrary recursion (since toField might itself call convertList) */ - const convertList = (list: Array, excludeEmptyObjects: boolean): Opt> => { + const convertList = (list: Array, excludeEmptyObjects: boolean): Opt> => { const target = new List(); let result: Opt; // if excludeEmptyObjects is true, any qualifying conversions from toField will @@ -1633,15 +1643,15 @@ export namespace Doc { return undefined; }; - const toField = (data: any, excludeEmptyObjects: boolean, title?: string): Opt => { + const toField = (data: unknown, excludeEmptyObjects: boolean, title?: string): Opt => { if (data === null || data === undefined) { return undefined; } if (primitives.includes(typeof data)) { - return data; + return data as FieldType; } if (typeof data === 'object') { - return data instanceof Array ? convertList(data, excludeEmptyObjects) : convertObject(data, excludeEmptyObjects, title, undefined); + return data instanceof Array ? convertList(data, excludeEmptyObjects) : convertObject(data as { [key: string]: FieldType }, excludeEmptyObjects, title, undefined); } throw new Error(`How did ${data} of type ${typeof data} end up in JSON?`); }; @@ -1654,8 +1664,8 @@ export function RTFIsFragment(html: string) { export function GetHrefFromHTML(html: string): string { const parser = new DOMParser(); const parsedHtml = parser.parseFromString(html, 'text/html'); - if (parsedHtml.body.childNodes.length === 1 && parsedHtml.body.childNodes[0].childNodes.length === 1 && (parsedHtml.body.childNodes[0].childNodes[0] as any).href) { - return (parsedHtml.body.childNodes[0].childNodes[0] as any).href; + if (parsedHtml.body.childNodes.length === 1 && parsedHtml.body.childNodes[0].childNodes.length === 1 && (parsedHtml.body.childNodes[0].childNodes[0] as HTMLAnchorElement).href) { + return (parsedHtml.body.childNodes[0].childNodes[0] as HTMLAnchorElement).href; } return ''; } @@ -1675,35 +1685,35 @@ export function IdToDoc(id: string) { return DocCast(DocServer.GetCachedRefField(id)); } // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function idToDoc(id: string): any { +ScriptingGlobals.add(function idToDoc(id: string): Doc { return IdToDoc(id); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function renameEmbedding(doc: any) { +ScriptingGlobals.add(function renameEmbedding(doc: Doc) { return StrCast(doc[DocData].title).replace(/\([0-9]*\)/, '') + `(${doc.proto_embeddingId})`; }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function getProto(doc: any) { +ScriptingGlobals.add(function getProto(doc: Doc) { return Doc.GetProto(doc); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function getDocTemplate(doc?: any) { +ScriptingGlobals.add(function getDocTemplate(doc?: Doc) { return Doc.getDocTemplate(doc); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function getEmbedding(doc: any) { +ScriptingGlobals.add(function getEmbedding(doc: Doc) { return Doc.MakeEmbedding(doc); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function getCopy(doc: any, copyProto: any) { +ScriptingGlobals.add(function getCopy(doc: Doc, copyProto: boolean) { return doc.isTemplateDoc ? Doc.MakeDelegateWithProto(doc) : Doc.MakeCopy(doc, copyProto); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function copyField(field: any) { +ScriptingGlobals.add(function copyField(field: FieldResult) { return Field.Copy(field); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function docList(field: any) { +ScriptingGlobals.add(function docList(field: FieldResult) { return DocListCast(field); }); // eslint-disable-next-line prefer-arrow-callback @@ -1711,11 +1721,11 @@ ScriptingGlobals.add(function addDocToList(doc: Doc, field: string, added: Doc) return Doc.AddDocToList(doc, field, added); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function setInPlace(doc: any, field: any, value: any) { +ScriptingGlobals.add(function setInPlace(doc: Doc, field: string, value: string) { return Doc.SetInPlace(doc, field, value, false); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function sameDocs(doc1: any, doc2: any) { +ScriptingGlobals.add(function sameDocs(doc1: Doc, doc2: Doc) { return Doc.AreProtosEqual(doc1, doc2); }); // eslint-disable-next-line prefer-arrow-callback @@ -1723,7 +1733,7 @@ ScriptingGlobals.add(function assignDoc(doc: Doc, field: string, id: string) { return Doc.assignDocToField(doc, field, id); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function docCastAsync(doc: FieldResult): any { +ScriptingGlobals.add(function docCastAsync(doc: FieldResult): FieldResult { return Cast(doc, Doc); }); // eslint-disable-next-line prefer-arrow-callback @@ -1732,7 +1742,7 @@ ScriptingGlobals.add(function activePresentationItem() { return curPres && DocListCast(curPres[Doc.LayoutFieldKey(curPres)])[NumCast(curPres._itemIndex)]; }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function setDocFilter(container: Doc, key: string, value: any, modifiers: 'match' | 'check' | 'x' | 'remove') { +ScriptingGlobals.add(function setDocFilter(container: Doc, key: string, value: string, modifiers: 'match' | 'check' | 'x' | 'remove') { Doc.setDocFilter(container, key, value, modifiers); }); // eslint-disable-next-line prefer-arrow-callback diff --git a/src/fields/List.ts b/src/fields/List.ts index 38c47d546..22bbcb9ab 100644 --- a/src/fields/List.ts +++ b/src/fields/List.ts @@ -2,33 +2,33 @@ import { action, computed, makeObservable, observable } from 'mobx'; import { alias, list as serializrList, serializable } from 'serializr'; import { ScriptingGlobals } from '../client/util/ScriptingGlobals'; import { Deserializable, afterDocDeserialize, autoObject } from '../client/util/SerializationHelper'; -import { Field, FieldType, StrListCast } from './Doc'; +import { Doc, Field, FieldType, ObjGetRefFields, StrListCast } from './Doc'; import { FieldTuples, Self, SelfProxy } from './DocSymbols'; import { Copy, FieldChanged, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols'; -import { ObjGetRefFields, ObjectField } from './ObjectField'; +import { ObjectField } from './ObjectField'; import { ProxyField } from './Proxy'; import { RefField } from './RefField'; import { containedFieldChangedHandler, deleteProperty, getter, setter } from './util'; function toObjectField(field: FieldType) { - return field instanceof RefField ? new ProxyField(field) : field; + return field instanceof Doc ? new ProxyField(field) : field; } -function toRealField(field: FieldType) { +function toRealField(field: FieldType | undefined) { return field instanceof ProxyField ? field.value : field; } -type StoredType = T extends RefField ? ProxyField : T; +type StoredType = T extends Doc ? ProxyField : T; export const ListFieldName = 'fields'; @Deserializable('list') -class ListImpl extends ObjectField { - static listHandlers: any = { +export class ListImpl extends ObjectField { + static listHandlers = { /// Mutator methods - copyWithin() { + copyWithin: function (this: ListImpl) { throw new Error('copyWithin not supported yet'); }, - fill(value: any, start?: number, end?: number) { + fill: function (this: ListImpl, value: FieldType, start?: number, end?: number) { if (value instanceof RefField) { throw new Error('fill with RefFields not supported yet'); } @@ -36,12 +36,12 @@ class ListImpl extends ObjectField { this[SelfProxy][FieldChanged]?.(); return res; }, - pop(): any { + pop: function (this: ListImpl): FieldType { const field = toRealField(this[Self].__fieldTuples.pop()); this[SelfProxy][FieldChanged]?.(); return field; }, - push: action(function (this: ListImpl, ...itemsIn: any[]) { + push: action(function (this: ListImpl, ...itemsIn: FieldType[]) { const items = itemsIn.map(toObjectField); const list = this[Self]; @@ -58,27 +58,27 @@ class ListImpl extends ObjectField { this[SelfProxy][FieldChanged]?.({ op: '$addToSet', items, length: length + items.length }); return res; }), - reverse() { + reverse: function (this: ListImpl) { const res = this[Self].__fieldTuples.reverse(); this[SelfProxy][FieldChanged]?.(); return res; }, - shift() { + shift: function (this: ListImpl) { const res = toRealField(this[Self].__fieldTuples.shift()); this[SelfProxy][FieldChanged]?.(); return res; }, - sort(cmpFunc: any) { + sort: function (this: ListImpl, cmpFunc: (first: FieldType | undefined, second: FieldType | undefined) => number) { this[Self].__realFields; // coerce retrieving entire array - const res = this[Self].__fieldTuples.sort(cmpFunc ? (first: any, second: any) => cmpFunc(toRealField(first), toRealField(second)) : undefined); + const res = this[Self].__fieldTuples.sort(cmpFunc ? (first: FieldType, second: FieldType) => cmpFunc(toRealField(first), toRealField(second)) : undefined); this[SelfProxy][FieldChanged]?.(); return res; }, - splice: action(function (this: any, start: number, deleteCount: number, ...itemsIn: any[]) { + splice: action(function (this: ListImpl, start: number, deleteCount: number, ...itemsIn: FieldType[]) { this[Self].__realFields; // coerce retrieving entire array const items = itemsIn.map(toObjectField); const list = this[Self]; - const removed = list.__fieldTuples.filter((item: any, i: number) => i >= start && i < start + deleteCount); + const removed = list.__fieldTuples.filter((item: FieldType, i: number) => i >= start && i < start + deleteCount); for (let i = 0; i < items.length; i++) { const item = items[i]; // TODO Error checking to make sure parent doesn't already exist @@ -88,7 +88,7 @@ class ListImpl extends ObjectField { item[FieldChanged] = containedFieldChangedHandler(this, i + start, item); } } - const hintArray: { val: any; index: number }[] = []; + const hintArray: { val: FieldType; index: number }[] = []; for (let i = start; i < start + deleteCount; i++) { hintArray.push({ val: list.__fieldTuples[i], index: i }); } @@ -104,7 +104,7 @@ class ListImpl extends ObjectField { ); return res.map(toRealField); }), - unshift(...itemsIn: any[]) { + unshift: function (this: ListImpl, ...itemsIn: FieldType[]) { const items = itemsIn.map(toObjectField); const list = this[Self]; for (let i = 0; i < items.length; i++) { @@ -121,108 +121,108 @@ class ListImpl extends ObjectField { return res; }, /// Accessor methods - concat: action(function (this: any, ...items: any[]) { + concat: action(function (this: ListImpl, ...items: FieldType[]) { this[Self].__realFields; return this[Self].__fieldTuples.map(toRealField).concat(...items); }), - includes(valueToFind: any, fromIndex: number) { + includes: function (this: ListImpl, valueToFind: FieldType, fromIndex: number) { if (valueToFind instanceof RefField) { return this[Self].__realFields.includes(valueToFind, fromIndex); } return this[Self].__fieldTuples.includes(valueToFind, fromIndex); }, - indexOf(valueToFind: any, fromIndex: number) { + indexOf: function (this: ListImpl, valueToFind: FieldType, fromIndex: number) { if (valueToFind instanceof RefField) { return this[Self].__realFields.indexOf(valueToFind, fromIndex); } return this[Self].__fieldTuples.indexOf(valueToFind, fromIndex); }, - join(separator: any) { + join: function (this: ListImpl, separator: string) { this[Self].__realFields; return this[Self].__fieldTuples.map(toRealField).join(separator); }, - lastElement() { + lastElement: function (this: ListImpl) { return this[Self].__realFields.lastElement(); }, - lastIndexOf(valueToFind: any, fromIndex: number) { + lastIndexOf: function (this: ListImpl, valueToFind: FieldType, fromIndex: number) { if (valueToFind instanceof RefField) { return this[Self].__realFields.lastIndexOf(valueToFind, fromIndex); } return this[Self].__fieldTuples.lastIndexOf(valueToFind, fromIndex); }, - slice(begin: number, end: number) { + slice: function (this: ListImpl, begin: number, end: number) { this[Self].__realFields; return this[Self].__fieldTuples.slice(begin, end).map(toRealField); }, /// Iteration methods - entries() { + entries: function (this: ListImpl) { return this[Self].__realFields.entries(); }, - every(callback: any, thisArg: any) { + every: function (this: ListImpl, callback: (value: FieldType, index: number, array: FieldType[]) => unknown, thisArg: unknown) { return this[Self].__realFields.every(callback, thisArg); // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway. // If we don't want to support the array parameter, we should use this version instead // return this[Self].__fieldTuples.every((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg); }, - filter(callback: any, thisArg: any) { + filter: function (this: ListImpl, callback: (value: FieldType, index: number, array: FieldType[]) => FieldType[], thisArg: unknown) { return this[Self].__realFields.filter(callback, thisArg); // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway. // If we don't want to support the array parameter, we should use this version instead // return this[Self].__fieldTuples.filter((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg); }, - find(callback: any, thisArg: any) { + find: function (this: ListImpl, callback: (value: FieldType, index: number, obj: FieldType[]) => FieldType, thisArg: unknown) { return this[Self].__realFields.find(callback, thisArg); // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway. // If we don't want to support the array parameter, we should use this version instead // return this[Self].__fieldTuples.find((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg); }, - findIndex(callback: any, thisArg: any) { + findIndex: function (this: ListImpl, callback: (value: FieldType, index: number, obj: FieldType[]) => number, thisArg: unknown) { return this[Self].__realFields.findIndex(callback, thisArg); // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway. // If we don't want to support the array parameter, we should use this version instead // return this[Self].__fieldTuples.findIndex((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg); }, - forEach(callback: any, thisArg: any) { + forEach: function (this: ListImpl, callback: (value: FieldType, index: number, array: FieldType[]) => void, thisArg: unknown) { return this[Self].__realFields.forEach(callback, thisArg); // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway. // If we don't want to support the array parameter, we should use this version instead // return this[Self].__fieldTuples.forEach((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg); }, - map(callback: any, thisArg: any) { + map: function (this: ListImpl, callback: (value: FieldType, index: number, array: FieldType[]) => unknown, thisArg: unknown) { return this[Self].__realFields.map(callback, thisArg); // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway. // If we don't want to support the array parameter, we should use this version instead // return this[Self].__fieldTuples.map((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg); }, - reduce(callback: any, initialValue: any) { + reduce: function (this: ListImpl, callback: (previousValue: unknown, currentValue: FieldType, currentIndex: number, array: FieldType[]) => unknown, initialValue: unknown) { return this[Self].__realFields.reduce(callback, initialValue); // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway. // If we don't want to support the array parameter, we should use this version instead // return this[Self].__fieldTuples.reduce((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue); }, - reduceRight(callback: any, initialValue: any) { + reduceRight: function (this: ListImpl, callback: (previousValue: unknown, currentValue: FieldType, currentIndex: number, array: FieldType[]) => unknown, initialValue: unknown) { return this[Self].__realFields.reduceRight(callback, initialValue); // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway. // If we don't want to support the array parameter, we should use this version instead // return this[Self].__fieldTuples.reduceRight((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue); }, - some(callback: any, thisArg: any) { + some: function (this: ListImpl, callback: (value: FieldType, index: number, array: FieldType[]) => boolean, thisArg: unknown) { return this[Self].__realFields.some(callback, thisArg); // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway. // If we don't want to support the array parameter, we should use this version instead // return this[Self].__fieldTuples.some((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg); }, - values() { + values: function (this: ListImpl) { return this[Self].__realFields.values(); }, - [Symbol.iterator]() { + [Symbol.iterator]: function (this: ListImpl) { return this[Self].__realFields.values(); }, }; - static listGetter(target: any, prop: string | symbol, receiver: any): any { + static listGetter(target: ListImpl, prop: string | symbol, receiver: ListImpl): unknown { if (Object.prototype.hasOwnProperty.call(ListImpl.listHandlers, prop)) { - return ListImpl.listHandlers[prop]; + return (ListImpl.listHandlers as { [key: string | symbol]: unknown })[prop]; } return getter(target, prop, receiver); } @@ -251,7 +251,7 @@ class ListImpl extends ObjectField { }, }); // eslint-disable-next-line no-use-before-define - this[SelfProxy] = list as any as List; // bcz: ugh .. don't know how to convince typesecript that list is a List + this[SelfProxy] = list as unknown as List; // bcz: ugh .. don't know how to convince typesecript that list is a List if (fields) { this[SelfProxy].push(...fields); } @@ -260,18 +260,20 @@ class ListImpl extends ObjectField { } [key: number]: T | (T extends RefField ? Promise : never); + [key2: symbol]: unknown; + [key3: string]: unknown; // this requests all ProxyFields at the same time to avoid the overhead // of separate network requests and separate updates to the React dom. @computed private get __realFields() { - const unrequested = this[FieldTuples].filter(f => f instanceof ProxyField && f.needsRequesting).map(f => f as ProxyField); + const unrequested = this[FieldTuples].filter(f => f instanceof ProxyField && f.needsRequesting).map(f => f as ProxyField); // if we find any ProxyFields that don't have a current value, then // start the server request for all of them if (unrequested.length) { const batchPromise = ObjGetRefFields(unrequested.map(p => p.fieldId)); // as soon as we get the fields from the server, set all the list values in one // action to generate one React dom update. - const allSetPromise = batchPromise.then(action(pfields => unrequested.map(toReq => toReq.setValue(pfields[toReq.fieldId])))); + const allSetPromise = batchPromise.then(action(pfields => unrequested.map(toReq => toReq.setValue(pfields.get(toReq.fieldId))))); // we also have to mark all lists items with this promise so that any calls to them // will await the batch request and return the requested field value. unrequested.forEach(p => p.setExternalValuePromise(allSetPromise)); @@ -280,11 +282,11 @@ class ListImpl extends ObjectField { } @serializable(alias(ListFieldName, serializrList(autoObject(), { afterDeserialize: afterDocDeserialize }))) - private get __fieldTuples() { + get __fieldTuples() { return this[FieldTuples]; } - private set __fieldTuples(value) { + set __fieldTuples(value) { this[FieldTuples] = value; Object.keys(value).forEach(key => { const item = value[Number(key)]; @@ -297,7 +299,7 @@ class ListImpl extends ObjectField { [Copy]() { const copiedData = this[Self].__fieldTuples.map(f => (f instanceof ObjectField ? f[Copy]() : f)); - const deepCopy = new ListImpl(copiedData as any); + const deepCopy = new ListImpl(copiedData as T[]); return deepCopy; } @@ -309,19 +311,19 @@ class ListImpl extends ObjectField { private [SelfProxy]: List; // also used in utils.ts even though it won't be found using find all references [ToScriptString]() { return `new List(${this[ToJavascriptString]()})`; } // prettier-ignore - [ToJavascriptString]() { return `[${(this as any).map((field: any) => Field.toScriptString(field))}]`; } // prettier-ignore - [ToString]() { return `[${(this as any).map((field: any) => Field.toString(field))}]`; } // prettier-ignore + [ToJavascriptString]() { return `[${(this[FieldTuples]).map(field => Field.toScriptString(field))}]`; } // prettier-ignore + [ToString]() { return `[${(this[FieldTuples]).map(field => Field.toString(field))}]`; } // prettier-ignore } // declare List as a type so you can use it in type declarations, e.g., { l: List, ...} export type List = ListImpl & (T | (T extends RefField ? Promise : never))[]; -// decalre List as a value so you can invoke 'new' on it, e.g., new List() +// decalre List as a value so you can invoke 'new' on it, e.g., new List() (since List IS ListImpl, we can safely cast the 'new' return value to return List) // eslint-disable-next-line no-redeclare -export const List: { new (fields?: T[]): List } = ListImpl as any; +export const List: { new (fields?: T[]): List } = ListImpl as unknown as { new (fields?: T[]): List }; ScriptingGlobals.add('List', List); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function compareLists(l1: any, l2: any) { +ScriptingGlobals.add(function compareLists(l1: List, l2: List) { const L1 = StrListCast(l1); const L2 = StrListCast(l2); return !L1 && !L2 ? true : L1 && L2 && L1.length === L2.length && L2.reduce((p, v) => p && L1.includes(v), true); diff --git a/src/fields/ObjectField.ts b/src/fields/ObjectField.ts index 231086262..21c4af608 100644 --- a/src/fields/ObjectField.ts +++ b/src/fields/ObjectField.ts @@ -2,13 +2,21 @@ import { ScriptingGlobals } from '../client/util/ScriptingGlobals'; import { Copy, FieldChanged, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols'; import { RefField } from './RefField'; +export type serverOpType = { + $set?: { [key: string]: unknown }; // + $unset?: { [key: string]: unknown }; + $remFromSet?: { [key: string]: unknown }; + $addToSet?: { [key: string]: unknown }; + length?: number; +}; export abstract class ObjectField { // prettier-ignore public [FieldChanged]?: (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; // eslint-disable-next-line no-use-before-define items: FieldType[] | undefined; length: number | undefined; - hint?: any }, serverOp?: any) => void; + hint?: unknown }, + serverOp?: serverOpType) => void; // eslint-disable-next-line no-use-before-define public [Parent]?: RefField | ObjectField; abstract [Copy](): ObjectField; @@ -22,15 +30,4 @@ export abstract class ObjectField { } export type FieldType = number | string | boolean | ObjectField | RefField; // bcz: hack for now .. must match the type definition in Doc.ts .. put here to avoid import cycles -// eslint-disable-next-line import/no-mutable-exports -export let ObjGetRefField: (id: string, force?: boolean) => Promise; -// eslint-disable-next-line import/no-mutable-exports -export let ObjGetRefFields: (ids: string[]) => Promise<{ [id: string]: RefField | undefined }>; - -export function SetObjGetRefField(func: (id: string, force?: boolean) => Promise) { - ObjGetRefField = func; -} -export function SetObjGetRefFields(func: (ids: string[]) => Promise<{ [id: string]: RefField | undefined }>) { - ObjGetRefFields = func; -} ScriptingGlobals.add(ObjectField); diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts index 83b5672b3..48c336e60 100644 --- a/src/fields/Proxy.ts +++ b/src/fields/Proxy.ts @@ -3,18 +3,19 @@ import { primitive, serializable } from 'serializr'; import { DocServer } from '../client/DocServer'; import { scriptingGlobal } from '../client/util/ScriptingGlobals'; import { Deserializable } from '../client/util/SerializationHelper'; -import { Field, FieldWaiting, Opt } from './Doc'; +import { Doc, Field, FieldWaiting, Opt } from './Doc'; import { Copy, Id, ToJavascriptString, ToScriptString, ToString, ToValue } from './FieldSymbols'; import { ObjectField } from './ObjectField'; -import { RefField } from './RefField'; -function deserializeProxy(field: any) { +type serializedProxyType = { cache: { field: unknown; p: undefined | Promise }; fieldId: string }; + +function deserializeProxy(field: serializedProxyType) { if (!field.cache.field) { - field.cache = { field: DocServer.GetCachedRefField(field.fieldId) as any, p: undefined }; + field.cache = { field: DocServer.GetCachedRefField(field.fieldId), p: undefined }; } } -@Deserializable('proxy', deserializeProxy) -export class ProxyField extends ObjectField { +@Deserializable('proxy', (obj: unknown) => deserializeProxy(obj as serializedProxyType)) +export class ProxyField extends ObjectField { constructor(); constructor(value: T); constructor(fieldId: string); @@ -39,10 +40,10 @@ export class ProxyField extends ObjectField { } [ToJavascriptString]() { - return Field.toScriptString(this[ToValue]()?.value); + return Field.toScriptString(this[ToValue]()?.value as T); } [ToScriptString]() { - return Field.toScriptString(this[ToValue]()?.value); // not sure this is quite right since it doesn't recreate a proxy field, but better than 'invalid' ? + return Field.toScriptString(this[ToValue]()?.value as T); // not sure this is quite right since it doesn't recreate a proxy field, but better than 'invalid' ? } [ToString]() { return Field.toString(this[ToValue]()?.value); @@ -83,7 +84,7 @@ export class ProxyField extends ObjectField { return !!(!this.cache.field && !this.failed && !this._cache.p && !DocServer.GetCachedRefField(this.fieldId)); } - setExternalValuePromise(externalValuePromise: Promise) { + setExternalValuePromise(externalValuePromise: Promise) { this.cache.p = externalValuePromise.then(() => this.value) as FieldWaiting; } @action @@ -94,7 +95,7 @@ export class ProxyField extends ObjectField { } } -// eslint-disable-next-line no-redeclare +// eslint-disable-next-line no-redeclare, @typescript-eslint/no-namespace export namespace ProxyField { let useProxy = true; export function DisableProxyFields() { @@ -114,7 +115,7 @@ export namespace ProxyField { } } - export function toValue(value: any) { + export function toValue(value: { value: unknown }) { if (useProxy) { return { value: value.value }; } @@ -123,10 +124,10 @@ export namespace ProxyField { } // eslint-disable-next-line no-use-before-define -function prefetchValue(proxy: PrefetchProxy) { - return proxy.value as any; +function prefetchValue(proxy: PrefetchProxy) { + return proxy.value as Promise; } @scriptingGlobal -@Deserializable('prefetch_proxy', prefetchValue) -export class PrefetchProxy extends ProxyField {} +@Deserializable('prefetch_proxy', (obj:unknown) => prefetchValue(obj as PrefetchProxy)) +export class PrefetchProxy extends ProxyField {} diff --git a/src/fields/RefField.ts b/src/fields/RefField.ts index 1ce81368a..4ef2a6748 100644 --- a/src/fields/RefField.ts +++ b/src/fields/RefField.ts @@ -14,7 +14,7 @@ export abstract class RefField { this[Id] = this.__id; } - protected [HandleUpdate]?(diff: any): void | Promise; + protected [HandleUpdate]?(diff: unknown): void | Promise; abstract [ToJavascriptString](): string; abstract [ToScriptString](): string; diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts index 8fe365ac2..582c09f29 100644 --- a/src/fields/ScriptField.ts +++ b/src/fields/ScriptField.ts @@ -1,15 +1,15 @@ import { action, makeObservable, observable } from 'mobx'; import { computedFn } from 'mobx-utils'; import { PropSchema, SKIP, createSimpleSchema, custom, map, object, primitive, serializable } from 'serializr'; -import { numberRange } from '../Utils'; +import { emptyFunction, numberRange } from '../Utils'; import { GPTCallType, gptAPICall } from '../client/apis/gpt/GPT'; import { CompileScript, CompiledScript, ScriptOptions, Transformer } from '../client/util/Scripting'; import { ScriptingGlobals, scriptingGlobal } from '../client/util/ScriptingGlobals'; import { Deserializable, autoObject } from '../client/util/SerializationHelper'; -import { Doc, Field, FieldType, FieldResult, Opt } from './Doc'; +import { Doc, Field, FieldType, FieldResult, ObjGetRefField, Opt } from './Doc'; import { Copy, FieldChanged, Id, ToJavascriptString, ToScriptString, ToString, ToValue } from './FieldSymbols'; import { List } from './List'; -import { ObjGetRefField, ObjectField } from './ObjectField'; +import { ObjectField } from './ObjectField'; import { Cast, StrCast } from './Types'; function optional(propSchema: PropSchema) { @@ -20,7 +20,7 @@ function optional(propSchema: PropSchema) { } return SKIP; }, - (jsonValue: any, context: any, oldValue: any, callback: (err: any, result: any) => void) => { + (jsonValue, context, oldValue, callback) => { if (jsonValue !== undefined) { return propSchema.deserializer(jsonValue, callback, context, oldValue); } @@ -63,7 +63,7 @@ function finalizeScript(scriptIn: ScriptField) { async function deserializeScript(scriptIn: ScriptField) { const script = scriptIn; if (script.captures) { - const captured: any = {}; + const captured: { [key: string]: undefined | string | number | boolean | Doc } = {}; (script.script.options as ScriptOptions).capturedVariables = captured; Promise.all( script.captures.map(async capture => { @@ -85,7 +85,7 @@ async function deserializeScript(scriptIn: ScriptField) { } @scriptingGlobal -@Deserializable('script', deserializeScript) +@Deserializable('script', (obj: unknown) => deserializeScript(obj as ScriptField)) export class ScriptField extends ObjectField { @serializable readonly rawscript: string | undefined; @@ -114,7 +114,7 @@ export class ScriptField extends ObjectField { const captured = script?.options?.capturedVariables; if (captured) { - this.captures = new List(Object.keys(captured).map(key => key + ':' + (captured[key] instanceof Doc ? 'ID->' + (captured[key] as Doc)[Id] : captured[key].toString()))); + this.captures = new List(Object.keys(captured).map(key => key + ':' + (captured[key] instanceof Doc ? 'ID->' + (captured[key] as Doc)[Id] : captured[key]?.toString()))); } this.rawscript = rawscript; this.setterscript = setterscript; @@ -186,7 +186,7 @@ export class ScriptField extends ObjectField { } @scriptingGlobal -@Deserializable('computed', deserializeScript) +@Deserializable('computed', (obj: unknown) => deserializeScript(obj as ComputedField)) export class ComputedField extends ScriptField { static undefined = '__undefined'; static useComputed = true; @@ -221,7 +221,7 @@ export class ComputedField extends ScriptField { _readOnly_: true, }, console.log - ).result + ).result as FieldResult )(); // prettier-ignore return this._lastComputedResult; }; @@ -239,7 +239,7 @@ export class ComputedField extends ScriptField { public static MakeInterpolatedNumber(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number, defaultVal: Opt) { if (!doc[`${fieldKey}_indexed`]) { - const flist = new List(numberRange(curTimecode + 1).map(() => undefined) as any as number[]); + const flist = new List(numberRange(curTimecode + 1).map(emptyFunction) as unknown as number[]); flist[curTimecode] = Cast(doc[fieldKey], 'number', null); doc[`${fieldKey}_indexed`] = flist; } @@ -249,7 +249,7 @@ export class ComputedField extends ScriptField { } public static MakeInterpolatedString(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) { if (!doc[`${fieldKey}_`]) { - const flist = new List(numberRange(curTimecode + 1).map(() => undefined) as any as string[]); + const flist = new List(numberRange(curTimecode + 1).map(emptyFunction) as unknown as string[]); flist[curTimecode] = StrCast(doc[fieldKey]); doc[`${fieldKey}_indexed`] = flist; } @@ -260,7 +260,7 @@ export class ComputedField extends ScriptField { public static MakeInterpolatedDataField(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) { if (doc[`${fieldKey}`] instanceof List) return undefined; if (!doc[`${fieldKey}_indexed`]) { - const flist = new List(numberRange(curTimecode + 1).map(() => undefined) as any as FieldType[]); + const flist = new List(numberRange(curTimecode + 1).map(emptyFunction) as unknown as FieldType[]); flist[curTimecode] = Field.Copy(doc[fieldKey]); doc[`${fieldKey}_indexed`] = flist; } @@ -278,7 +278,7 @@ export class ComputedField extends ScriptField { ScriptingGlobals.add( // eslint-disable-next-line prefer-arrow-callback - function setIndexVal(list: any[], index: number, value: any) { + function setIndexVal(list: FieldResult[], index: number, value: FieldType) { while (list.length <= index) list.push(undefined); list[index] = value; }, @@ -288,7 +288,7 @@ ScriptingGlobals.add( ScriptingGlobals.add( // eslint-disable-next-line prefer-arrow-callback - function getIndexVal(list: any[], index: number, defaultVal: Opt = undefined) { + function getIndexVal(list: unknown[], index: number, defaultVal: Opt = undefined) { return list?.reduce((p, x, i) => ((i <= index && x !== undefined) || p === undefined ? x : p), defaultVal); }, 'returns the value at a given index of a list', diff --git a/src/fields/util.ts b/src/fields/util.ts index a6499c3e3..69ece82a2 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -7,7 +7,7 @@ import { UndoManager } from '../client/util/UndoManager'; import { Doc, DocListCast, FieldType, FieldResult, HierarchyMapping, ReverseHierarchyMap, StrListCast, aclLevel, updateCachedAcls } from './Doc'; import { AclAdmin, AclAugment, AclEdit, AclPrivate, DirectLinks, DocAcl, DocData, DocLayout, FieldKeys, ForceServerWrite, Height, Initializing, SelfProxy, UpdatingFromServer, Width } from './DocSymbols'; import { FieldChanged, Id, Parent, ToValue } from './FieldSymbols'; -import { List } from './List'; +import { List, ListImpl } from './List'; import { ObjectField } from './ObjectField'; import { PrefetchProxy, ProxyField } from './Proxy'; import { RefField } from './RefField'; @@ -44,15 +44,23 @@ export function TraceMobx() { tracing && trace(); } -export const _propSetterCB = new Map void) | undefined>(); +export const _propSetterCB = new Map void) | undefined>(); -const _setterImpl = action((target: any, prop: string | symbol | number, valueIn: any, receiver: any): boolean => { +const _setterImpl = action((target: Doc | ListImpl, prop: string | symbol | number, valueIn: unknown, receiver: Doc | ListImpl): boolean => { + if (target instanceof ListImpl) { + if (typeof prop !== 'symbol' && +prop == prop) { + target[SelfProxy].splice(+prop, 1, valueIn as FieldType); + } else { + target[prop] = valueIn as FieldType; + } + return true; + } if (SerializationHelper.IsSerializing() || typeof prop === 'symbol') { - target[prop] = valueIn; + target[prop] = valueIn as FieldResult; return true; } - let value = valueIn?.[SelfProxy] ?? valueIn; // convert any Doc type values to Proxy's + let value = (valueIn as Doc | ListImpl)?.[SelfProxy] ?? valueIn; // convert any Doc type values to Proxy's const curValue = target.__fieldTuples[prop]; if (curValue === value || (curValue instanceof ProxyField && value instanceof RefField && curValue.fieldId === value[Id])) { @@ -60,7 +68,7 @@ const _setterImpl = action((target: any, prop: string | symbol | number, valueIn // curValue should get filled in with value if it isn't already filled in, in case we fetched the referenced field some other way return true; } - if (value instanceof RefField) { + if (value instanceof Doc) { value = new ProxyField(value); } @@ -77,7 +85,7 @@ const _setterImpl = action((target: any, prop: string | symbol | number, valueIn delete curValue[FieldChanged]; } - if (typeof prop === 'string' && _propSetterCB.has(prop)) _propSetterCB.get(prop)!(target[SelfProxy], value); + if (typeof prop === 'string' && _propSetterCB.has(prop)) _propSetterCB.get(prop)!(target[SelfProxy], value as FieldType); // eslint-disable-next-line no-use-before-define const effectiveAcl = GetEffectiveAcl(target); @@ -108,16 +116,17 @@ const _setterImpl = action((target: any, prop: string | symbol | number, valueIn (target as Doc|ObjectField)[FieldChanged]?.(undefined, { $unset: { ['fields.' + prop]: '' } }); else (target as Doc|ObjectField)[FieldChanged]?.(undefined, { $set: { ['fields.' + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) :value}}); if (prop === 'author' || prop.toString().startsWith('acl_')) updateCachedAcls(target); - } else { + } else if (receiver instanceof Doc) { DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue); } !receiver[Initializing] && + receiver instanceof Doc && !StrListCast(receiver.undoIgnoreFields).includes(prop.toString()) && (!receiver[UpdatingFromServer] || receiver[ForceServerWrite]) && UndoManager.AddEvent( { redo: () => { - receiver[prop] = value; + receiver[prop] = value as FieldType; }, undo: () => { const wasUpdate = receiver[UpdatingFromServer]; @@ -137,7 +146,7 @@ const _setterImpl = action((target: any, prop: string | symbol | number, valueIn return true; }); -let _setter: (target: any, prop: string | symbol | number, value: any, receiver: any) => boolean = _setterImpl; +let _setter: (target: Doc | ListImpl, prop: string | symbol | number, value: FieldType | undefined, receiver: Doc | ListImpl) => boolean = _setterImpl; export function makeReadOnly() { _setter = _readOnlySetter; @@ -156,18 +165,18 @@ export function denormalizeEmail(email: string) { // return acl from cache or cache the acl and return. // eslint-disable-next-line no-use-before-define -const getEffectiveAclCache = computedFn((target: any, user?: string) => getEffectiveAcl(target, user), true); +const getEffectiveAclCache = computedFn((target: Doc | ListImpl, user?: string) => getEffectiveAcl(target, user), true); /** * Calculates the effective access right to a document for the current user. */ -export function GetEffectiveAcl(target: any, user?: string): symbol { +export function GetEffectiveAcl(target: Doc | ListImpl, user?: string): symbol { if (!target) return AclPrivate; if (target[UpdatingFromServer] || ClientUtils.CurrentUserEmail() === 'guest') return AclAdmin; return getEffectiveAclCache(target, user); // all changes received from the server must be processed as Admin. return this directly so that the acls aren't cached (UpdatingFromServer is not observable) } -export function GetPropAcl(target: any, prop: string | symbol | number) { +export function GetPropAcl(target: Doc | ListImpl, prop: string | symbol | number) { if (typeof prop === 'symbol' || target[UpdatingFromServer]) return AclAdmin; // requesting the UpdatingFromServer prop or AclSym must always go through to keep the local DB consistent if (prop && DocServer.IsPlaygroundField(prop.toString())) return AclEdit; // playground props are always editable return GetEffectiveAcl(target); @@ -182,7 +191,8 @@ export function GetCachedGroupByName(name: string) { export function SetCachedGroups(groups: string[]) { runInAction(() => cachedGroups.push(...groups)); } -function getEffectiveAcl(target: any, user?: string): symbol { +function getEffectiveAcl(target: Doc | ListImpl, user?: string): symbol { + if (target instanceof ListImpl) return AclAdmin; const targetAcls = target[DocAcl]; if (targetAcls?.acl_Me === AclAdmin || GetCachedGroupByName('Admin')) return AclAdmin; @@ -287,14 +297,14 @@ export function inheritParentAcls(parent: Doc, child: Doc, layoutOnly: boolean) * @param prop * @param propSetter */ -export function SetPropSetterCb(prop: string, propSetter: ((target: any, value: any) => void) | undefined) { +export function SetPropSetterCb(prop: string, propSetter: ((target: Doc, value: FieldType) => void) | undefined) { _propSetterCB.set(prop, propSetter); } // // target should be either a Doc or ListImpl. receiver should be a Proxy Or List. // -export function setter(target: any, inProp: string | symbol | number, value: any, receiver: any): boolean { +export function setter(target: ListImpl | Doc, inProp: string | symbol | number, value: unknown, receiver: Doc | ListImpl): boolean { if (!inProp) { console.log('WARNING: trying to set an empty property. This should be fixed. '); return false; @@ -303,12 +313,12 @@ export function setter(target: any, inProp: string | symbol | number, value: any const effectiveAcl = inProp === 'constructor' || typeof inProp === 'symbol' ? AclAdmin : GetPropAcl(target, prop); if (effectiveAcl !== AclEdit && effectiveAcl !== AclAugment && effectiveAcl !== AclAdmin) return true; // if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't - if (typeof prop === 'string' && prop.startsWith('acl_') && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined].includes(value))) return true; + if (typeof prop === 'string' && prop.startsWith('acl_') && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined].includes(value as SharingPermissions))) return true; if (typeof prop === 'string' && prop !== '__id' && prop !== '__fieldTuples' && prop.startsWith('_')) { if (!prop.startsWith('__')) prop = prop.substring(1); - if (target.__LAYOUT__) { - target.__LAYOUT__[prop] = value; + if (target.__LAYOUT__ instanceof Doc) { + target.__LAYOUT__[prop] = value as FieldResult; return true; } } @@ -317,10 +327,10 @@ export function setter(target: any, inProp: string | symbol | number, value: any return !!ScriptCast(target.__fieldTuples[prop])?.setterscript?.run({ self: target[SelfProxy], this: target[SelfProxy], value }).success; } } - return _setter(target, prop, value, receiver); + return _setter(target, prop, value as FieldType, receiver); } -function getFieldImpl(target: any, prop: string | number, proxy: any, ignoreProto: boolean = false): any { +function getFieldImpl(target: ListImpl | Doc, prop: string | number, proxy: ListImpl | Doc, ignoreProto: boolean = false): FieldType { const field = target.__fieldTuples[prop]; const value = field?.[ToValue]?.(proxy); // converts ComputedFields to values, or unpacks ProxyFields into Proxys if (value) return value.value; @@ -332,7 +342,7 @@ function getFieldImpl(target: any, prop: string | number, proxy: any, ignoreProt } return field; } -export function getter(target: any, prop: string | symbol, proxy: any): any { +export function getter(target: Doc | ListImpl, prop: string | symbol, proxy: ListImpl | Doc): unknown { // prettier-ignore switch (prop) { case 'then' : return undefined; @@ -352,19 +362,23 @@ export function getter(target: any, prop: string | symbol, proxy: any): any { } const layoutProp = prop.startsWith('_') ? prop.substring(1) : undefined; - if (layoutProp && target.__LAYOUT__) return target.__LAYOUT__[layoutProp]; + if (layoutProp && target.__LAYOUT__) return (target.__LAYOUT__ as Doc)[layoutProp]; return getFieldImpl(target, layoutProp ?? prop, proxy); } -export function getField(target: any, prop: string | number, ignoreProto: boolean = false): any { - return getFieldImpl(target, prop, target[SelfProxy], ignoreProto); +export function getField(target: ListImpl | Doc, prop: string | number, ignoreProto: boolean = false): unknown { + return getFieldImpl(target, prop, target[SelfProxy] as Doc, ignoreProto); } -export function deleteProperty(target: any, prop: string | number | symbol) { +export function deleteProperty(target: Doc | ListImpl, prop: string | number | symbol) { if (typeof prop === 'symbol') { delete target[prop]; } else { - target[SelfProxy][prop] = undefined; + if (target instanceof Doc) { + target[SelfProxy][prop] = undefined; + } else if (+prop == prop) { + target[SelfProxy].splice(+prop, 1); + } } return true; } @@ -378,39 +392,42 @@ export function deleteProperty(target: any, prop: string | number | symbol) { // were replaced. Based on this specification, an Undo event is setup that will save enough information about the ObjectField to be // able to undo and redo the partial change. // -export function containedFieldChangedHandler(container: List | Doc, prop: string | number, liveContainedField: ObjectField) { +export function containedFieldChangedHandler(container: ListImpl | Doc, prop: string | number, liveContainedField: ObjectField) { let lastValue: FieldResult = liveContainedField instanceof ObjectField ? ObjectField.MakeCopy(liveContainedField) : liveContainedField; - return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: any } /* , dummyServerOp?: any */) => { + return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: (FieldType & { value?: FieldType })[] | undefined; length: number | undefined; hint?: unknown } /* , dummyServerOp?: any */) => { const serializeItems = () => ({ __type: 'list', fields: diff?.items?.map((item: FieldType) => SerializationHelper.Serialize(item)) }); // prettier-ignore const serverOp = diff?.op === '$addToSet' ? { $addToSet: { ['fields.' + prop]: serializeItems() }, length: diff.length } : diff?.op === '$remFromSet' ? { $remFromSet: { ['fields.' + prop]: serializeItems(), hint: diff.hint}, length: diff.length } - : { $set: { ['fields.' + prop]: liveContainedField ? SerializationHelper.Serialize(liveContainedField) : undefined } }; + : { $set: { ['fields.' + prop]: liveContainedField ? SerializationHelper.Serialize(liveContainedField) as FieldType : undefined } }; if (!(container instanceof Doc) || !container[UpdatingFromServer]) { - const prevValue = ObjectField.MakeCopy(lastValue as List); + const cont = container as { [key: string | number]: FieldType }; + const prevValue = ObjectField.MakeCopy(lastValue as List); lastValue = ObjectField.MakeCopy(liveContainedField); const newValue = ObjectField.MakeCopy(liveContainedField); if (diff?.op === '$addToSet') { UndoManager.AddEvent( { redo: () => { + const contList = cont[prop] as List; // console.log('redo $add: ' + prop, diff.items); // bcz: uncomment to log undo - (container as any)[prop as any]?.push(...((diff.items || [])?.map((item: any) => item.value ?? item) ?? [])); - lastValue = ObjectField.MakeCopy((container as any)[prop as any]); + contList?.push(...((diff.items || [])?.map(item => item.value ?? item) ?? [])); + lastValue = ObjectField.MakeCopy(contList); }, undo: action(() => { + const contList = cont[prop] as List; // console.log('undo $add: ' + prop, diff.items); // bcz: uncomment to log undo - diff.items?.forEach((item: any) => { + diff.items?.forEach(item => { const ind = item instanceof SchemaHeaderField // - ? (container as any)[prop as any]?.findIndex((ele: any) => ele instanceof SchemaHeaderField && ele.heading === item.heading) - : (container as any)[prop as any]?.indexOf(item.value ?? item); - ind !== undefined && ind !== -1 && (container as any)[prop as any]?.splice(ind, 1); + ? contList?.findIndex(ele => ele instanceof SchemaHeaderField && ele.heading === item.heading) + : contList?.indexOf(item.value ?? item); + ind !== undefined && ind !== -1 && (cont[prop] as List)?.splice(ind, 1); }); - lastValue = ObjectField.MakeCopy((container as any)[prop as any]); + lastValue = ObjectField.MakeCopy(contList); }), prop: 'add ' + (diff.items?.length ?? 0) + ' items to list', }, @@ -420,48 +437,53 @@ export function containedFieldChangedHandler(container: List | Doc, p UndoManager.AddEvent( { redo: action(() => { + const contList = cont[prop] as List; // console.log('redo $rem: ' + prop, diff.items); // bcz: uncomment to log undo - diff.items?.forEach((item: any) => { + diff.items?.forEach(item => { const ind = item instanceof SchemaHeaderField // - ? (container as any)[prop as any]?.findIndex((ele: any) => ele instanceof SchemaHeaderField && ele.heading === item.heading) - : (container as any)[prop as any]?.indexOf(item.value ?? item); - ind !== undefined && ind !== -1 && (container as any)[prop as any]?.splice(ind, 1); + ? contList?.findIndex(ele => ele instanceof SchemaHeaderField && ele.heading === item.heading) + : contList?.indexOf(item.value ?? item); + ind !== undefined && ind !== -1 && contList?.splice(ind, 1); }); - lastValue = ObjectField.MakeCopy((container as any)[prop as any]); + lastValue = ObjectField.MakeCopy(contList); }), undo: () => { + const contList = cont[prop] as List; + const prevList = prevValue as List; // console.log('undo $rem: ' + prop, diff.items); // bcz: uncomment to log undo - diff.items?.forEach((item: any) => { + diff.items?.forEach(item => { if (item instanceof SchemaHeaderField) { - const ind = (prevValue as List).findIndex((ele: any) => ele instanceof SchemaHeaderField && ele.heading === item.heading); - ind !== -1 && (container as any)[prop as any].findIndex((ele: any) => ele instanceof SchemaHeaderField && ele.heading === item.heading) === -1 && (container as any)[prop as any].splice(ind, 0, item); + const ind = prevList.findIndex(ele => ele instanceof SchemaHeaderField && ele.heading === item.heading); + ind !== -1 && contList.findIndex(ele => ele instanceof SchemaHeaderField && ele.heading === item.heading) === -1 && contList.splice(ind, 0, item); } else { - const ind = (prevValue as List).indexOf(item.value ?? item); - ind !== -1 && (container as any)[prop as any].indexOf(item.value ?? item) === -1 && (container as any)[prop as any].splice(ind, 0, item); + const ind = prevList.indexOf(item.value ?? item); + ind !== -1 && contList.indexOf(item.value ?? item) === -1 && (cont[prop] as List).splice(ind, 0, item); } }); - lastValue = ObjectField.MakeCopy((container as any)[prop as any]); + lastValue = ObjectField.MakeCopy(contList); }, - prop: 'remove ' + (diff.items?.length ?? 0) + ' items from list(' + ((container as any)?.title ?? '') + ':' + prop + ')', + prop: 'remove ' + (diff.items?.length ?? 0) + ' items from list(' + (cont?.title ?? '') + ':' + prop + ')', }, diff?.items ); } else { const setFieldVal = (val: FieldType | undefined) => { - container instanceof Doc ? (container[prop as string] = val) : (container[prop as number] = val as FieldType); + container instanceof Doc ? (container[prop] = val) : (container[prop as number] = val as FieldType); }; UndoManager.AddEvent( { redo: () => { // console.log('redo list: ' + prop, fieldVal()); // bcz: uncomment to log undo - setFieldVal(newValue instanceof ObjectField ? ObjectField.MakeCopy(newValue) : undefined); - lastValue = ObjectField.MakeCopy((container as any)[prop as any]); + setFieldVal(ObjectField.MakeCopy(newValue)); + const containerProp = cont[prop]; + lastValue = containerProp instanceof ObjectField && ObjectField.MakeCopy(containerProp); }, undo: () => { // console.log('undo list: ' + prop, fieldVal()); // bcz: uncomment to log undo - setFieldVal(prevValue instanceof ObjectField ? ObjectField.MakeCopy(prevValue) : undefined); - lastValue = ObjectField.MakeCopy((container as any)[prop as any]); + setFieldVal(ObjectField.MakeCopy(prevValue)); + const containerProp = cont[prop]; + lastValue = containerProp instanceof ObjectField && ObjectField.MakeCopy(containerProp); }, prop: 'set list field', }, diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index 7a1e35636..36c0d6a4d 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; @@ -16,6 +14,7 @@ import { listSpec } from '../fields/Schema'; import { Cast } from '../fields/Types'; import './ImageUpload.scss'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const { DFLT_IMAGE_NATIVE_DIM } = require('../client/views/global/globalCssVariables.module.scss'); // prettier-ignore export interface ImageUploadProps { diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index d8ba89fdb..4f37c45a8 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -265,7 +265,6 @@ export class MobileInterface extends React.Component { this._menuListView = this._homeDoc._type_collection === 'stacking' ? true : false; Doc.ActiveTool = InkTool.None; // ink should intially be set to none Doc.UserDoc().activeMobile = this._homeDoc; // active mobile set to home - AudioBox.Enabled = true; // remove double click to avoid mobile zoom in document.removeEventListener('dblclick', this.onReactDoubleClick); diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts index 28323d62f..bf5475042 100644 --- a/src/pen-gestures/GestureUtils.ts +++ b/src/pen-gestures/GestureUtils.ts @@ -2,14 +2,15 @@ import { Rect } from 'react-measure'; import { Gestures, PointData } from './GestureTypes'; import { NDollarRecognizer } from './ndollar'; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace GestureUtils { export class GestureEvent { readonly gesture: Gestures; readonly points: PointData[]; readonly bounds: Rect; - readonly text?: any; + readonly text?: string; - constructor(gesture: Gestures, points: PointData[], bounds: Rect, text?: any) { + constructor(gesture: Gestures, points: PointData[], bounds: Rect, text?: string) { this.gesture = gesture; this.points = points; this.bounds = bounds; diff --git a/src/server/ApiManagers/GooglePhotosManager.ts b/src/server/ApiManagers/GooglePhotosManager.ts index 5feb25fd4..0970dee81 100644 --- a/src/server/ApiManagers/GooglePhotosManager.ts +++ b/src/server/ApiManagers/GooglePhotosManager.ts @@ -139,13 +139,13 @@ // const completed: Opt[] = []; // for (const { baseUrl } of mediaItems) { // // start by getting the content size of the remote image -// const results = await DashUploadUtils.InspectImage(baseUrl); -// if (results instanceof Error) { +// const result = await DashUploadUtils.InspectImage(baseUrl); +// if (result instanceof Error) { // // if something went wrong here, we can't hope to upload it, so just move on to the next // failed++; // continue; // } -// const { contentSize, ...attributes } = results; +// const { contentSize, ...attributes } = result; // // check to see if we have uploaded a Google user content image *specifically via this route* already // // that has this exact content size // const found: Opt = await Database.Auxiliary.QueryUploadHistory(contentSize); diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts index 4cb3d8baf..b2624f654 100644 --- a/src/server/ApiManagers/UploadManager.ts +++ b/src/server/ApiManagers/UploadManager.ts @@ -144,7 +144,7 @@ export default class UploadManager extends ApiManager { ids[id] = uuid.v4(); return ids[id]; }; - const mapFn = (docIn: any) => { + const mapFn = (docIn: { id: string; fields: any[] }) => { const doc = docIn; if (doc.id) { doc.id = getId(doc.id); @@ -170,10 +170,10 @@ export default class UploadManager extends ApiManager { mapFn(field); } else if (typeof field === 'string') { const re = /("(?:dataD|d)ocumentId"\s*:\s*")([\w-]*)"/g; - doc.fields[key] = (field as any).replace(re, (match: any, p1: string, p2: string) => `${p1}${getId(p2)}"`); + doc.fields[key] = field.replace(re, (match: string, p1: string, p2: string) => `${p1}${getId(p2)}"`); } else if (field.__type === 'RichTextField') { const re = /("href"\s*:\s*")(.*?)"/g; - field.Data = field.Data.replace(re, (match: any, p1: string, p2: string) => `${p1}${getId(p2)}"`); + field.Data = field.Data.replace(re, (match: string, p1: string, p2: string) => `${p1}${getId(p2)}"`); } } }; @@ -192,7 +192,7 @@ export default class UploadManager extends ApiManager { if (!f) continue; const path2 = f[0]; // what about the rest of the array? are we guaranteed only one value is set? const zip = new AdmZip(path2.filepath); - zip.getEntries().forEach((entry: any) => { + zip.getEntries().forEach(entry => { const entryName = entry.entryName.replace(/%%%/g, '/'); if (!entryName.startsWith('files/')) { return; @@ -245,7 +245,7 @@ export default class UploadManager extends ApiManager { } } SolrManager.update(); - res.send(JSON.stringify({ id, docids, linkids } || 'error')); + res.send(JSON.stringify({ id, docids, linkids }) || 'error'); } catch (e) { console.log(e); } @@ -282,8 +282,8 @@ export default class UploadManager extends ApiManager { const serverPath = serverPathToFile(Directory.images, ''); const regex = new RegExp(`${deleteFiles}.*`); fs.readdirSync(serverPath) - .filter((f: any) => regex.test(f)) - .map((f: any) => fs.unlinkSync(serverPath + f)); + .filter(f => regex.test(f)) + .map(f => fs.unlinkSync(serverPath + f)); } imageDataUri.outputFile(uri, serverPathToFile(Directory.images, InjectSize(filename, origSuffix))).then((savedName: string) => { const ext = path.extname(savedName).toLowerCase(); diff --git a/src/server/DashStats.ts b/src/server/DashStats.ts index 808d2c6f2..6b9fb8971 100644 --- a/src/server/DashStats.ts +++ b/src/server/DashStats.ts @@ -9,6 +9,7 @@ import { socketMap, timeMap, userOperations } from './SocketData'; * This includes time connected, number of operations, and * the rate of their operations */ +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DashStats { export const SAMPLING_INTERVAL = 1000; // in milliseconds (ms) - Time interval to update the frontend. export const RATE_INTERVAL = 10; // in seconds (s) - Used to calculate rate diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index 08cea1de5..5e58db103 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -1,6 +1,7 @@ import axios from 'axios'; +import { spawn, exec } from 'child_process'; import { green, red } from 'colors'; -import { ExifImage } from 'exif'; +import { ExifData, ExifImage } from 'exif'; import * as exifr from 'exifr'; import * as ffmpeg from 'fluent-ffmpeg'; import * as formidable from 'formidable'; @@ -18,13 +19,11 @@ import { Duplex, Stream } from 'stream'; import { Utils } from '../Utils'; import { createIfNotExists } from './ActionUtilities'; import { AzureManager } from './ApiManagers/AzureManager'; -import { ParsedPDF } from './PdfTypes'; import { AcceptableMedia, Upload } from './SharedMediaTypes'; import { Directory, clientPathToFile, filesDirectory, pathToDirectory, publicDirectory, serverPathToFile } from './SocketData'; import { resolvedServerUrl } from './server_Initialization'; -const { spawn } = require('child_process'); -const { exec } = require('child_process'); +// eslint-disable-next-line @typescript-eslint/no-var-requires const requestImageSize = require('../client/util/request-image-size'); export enum SizeSuffix { @@ -48,6 +47,7 @@ function usingAzure() { return process.env.USE_AZURE === 'true'; } +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DashUploadUtils { export interface Size { width: number; @@ -111,7 +111,7 @@ export namespace DashUploadUtils { // .outputOptions('-c copy') // .videoCodec("copy") .save(outputFilePath) - .on('error', (err: any) => { + .on('error', err => { console.log(err); reject(); }) @@ -130,8 +130,8 @@ export namespace DashUploadUtils { } function resolveExistingFile(name: string, pat: string, directory: Directory, mimetype?: string | null, duration?: number, rawText?: string): Upload.FileResponse { - const data = { size: 0, filepath: pat, name, type: mimetype ?? '', originalFilename: name, newFilename: path.basename(pat), mimetype: mimetype || null, hashAlgorithm: false as any }; - const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), mimetype: mimetype || null, toJson: () => undefined as any }) }; + const data = { size: 0, filepath: pat, name, type: mimetype ?? '', originalFilename: name, newFilename: path.basename(pat), mimetype: mimetype || null, hashAlgorithm: false as falsetype }; + const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), mimetype: mimetype || null }) }; return { source: file || null, result: { @@ -184,11 +184,10 @@ export namespace DashUploadUtils { const parseExifData = async (source: string) => { const image = await request.get(source, { encoding: null }); - const { /* data, */ error } = await new Promise<{ data: any; error: any }>(resolve => { + const { /* data, */ error } = await new Promise<{ data: ExifData; error: string | undefined }>(resolve => { // eslint-disable-next-line no-new new ExifImage({ image }, (exifError, data) => { - const reason = (exifError as any)?.code; - resolve({ data, error: reason }); + resolve({ data, error: exifError?.message }); }); }); return error ? { data: undefined, error } : { data: await exifr.parse(image), error }; @@ -252,11 +251,12 @@ export namespace DashUploadUtils { }; // Use the request library to parse out file level image information in the headers - const { headers } = await new Promise((resolve, reject) => { - request.head(resolvedUrl, (error, res) => (error ? reject(error) : resolve(res))); + const headerResult = await new Promise<{ headers: { [key: string]: string } }>((resolve, reject) => { + request.head(resolvedUrl, (error, res) => (error ? reject(error) : resolve(res as { headers: { [key: string]: string } }))); }).catch(e => { console.log('Error processing headers: ', e); }); + const { headers } = headerResult !== null && typeof headerResult === 'object' ? headerResult : { headers: {} as { [key: string]: string } }; try { // Compute the native width and height ofthe image with an npm module @@ -272,9 +272,9 @@ export namespace DashUploadUtils { filename, ...results, }; - } catch (e: any) { + } catch (e: unknown) { console.log(e); - return e; + return new Error(e ? e.toString?.() : 'unkown error'); } }; @@ -331,7 +331,7 @@ export namespace DashUploadUtils { )); // prettier-ignore return Jimp.read(imgBuffer) - .then(async (imgIn: any) => { + .then(async imgIn => { let img = imgIn; await Promise.all( sizes.filter(({ width }) => width).map(({ width, suffix }) => { img = img.resize(width, Jimp.AUTO).write(outputPath(suffix)); @@ -339,7 +339,7 @@ export namespace DashUploadUtils { } )); // prettier-ignore return writtenFiles; }) - .catch((e: any) => { + .catch(e => { console.log('ERROR' + e); return writtenFiles; }); @@ -432,15 +432,17 @@ export namespace DashUploadUtils { * 4) the content type of the image, i.e. image/(jpeg | png | ...) */ export const UploadImage = async (source: string, filename?: string, prefix: string = ''): Promise => { - const metadata = await InspectImage(source); - if (metadata instanceof Error) { - return { name: metadata.name, message: metadata.message }; + const result = await InspectImage(source); + if (result instanceof Error) { + return { name: result.name, message: result.message }; } - const outputFile = filename || metadata.filename || ''; + const outputFile = filename || result.filename || ''; - return UploadInspectedImage(metadata, outputFile, prefix); + return UploadInspectedImage(result, outputFile, prefix); }; + type md5 = 'md5'; + type falsetype = false; export function uploadYoutube(videoId: string, overwriteId: string): Promise { return new Promise>(res => { const name = videoId; @@ -448,6 +450,7 @@ export namespace DashUploadUtils { const finalPath = serverPathToFile(Directory.videos, filepath); if (existsSync(finalPath)) { uploadProgress.set(overwriteId, 'computing duration'); + // eslint-disable-next-line @typescript-eslint/no-explicit-any exec(`yt-dlp -o ${finalPath} "https://www.youtube.com/watch?v=${videoId}" --get-duration`, (error: any, stdout: any /* , stderr: any */) => { const time = Array.from(stdout.trim().split(':')).reverse(); const duration = (time.length > 2 ? Number(time[2]) * 1000 * 60 : 0) + (time.length > 1 ? Number(time[1]) * 60 : 0) + (time.length > 0 ? Number(time[0]) : 0); @@ -457,14 +460,17 @@ export namespace DashUploadUtils { uploadProgress.set(overwriteId, 'starting download'); const ytdlp = spawn(`yt-dlp`, ['-o', filepath, `https://www.youtube.com/watch?v=${videoId}`, '--max-filesize', '100M', '-f', 'mp4']); + // eslint-disable-next-line @typescript-eslint/no-explicit-any ytdlp.stdout.on('data', (data: any) => uploadProgress.set(overwriteId, data.toString())); let errors = ''; + // eslint-disable-next-line @typescript-eslint/no-explicit-any ytdlp.stderr.on('data', (data: any) => { uploadProgress.set(overwriteId, 'error:' + data.toString()); errors = data.toString(); }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any ytdlp.on('exit', (code: any) => { if (code) { res({ @@ -484,8 +490,8 @@ export namespace DashUploadUtils { exec(`yt-dlp-o ${filepath} "https://www.youtube.com/watch?v=${videoId}" --get-duration`, (/* error: any, stdout: any, stderr: any */) => { // const time = Array.from(stdout.trim().split(':')).reverse(); // const duration = (time.length > 2 ? Number(time[2]) * 1000 * 60 : 0) + (time.length > 1 ? Number(time[1]) * 60 : 0) + (time.length > 0 ? Number(time[0]) : 0); - const data = { size: 0, filepath, name, mimetype: 'video', originalFilename: name, newFilename: name, hashAlgorithm: 'md5' as 'md5', type: 'video/mp4' }; - const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), toJson: () => undefined as any }) }; + const data = { size: 0, filepath, name, mimetype: 'video', originalFilename: name, newFilename: name, hashAlgorithm: 'md5' as md5, type: 'video/mp4' }; + const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date() }) }; MoveParsedFile(file, Directory.videos).then(output => res(output)); }); } @@ -517,15 +523,15 @@ export namespace DashUploadUtils { }); } const dataBuffer = readFileSync(file.filepath); - const result: ParsedPDF | any = await parse(dataBuffer).catch((e: any) => e); - if (!result.code) { + const result: parse.Result = await parse(dataBuffer).catch(e => e); + if (result) { await new Promise((resolve, reject) => { const writeStream = createWriteStream(serverPathToFile(Directory.text, textFilename)); writeStream.write(result?.text, error => (error ? reject(error) : resolve())); }); return MoveParsedFile(file, Directory.pdfs, undefined, result?.text, undefined, fileKey); } - return { source: file, result: { name: 'faile pdf pupload', message: `Could not upload (${file.originalFilename}).${result.message}` } }; + return { source: file, result: { name: 'faile pdf pupload', message: `Could not upload (${file.originalFilename}).${result}` } }; } async function UploadCsv(file: File) { @@ -563,7 +569,7 @@ export namespace DashUploadUtils { .videoCodec('copy') // this will copy the data instead of reencode it .save(vidFile.filepath.replace('.mkv', '.mp4')) .on('end', res) - .on('error', (e: any) => console.log(e)); + .on('error', console.log); }); vidFile.filepath = vidFile.filepath.replace('.mkv', '.mp4'); format = '.mp4'; @@ -571,8 +577,9 @@ export namespace DashUploadUtils { if (format.includes('quicktime')) { let abort = false; await new Promise(res => { - ffmpeg.ffprobe(vidFile.filepath, (err: any, metadata: any) => { - if (metadata.streams.some((stream: any) => stream.codec_name === 'hevc')) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ffmpeg.ffprobe(vidFile.filepath, (err: any, metadata: ffmpeg.FfprobeData) => { + if (metadata.streams.some(stream => stream.codec_name === 'hevc')) { abort = true; } res(); diff --git a/src/server/SharedMediaTypes.ts b/src/server/SharedMediaTypes.ts index 8ae13454e..680db9cd0 100644 --- a/src/server/SharedMediaTypes.ts +++ b/src/server/SharedMediaTypes.ts @@ -1,6 +1,7 @@ import { ExifData } from 'exif'; import { File } from 'formidable'; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace AcceptableMedia { export const gifs = ['.gif']; export const pngs = ['.png']; @@ -18,6 +19,7 @@ export enum AudioAnnoState { playing = 'playing', } +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Upload { export function isImageInformation(uploadResponse: Upload.FileInformation): uploadResponse is Upload.ImageInformation { return 'nativeWidth' in uploadResponse; @@ -36,7 +38,7 @@ export namespace Upload { duration?: number; } export interface EnrichedExifData { - data: ExifData & ExifData['gps']; + data: ExifData & ExifData['gps'] & { Orientation?: string }; error?: string; } export interface InspectionResults { diff --git a/src/server/index.ts b/src/server/index.ts index 3151c2975..3e0d86814 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -29,7 +29,6 @@ import initializeServer from './server_Initialization'; dotenv.config(); export const onWindows = process.platform === 'win32'; -// eslint-disable-next-line import/no-mutable-exports export let sessionAgent: AppliedSessionAgent; /** diff --git a/src/server/websocket.ts b/src/server/websocket.ts index cece8a1b7..821607df5 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -16,12 +16,11 @@ import YoutubeApi from './apis/youtube/youtubeApiSample'; import { initializeGuest } from './authentication/DashUserModel'; import { Database } from './database'; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace WebSocket { let CurUser: string | undefined; - // eslint-disable-next-line import/no-mutable-exports export let _socket: Socket; - // eslint-disable-next-line import/no-mutable-exports - export let _disconnect: Function; + export let _disconnect: () => void; export const clients: { [key: string]: Client } = {}; function processGesturePoints(socket: Socket, content: GestureContent) { diff --git a/webpack.config.js b/webpack.config.js index 58df9a57d..9c74bf24e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,8 +1,7 @@ -/* eslint-disable node/no-unpublished-require */ +/* eslint-disable @typescript-eslint/no-var-requires */ const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); -// eslint-disable-next-line import/no-extraneous-dependencies // const ESLintPlugin = require('eslint-webpack-plugin'); // const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const { parsed } = require('dotenv').config(); -- cgit v1.2.3-70-g09d2 From 762ac2bf354e4cc2c4b15f42502da939f5061646 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 9 Aug 2024 16:48:18 -0400 Subject: a bunch more typing fixes. --- src/client/util/BranchingTrailManager.tsx | 14 +- src/client/util/reportManager/ReportManager.scss | 12 +- src/client/views/ContextMenu.scss | 37 ++--- src/client/views/ContextMenu.tsx | 32 ++-- src/client/views/ContextMenuItem.tsx | 180 ++++++--------------- src/client/views/DictationOverlay.tsx | 2 +- src/client/views/DocViewUtils.ts | 1 + src/client/views/DocumentButtonBar.tsx | 11 +- src/client/views/DocumentDecorations.tsx | 23 +-- src/client/views/EditableView.tsx | 26 +-- src/client/views/ExtractColors.ts | 2 +- src/client/views/FieldsDropdown.tsx | 8 +- src/client/views/GlobalKeyHandler.ts | 4 +- src/client/views/KeyphraseQueryView.scss | 8 - src/client/views/KeyphraseQueryView.tsx | 32 ---- src/client/views/MainViewModal.tsx | 2 - src/client/views/ObservableReactComponent.tsx | 14 +- src/client/views/PreviewCursor.tsx | 51 +++--- src/client/views/PropertiesButtons.tsx | 19 +-- .../views/PropertiesDocBacklinksSelector.tsx | 2 +- src/client/views/PropertiesDocContextSelector.tsx | 7 +- src/client/views/PropertiesSection.tsx | 4 +- src/client/views/PropertiesView.tsx | 102 ++++++------ src/client/views/SidebarAnnos.tsx | 10 +- src/client/views/StyleProvider.tsx | 11 +- src/client/views/TemplateMenu.tsx | 3 +- src/client/views/UndoStack.tsx | 2 - .../views/collections/CollectionCarouselView.tsx | 3 +- src/client/views/collections/CollectionMenu.tsx | 44 ++--- .../views/collections/CollectionTreeView.tsx | 4 +- src/client/views/collections/CollectionView.tsx | 12 +- src/client/views/global/globalScripts.ts | 32 ++-- src/client/views/linking/LinkMenu.tsx | 4 +- src/client/views/linking/LinkMenuGroup.tsx | 2 - src/client/views/linking/LinkMenuItem.tsx | 20 ++- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 2 +- src/client/views/nodes/DocumentContentsView.tsx | 4 +- src/client/views/nodes/FunctionPlotBox.tsx | 20 +-- src/client/views/nodes/KeyValueBox.tsx | 3 +- src/client/views/nodes/KeyValuePair.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 6 +- .../views/nodes/formattedText/EquationView.tsx | 10 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 6 +- 43 files changed, 333 insertions(+), 460 deletions(-) delete mode 100644 src/client/views/KeyphraseQueryView.scss delete mode 100644 src/client/views/KeyphraseQueryView.tsx diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx index 119d103c5..65336812d 100644 --- a/src/client/util/BranchingTrailManager.tsx +++ b/src/client/util/BranchingTrailManager.tsx @@ -15,18 +15,18 @@ export class BranchingTrailManager extends React.Component { public static Instance: BranchingTrailManager; // stack of the history - @observable private slideHistoryStack: String[] = []; - @observable private containsSet: Set = new Set(); + @observable private slideHistoryStack: string[] = []; + @observable private containsSet: Set = new Set(); // docId to Doc map - @observable private docIdToDocMap: Map = new Map(); + @observable private docIdToDocMap: Map = new Map(); // prev pres to copmare with - @observable private prevPresId: String | null = null; - @action setPrevPres = action((newId: String | null) => { + @observable private prevPresId: string | null = null; + @action setPrevPres = action((newId: string | null) => { this.prevPresId = newId; }); - constructor(props: any) { + constructor(props: object) { super(props); makeObservable(this); if (!BranchingTrailManager.Instance) { @@ -48,7 +48,7 @@ export class BranchingTrailManager extends React.Component { // Doc.AddToMyOverlay(hi); }; - @action setSlideHistoryStack = action((newArr: String[]) => { + @action setSlideHistoryStack = action((newArr: string[]) => { this.slideHistoryStack = newArr; }); diff --git a/src/client/util/reportManager/ReportManager.scss b/src/client/util/reportManager/ReportManager.scss index d82d7fdeb..fd343ac8e 100644 --- a/src/client/util/reportManager/ReportManager.scss +++ b/src/client/util/reportManager/ReportManager.scss @@ -96,12 +96,12 @@ transition: all 0.2s ease; background: transparent; - &:hover { - // border-bottom-color: $text-gray; - } - &:focus { - // border-bottom-color: #4476f7; - } + // &:hover { + // // border-bottom-color: $text-gray; + // } + // &:focus { + // // border-bottom-color: #4476f7; + // } } // View issues diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss index 232362c5c..4aaf2d03b 100644 --- a/src/client/views/ContextMenu.scss +++ b/src/client/views/ContextMenu.scss @@ -38,7 +38,12 @@ background: whitesmoke; } -.contextMenu-item { +.contextMenuItem-Selected { + background: lightgoldenrodyellow; + border-style: none; +} + +.contextMenuItem { // width: 11vw; //10vw height: 25px; //2vh display: flex; //comment out to allow search icon to be inline with search text @@ -59,7 +64,7 @@ text-transform: uppercase; padding-right: 30px; - .contextMenu-item-background { + .contextMenuItem-background { width: 100%; height: 100%; position: absolute; @@ -69,13 +74,7 @@ filter: opacity(0); } - &:hover { - .contextMenu-item-background { - filter: opacity(0.2) !important; - } - } - - .contextMenu-item-icon-background { + .contextMenuItem-icon { pointer-events: all; background-color: transparent; width: 35px; @@ -103,6 +102,8 @@ letter-spacing: 1px; text-transform: uppercase; padding-right: 30px; + align-items: center; + align-self: center; } .contextMenu-item:hover { @@ -115,11 +116,6 @@ cursor: pointer; } -.contextMenu-itemSelected { - background: lightgoldenrodyellow; - border-style: none; -} - .contextMenu-group { // width: 11vw; //10vw height: 30px; //2vh @@ -145,23 +141,24 @@ padding-left: 5px; } -.contextMenu-inlineMenu { - // border-top: solid 1px; //TODO:glr clean -} - .contextMenu-description { margin-left: 5px; text-align: left; display: inline; //need this? } -.search-icon { +.contextMenu-search { margin: 10px; + display: flex; + .contextMenu-searchIcon { + margin-right: 5px; + } } -.search { +.contextMenu-searchInput { margin-left: 10px; padding-left: 10px; border: solid black 1px; border-radius: 5px; + width: 100%; } diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 05634f376..5edb5fc0d 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -8,7 +8,7 @@ import * as React from 'react'; import { DivHeight, DivWidth } from '../../ClientUtils'; import { SnappingManager } from '../util/SnappingManager'; import './ContextMenu.scss'; -import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from './ContextMenuItem'; +import { ContextMenuItem, ContextMenuProps } from './ContextMenuItem'; import { ObservableReactComponent } from './ObservableReactComponent'; @observer @@ -148,13 +148,13 @@ export class ContextMenu extends ObservableReactComponent<{ noexpand?: boolean } return wasOpen; }; - @computed get filteredItems(): (OriginalMenuProps | string[])[] { + @computed get filteredItems(): (ContextMenuProps | string[])[] { const searchString = this._searchString.toLowerCase().split(' '); const matches = (descriptions: string[]) => searchString.every(s => descriptions.some(desc => desc.toLowerCase().includes(s))); const flattenItems = (items: ContextMenuProps[], groupFunc: (groupName: string) => string[]) => { - let eles: (OriginalMenuProps | string[])[] = []; + let eles: (ContextMenuProps | string[])[] = []; - const leaves: OriginalMenuProps[] = []; + const leaves: ContextMenuProps[] = []; items.forEach(item => { const { description } = item; const path = groupFunc(description); @@ -165,7 +165,7 @@ export class ContextMenu extends ObservableReactComponent<{ noexpand?: boolean } eles = eles.concat(children); } } else if (matches(path)) { - leaves.push(item as OriginalMenuProps); + leaves.push(item as ContextMenuProps); } }); @@ -176,8 +176,8 @@ export class ContextMenu extends ObservableReactComponent<{ noexpand?: boolean } return flattenItems(this._items.slice(), name => [name]); } - @computed get flatItems(): OriginalMenuProps[] { - return this.filteredItems.filter(item => !Array.isArray(item)) as OriginalMenuProps[]; + @computed get flatItems(): ContextMenuProps[] { + return this.filteredItems.filter(item => !Array.isArray(item)) as ContextMenuProps[]; } @computed get menuItems() { @@ -228,21 +228,11 @@ export class ContextMenu extends ObservableReactComponent<{ noexpand?: boolean } color: SnappingManager.userColor, }}> {!this.itemsNeedSearch ? null : ( - - + + - + )} {this.menuItems} @@ -264,7 +254,7 @@ export class ContextMenu extends ObservableReactComponent<{ noexpand?: boolean } e.preventDefault(); } else if (e.key === 'Enter' || e.key === 'Tab') { const item = this.flatItems[this._selectedIndex]; - if (item) { + if (item.event) { item.event({ x: this.pageX, y: this.pageY }); } else { // if (this._searchString.startsWith(this._defaultPrefix)) { diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 3b87ea58b..5b4eb704b 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -8,32 +8,27 @@ import { SnappingManager } from '../util/SnappingManager'; import { UndoManager } from '../util/UndoManager'; import { ObservableReactComponent } from './ObservableReactComponent'; -export interface OriginalMenuProps { +export interface ContextMenuProps { + icon: IconProp | JSX.Element; description: string; - event: (stuff?: unknown) => void; - undoable?: boolean; - noexpand?: boolean; - subitems?: ContextMenuProps[]; - icon: IconProp | JSX.Element; // maybe should be optional (icon?) - closeMenu?: () => void; -} - -export interface SubmenuProps { - description: string; - // eslint-disable-next-line no-use-before-define - subitems: ContextMenuProps[]; - noexpand?: boolean; addDivider?: boolean; - icon: IconProp; // maybe should be optional (icon?) closeMenu?: () => void; -} -export type ContextMenuProps = OriginalMenuProps | SubmenuProps; + subitems?: ContextMenuProps[]; + noexpand?: boolean; // whether to render the submenu items as a flyout from this item, or inline in place of this item + + undoable?: boolean; // whether to wrap the event callback in an UndoBatch or not + event?: (stuff?: unknown) => void; +} @observer export class ContextMenuItem extends ObservableReactComponent { - @observable private _items: Array = []; - @observable private overItem = false; + static readonly HOVER_TIMEOUT = 100; + _hoverTimeout?: NodeJS.Timeout; + _overPosY = 0; + _overPosX = 0; + @observable _items: ContextMenuProps[] = []; + @observable _overItem = false; constructor(props: ContextMenuProps & { selected?: boolean }) { super(props); @@ -41,132 +36,63 @@ export class ContextMenuItem extends ObservableReactComponent { - this._items.length = 0; - }); - if ((this._props as SubmenuProps)?.subitems) { - (this._props as SubmenuProps).subitems?.forEach(i => runInAction(() => this._items.push(i))); - } + runInAction(() => this._items.push(...(this._props.subitems ?? []))); } handleEvent = async (e: React.MouseEvent) => { - if ('event' in this._props) { + if (this._props.event) { this._props.closeMenu?.(); - const batch = this._props.undoable !== false ? UndoManager.StartBatch(`Click Menu item: ${this._props.description}`) : undefined; + const batch = this._props.undoable ? UndoManager.StartBatch(`Click Menu item: ${this._props.description}`) : undefined; await this._props.event({ x: e.clientX, y: e.clientY }); batch?.end(); } }; - currentTimeout?: NodeJS.Timeout | undefined; - static readonly timeout = 300; - _overPosY = 0; - _overPosX = 0; + setOverItem = (over: boolean) => { + this._hoverTimeout = setTimeout( action(() => { this._overItem = over; }), ContextMenuItem.HOVER_TIMEOUT ); // prettier-ignore + }; + onPointerEnter = (e: React.MouseEvent) => { - if (this.currentTimeout) { - clearTimeout(this.currentTimeout); - this.currentTimeout = undefined; - } - if (this.overItem) { - return; - } + this._hoverTimeout && clearTimeout(this._hoverTimeout); this._overPosY = e.clientY; this._overPosX = e.clientX; - this.currentTimeout = setTimeout( - action(() => { - this.overItem = true; - }), - ContextMenuItem.timeout - ); + !this._overItem && this.setOverItem(true); }; onPointerLeave = () => { - if (this.currentTimeout) { - clearTimeout(this.currentTimeout); - this.currentTimeout = undefined; - } - if (!this.overItem) { - return; - } - this.currentTimeout = setTimeout( - action(() => { - this.overItem = false; - }), - ContextMenuItem.timeout - ); + this._hoverTimeout && clearTimeout(this._hoverTimeout); + this._overItem && this.setOverItem(false); }; - isJSXElement(val: unknown): val is JSX.Element { - return React.isValidElement(val); - } + renderItem = (submenu: JSX.Element[]) => { + const alignItems = this._overPosY < window.innerHeight / 3 ? 'flex-start' : this._overPosY > (window.innerHeight * 2) / 3 ? 'flex-end' : 'center'; + const marginTop = this._overPosY < window.innerHeight / 3 ? '20px' : this._overPosY > (window.innerHeight * 2) / 3 ? '-20px' : ''; + const marginLeft = window.innerWidth - this._overPosX - 50 > 0 ? '90%' : '20%'; - render() { - if ('event' in this._props) { - return ( -
- {this._props.icon ? {this.isJSXElement(this._props.icon) ? this._props.icon : } : null} -
{this._props.description.replace(':', '')}
-
-
- ); - } - if ('subitems' in this._props) { - const where = !this.overItem ? '' : this._overPosY < window.innerHeight / 3 ? 'flex-start' : this._overPosY > (window.innerHeight * 2) / 3 ? 'flex-end' : 'center'; - const marginTop = !this.overItem ? '' : this._overPosY < window.innerHeight / 3 ? '20px' : this._overPosY > (window.innerHeight * 2) / 3 ? '-20px' : ''; + return ( +
+
+ + {React.isValidElement(this._props.icon) ? this._props.icon : this._props.icon ? : null} + +
{this._props.description}
+ {!submenu.length ? null : ( + !this._overItem ? + : ( +
+ {submenu} +
+ ) + )} +
+ ); // prettier-ignore + }; - // here - const submenu = !this.overItem ? null : ( -
0 ? '90%' : '20%', - marginTop, - background: SnappingManager.userBackgroundColor, - }}> - {this._items.map(prop => ( - - ))} -
- ); - if (!(this._props as SubmenuProps).noexpand) { - return ( -
- {this._items.map(prop => ( - - ))} -
- ); - } - return ( -
- {this._props.icon ? ( - - - - ) : null} -
- {this._props.description} - -
-
- {submenu} -
- ); - } - return null; + render() { + const submenu = this._items.map(prop => ); + return this.props.event || this._props.noexpand ? this.renderItem(submenu) :
{submenu}
; } } diff --git a/src/client/views/DictationOverlay.tsx b/src/client/views/DictationOverlay.tsx index b242acdba..e33049d3b 100644 --- a/src/client/views/DictationOverlay.tsx +++ b/src/client/views/DictationOverlay.tsx @@ -17,7 +17,7 @@ export class DictationOverlay extends React.Component { // eslint-disable-next-line react/no-unused-class-component-methods public hasActiveModal = false; - constructor(props: any) { + constructor(props: object) { super(props); makeObservable(this); DictationOverlay.Instance = this; diff --git a/src/client/views/DocViewUtils.ts b/src/client/views/DocViewUtils.ts index 1f5f29c7e..49a30aa08 100644 --- a/src/client/views/DocViewUtils.ts +++ b/src/client/views/DocViewUtils.ts @@ -6,6 +6,7 @@ import { Doc, SetActiveAudioLinker } from '../../fields/Doc'; import { DocUtils } from '../documents/DocUtils'; import { FieldViewProps } from './nodes/FieldView'; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DocViewUtils { export const ActiveRecordings: { props: FieldViewProps; getAnchor: (addAsAnnotation: boolean) => Doc }[] = []; diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 487868169..b778a4fb9 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -1,6 +1,3 @@ -/* eslint-disable jsx-a11y/control-has-associated-label */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { IconLookup, IconProp } from '@fortawesome/fontawesome-svg-core'; import { faCalendarDays } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -20,7 +17,7 @@ import { DictationManager } from '../util/DictationManager'; import { DragManager } from '../util/DragManager'; import { dropActionType } from '../util/DropActionTypes'; import { SharingManager } from '../util/SharingManager'; -import { UndoManager, undoBatch } from '../util/UndoManager'; +import { UndoManager, undoable } from '../util/UndoManager'; import './DocumentButtonBar.scss'; import { ObservableReactComponent } from './ObservableReactComponent'; import { PinProps } from './PinFuncs'; @@ -33,12 +30,12 @@ import { OpenWhere } from './nodes/OpenWhere'; import { DashFieldView } from './nodes/formattedText/DashFieldView'; @observer -export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (DocumentView | undefined)[]; stack?: any }> { +export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (DocumentView | undefined)[]; stack?: unknown }> { private _dragRef = React.createRef(); // eslint-disable-next-line no-use-before-define public static Instance: DocumentButtonBar; - constructor(props: any) { + constructor(props: { views: () => (DocumentView | undefined)[]; stack?: unknown }) { super(props); makeObservable(this); DocumentButtonBar.Instance = this; @@ -83,7 +80,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
this._props.views().map(view => view?.toggleFollowLink(undefined, false)))}> + onClick={undoable(() => this._props.views().map(view => view?.toggleFollowLink(undefined, false)), 'follow link')}>
{followBtn( true, diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 93c3e3338..68970223a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -34,6 +34,7 @@ import { DocumentView } from './nodes/DocumentView'; import { ImageBox } from './nodes/ImageBox'; import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; interface DocumentDecorationsProps { PanelWidth: number; @@ -145,7 +146,7 @@ export class DocumentDecorations extends ObservableReactComponent { if (e.key === 'Enter') { e.stopPropagation(); - (e.target as any).blur(); + (e.target as HTMLElement).blur?.(); } }; @@ -239,7 +240,7 @@ export class DocumentDecorations extends ObservableReactComponent DragManager.StartWindowDrag?.(e, [DocumentView.SelectedDocs().lastElement()]) ?? false, emptyFunction, this.onMaximizeClick, false, false); e.stopPropagation(); }; - onMaximizeClick = (e: any): void => { + onMaximizeClick = (e: PointerEvent): void => { const selView = DocumentView.Selected()[0]; if (selView) { if (e.ctrlKey) { @@ -349,8 +350,10 @@ export class DocumentDecorations extends ObservableReactComponent // return false to keep getting events - this.setRotateCenter(seldocview, [this.rotCenter[0] + delta[0], this.rotCenter[1] + delta[1]]) as any as boolean, + (moveEv: PointerEvent, down: number[], delta: number[]) => { + this.setRotateCenter(seldocview, [this.rotCenter[0] + delta[0], this.rotCenter[1] + delta[1]]); + return false; + }, action(() => { this._isRotating = false; }), // upEvent action(() => { seldocview.Document._rotation_centerX = seldocview.Document._rotation_centerY = 0; }), true @@ -430,7 +433,7 @@ export class DocumentDecorations extends ObservableReactComponent this.resizeView(docView, refPt, scaleAspect, { dragHdl, ctrlKey:e.ctrlKey })); // prettier-ignore - await new Promise(res => { setTimeout(() => { res(this._interactionLock = undefined)})}); + await new Promise(res => { setTimeout(() => { res(this._interactionLock = undefined)})}); }); // prettier-ignore return false; @@ -681,10 +684,10 @@ export class DocumentDecorations extends ObservableReactComponent void), click: undefined | ((e: any) => void), title: string) => ( + const topBtn = (key: string, icon: IconProp, pointerDown: undefined | ((e: React.PointerEvent) => void), click: undefined | ((e: PointerEvent) => void), title: string) => ( {title}
} placement="top"> -
e.preventDefault()} onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => click!(clickEv)))}> - +
e.preventDefault()} onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => click?.(clickEv)))}> +
); diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 684b948af..e02e39b8b 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -1,10 +1,7 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { action, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import * as Autosuggest from 'react-autosuggest'; -import { ObjectField } from '../../fields/ObjectField'; import './EditableView.scss'; import { DocumentIconContainer } from './nodes/DocumentIcon'; import { FieldView, FieldViewProps } from './nodes/FieldView'; @@ -29,7 +26,7 @@ export interface EditableProps { /** * The contents to render when not editing */ - contents: any; + contents: string; fieldContents?: FieldViewProps; fontStyle?: string; fontSize?: number; @@ -41,8 +38,8 @@ export interface EditableProps { autosuggestProps?: { resetValue: () => void; value: string; - onChange: (e: React.ChangeEvent, { newValue }: { newValue: string }) => void; - autosuggestProps: Autosuggest.AutosuggestProps; + onChange: (e: React.FormEvent, { newValue }: { newValue: string }) => void; + autosuggestProps: Autosuggest.AutosuggestProps; }; oneLine?: boolean; // whether to display the editable view as a single input line or as a textarea allowCRs?: boolean; // can carriage returns be entered @@ -112,8 +109,8 @@ export class EditableView extends ObservableReactComponent { } onChange = (e: React.ChangeEvent) => { - const targVal = (e.target as any).value; - if (!(targVal.startsWith(':=') || targVal.startsWith('='))) { + const targVal = (e.target as HTMLSelectElement).value; + if (!(targVal?.startsWith(':=') || targVal?.startsWith('='))) { this._overlayDisposer?.(); this._overlayDisposer = undefined; } else if (!this._overlayDisposer) { @@ -230,13 +227,11 @@ export class EditableView extends ObservableReactComponent { className: 'editableView-input', onKeyDown: this.onKeyDown, autoFocus: true, - // @ts-ignore - onBlur: e => this.finalizeEdit(e.currentTarget.value, false, true, false), + onBlur: e => this.finalizeEdit((e.currentTarget as HTMLSelectElement).value, false, true, false), onPointerDown: this.stopPropagation, onClick: this.stopPropagation, onPointerUp: this.stopPropagation, value: this._props.autosuggestProps.value, - // @ts-ignore onChange: this._props.autosuggestProps.onChange, }} /> @@ -248,7 +243,6 @@ export class EditableView extends ObservableReactComponent { placeholder={this._props.placeholder} onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)} defaultValue={this._props.GetValue()} - // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus onChange={this.onChange} onKeyDown={this.onKeyDown} @@ -264,7 +258,6 @@ export class EditableView extends ObservableReactComponent { placeholder={this._props.placeholder} onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)} defaultValue={this._props.GetValue()} - // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus onChange={this.onChange} onKeyDown={this.onKeyDown} @@ -288,7 +281,7 @@ export class EditableView extends ObservableReactComponent { ); } setTimeout(() => this._props.autosuggestProps?.resetValue()); - return this._props.contents instanceof ObjectField ? null : ( + return (
{ fontStyle: this._props.fontStyle, fontSize: this._props.fontSize, }}> - { - // eslint-disable-next-line react/jsx-props-no-spreading - this._props.fieldContents ? : this.props.contents ? this._props.contents?.valueOf() : '' - } + {this._props.fieldContents ? : this._props.contents ? this._props.contents?.valueOf() : ''}
); diff --git a/src/client/views/ExtractColors.ts b/src/client/views/ExtractColors.ts index f6928c52a..eee1d3a04 100644 --- a/src/client/views/ExtractColors.ts +++ b/src/client/views/ExtractColors.ts @@ -126,7 +126,7 @@ export class ExtractColors { let hue = 0; let saturation = 0; - let lightness = intensity; + const lightness = intensity; if (area !== 0) { saturation = area / (1 - Math.abs(2 * intensity - 1)); diff --git a/src/client/views/FieldsDropdown.tsx b/src/client/views/FieldsDropdown.tsx index 0ea0ebd83..407031b40 100644 --- a/src/client/views/FieldsDropdown.tsx +++ b/src/client/views/FieldsDropdown.tsx @@ -29,7 +29,7 @@ interface fieldsDropdownProps { @observer export class FieldsDropdown extends ObservableReactComponent { @observable _newField = ''; - constructor(props: any) { + constructor(props: fieldsDropdownProps) { super(props); makeObservable(this); } @@ -101,13 +101,13 @@ export class FieldsDropdown extends ObservableReactComponent this._props.selectFunc((val as any as { value: string; label: string }).value)} + onChange={val => this._props.selectFunc((val as { value: string; label: string }).value)} onKeyDown={e => { if (e.key === 'Enter') { runInAction(() => { - this._props.selectFunc((this._newField = (e.nativeEvent.target as any)?.value)); + this._props.selectFunc((this._newField = (e.nativeEvent.target as HTMLSelectElement)?.value)); }); } e.stopPropagation(); diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 7d01bbabb..a85a03aab 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -56,7 +56,7 @@ export class KeyManager { window.addEventListener('keydown', KeyManager.Instance.handle); window.removeEventListener('keyup', KeyManager.Instance.unhandle); window.addEventListener('keyup', KeyManager.Instance.unhandle); - window.addEventListener('paste', KeyManager.Instance.paste as any); + window.addEventListener('paste', KeyManager.Instance.paste); } public unhandle = action((/* e: KeyboardEvent */) => { @@ -330,7 +330,7 @@ export class KeyManager { } break; case 'c': - if ((document.activeElement as any)?.type !== 'text' && !AnchorMenu.Instance.Active && DocumentDecorations.Instance.Bounds.r - DocumentDecorations.Instance.Bounds.x > 2) { + if (!AnchorMenu.Instance.Active && DocumentDecorations.Instance.Bounds.r - DocumentDecorations.Instance.Bounds.x > 2) { const bds = DocumentDecorations.Instance.Bounds; const pt = DocumentView.Selected()[0] .screenToViewTransform() diff --git a/src/client/views/KeyphraseQueryView.scss b/src/client/views/KeyphraseQueryView.scss deleted file mode 100644 index ac715e5e7..000000000 --- a/src/client/views/KeyphraseQueryView.scss +++ /dev/null @@ -1,8 +0,0 @@ -.fading { - animation: fanOut 1s -} - -@keyframes fanOut { - from {opacity: 0;} - to {opacity: 1;} -} \ No newline at end of file diff --git a/src/client/views/KeyphraseQueryView.tsx b/src/client/views/KeyphraseQueryView.tsx deleted file mode 100644 index 81f004010..000000000 --- a/src/client/views/KeyphraseQueryView.tsx +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-disable jsx-a11y/label-has-associated-control */ -import { observer } from 'mobx-react'; -import * as React from 'react'; -import './KeyphraseQueryView.scss'; - -// tslint:disable-next-line: class-name -export interface KP_Props { - keyphrases: string; -} - -@observer -export class KeyphraseQueryView extends React.Component { - render() { - const keyterms = this.props.keyphrases.split(','); - return ( -
-
Select queries to send:
-
- {keyterms.map((kp: string) => ( - // return (

{"-" + kp}

); -

- -

- ))} -
-
- ); - } -} diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx index a6dc5c62b..4a35805fb 100644 --- a/src/client/views/MainViewModal.tsx +++ b/src/client/views/MainViewModal.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable react/require-default-props */ import { isDark } from 'browndash-components'; import { observer } from 'mobx-react'; diff --git a/src/client/views/ObservableReactComponent.tsx b/src/client/views/ObservableReactComponent.tsx index 34da82b6c..bb7a07f0e 100644 --- a/src/client/views/ObservableReactComponent.tsx +++ b/src/client/views/ObservableReactComponent.tsx @@ -8,27 +8,27 @@ import JsxParser from 'react-jsx-parser'; * This is an abstract class that serves as the base for a PDF-style or Marquee-style * menu. To use this class, look at PDFMenu.tsx or MarqueeOptionsMenu.tsx for an example. */ -export abstract class ObservableReactComponent extends React.Component { +export abstract class ObservableReactComponent extends React.Component { @observable _props: React.PropsWithChildren; - constructor(props: any) { + constructor(props: React.PropsWithChildren) { super(props); this._props = props; makeObservable(this); } componentDidUpdate(prevProps: Readonly): void { Object.keys(prevProps) - .filter(pkey => (prevProps as any)[pkey] !== (this.props as any)[pkey]) + .filter(pkey => (prevProps as {[key:string]: unknown})[pkey] !== (this.props as {[key:string]: unknown})[pkey]) .forEach(action(pkey => { - (this._props as any)[pkey] = (this.props as any)[pkey]; + (this._props as {[key:string]: unknown})[pkey] = (this.props as {[key:string]: unknown})[pkey]; })); // prettier-ignore } } class ObserverJsxParser1 extends JsxParser { - constructor(props: any) { + constructor(props: object) { super(props); - observer(this as any); + observer(this as typeof JsxParser); } } -export const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any; +export const ObserverJsxParser = ObserverJsxParser1 as typeof JsxParser; diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 034ade50b..7e597879d 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -7,13 +7,14 @@ import { Docs, DocumentOptions } from '../documents/Documents'; import { DocUtils } from '../documents/DocUtils'; import { ImageUtils } from '../util/Import & Export/ImageUtils'; import { Transform } from '../util/Transform'; -import { UndoManager, undoBatch } from '../util/UndoManager'; +import { UndoManager, undoable } from '../util/UndoManager'; import { ObservableReactComponent } from './ObservableReactComponent'; import './PreviewCursor.scss'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; +import { StrCast } from '../../fields/Types'; @observer -export class PreviewCursor extends ObservableReactComponent<{}> { +export class PreviewCursor extends ObservableReactComponent { // eslint-disable-next-line no-use-before-define static _instance: PreviewCursor; public static get Instance() { @@ -29,7 +30,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> { @observable _clickPoint: number[] = []; @observable public Visible = false; public Doc: Opt; - constructor(props: any) { + constructor(props: object) { super(props); makeObservable(this); PreviewCursor._instance = this; @@ -46,7 +47,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> { }); // tests for URL and makes web document - const re: any = /^https?:\/\//g; + const re = /^https?:\/\//g; const plain = e.clipboardData.getData('text/plain'); if (plain && newPoint) { // tests for youtube and makes video document @@ -64,17 +65,19 @@ export class PreviewCursor extends ObservableReactComponent<{}> { } else if (re.test(plain)) { const url = plain; if (!url.startsWith(window.location.href)) { - undoBatch(() => - this._addDocument?.( - Docs.Create.WebDocument(url, { - title: url, - _width: 500, - _height: 300, - data_useCors: true, - x: newPoint[0], - y: newPoint[1], - }) - ) + undoable( + () => + this._addDocument?.( + Docs.Create.WebDocument(url, { + title: url, + _width: 500, + _height: 300, + data_useCors: true, + x: newPoint[0], + y: newPoint[1], + }) + ), + 'paste web doc' )(); } else alert('cannot paste dash into itself'); } else if (plain.startsWith('__DashDocId(') || plain.startsWith('__DashCloneId(')) { @@ -94,11 +97,11 @@ export class PreviewCursor extends ObservableReactComponent<{}> { } // pasting in images else if (e.clipboardData.getData('text/html') !== '' && e.clipboardData.getData('text/html').includes(' { + if (newPoint && arr) { + undoable(() => { const doc = Docs.Create.ImageDocument(arr[1], { _width: 300, title: arr[1], @@ -107,7 +110,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> { }); ImageUtils.ExtractImgInfo(doc); this._addDocument?.(doc); - })(); + }, 'paste image doc')(); } } else if (e.clipboardData.items.length && newPoint) { const batch = UndoManager.StartBatch('collection view drop'); @@ -196,8 +199,12 @@ export class PreviewCursor extends ObservableReactComponent<{}> { } render() { return !this._clickPoint || !this.Visible ? null : ( - // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -
e?.focus()} style={{ color: lightOrDark(this.Doc?.backgroundColor ?? 'white'), transform: `translate(${this._clickPoint[0]}px, ${this._clickPoint[1]}px)` }}> +
e?.focus()} + style={{ color: lightOrDark(StrCast(this.Doc?.backgroundColor, 'white')), transform: `translate(${this._clickPoint[0]}px, ${this._clickPoint[1]}px)` }}> I
); diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index edf6df2b9..f346d4ba8 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable react/no-unused-class-component-methods */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Dropdown, DropdownType, IListItemProps, Toggle, ToggleType, Type } from 'browndash-components'; @@ -18,7 +16,7 @@ import { TfiBarChart } from 'react-icons/tfi'; import { Doc, Opt } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; import { ScriptField } from '../../fields/ScriptField'; -import { BoolCast, ScriptCast } from '../../fields/Types'; +import { BoolCast, ScriptCast, StrCast } from '../../fields/Types'; import { ImageField } from '../../fields/URLField'; import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils'; import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; @@ -32,7 +30,7 @@ import { OpenWhere } from './nodes/OpenWhere'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; @observer -export class PropertiesButtons extends React.Component<{}, {}> { +export class PropertiesButtons extends React.Component { // eslint-disable-next-line no-use-before-define @observable public static Instance: PropertiesButtons; @@ -314,13 +312,6 @@ export class PropertiesButtons extends React.Component<{}, {}> { // ); // } - @undoBatch - handlePerspectiveChange = (e: any) => { - this.selectedDoc && (this.selectedDoc._type_collection = e.target.value); - DocumentView.Selected().forEach(docView => { - docView.layoutDoc._type_collection = e.target.value; - }); - }; @computed get onClickVal() { const linkButton = IsFollowLinkScript(this.selectedDoc.onClick); const followLoc = this.selectedDoc._followLinkLocation; @@ -452,7 +443,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { else this.selectedDoc && DocUtils.makeCustomViewClicked(this.selectedDoc, undefined, 'onClick'); }; - propertyToggleBtn = (label: (on?: any) => string, property: string, tooltip: (on?: any) => string, icon: (on?: any) => any, onClick?: (dv: Opt, doc: Doc, property: string) => void, useUserDoc?: boolean) => { + propertyToggleBtn = (label: (on?: unknown) => string, property: string, tooltip: (on?: unknown) => string, icon: (on?: unknown) => unknown, onClick?: (dv: Opt, doc: Doc, property: string) => void, useUserDoc?: boolean) => { const targetDoc = useUserDoc ? Doc.UserDoc() : this.selectedLayoutDoc; const onPropToggle = (dv: Opt, doc: Doc, prop: string) => { (dv?.layoutDoc || doc)[prop] = !(dv?.layoutDoc || doc)[prop]; @@ -463,7 +454,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { tooltip={tooltip(BoolCast(targetDoc[property]))} text={label(targetDoc?.[property])} color={SettingsManager.userColor} - icon={icon(targetDoc?.[property] as any)} + icon={icon(targetDoc?.[property]) as string} iconPlacement="left" align="flex-start" fillWidth @@ -484,7 +475,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const isImage = layoutField instanceof ImageField; const isMap = this.selectedDoc?.type === DocumentType.MAP; const isCollection = this.selectedDoc?.type === DocumentType.COL; - const isStacking = [CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.NoteTaking].includes(this.selectedDoc?._type_collection as any); + const isStacking = [CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.NoteTaking].includes(StrCast(this.selectedDoc?._type_collection) as CollectionViewType); const isFreeForm = this.selectedDoc?._type_collection === CollectionViewType.Freeform; const isTree = this.selectedDoc?._type_collection === CollectionViewType.Tree; const toggle = (ele: JSX.Element | null, style?: React.CSSProperties) => ( diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx index edb55f341..e30d14eae 100644 --- a/src/client/views/PropertiesDocBacklinksSelector.tsx +++ b/src/client/views/PropertiesDocBacklinksSelector.tsx @@ -16,7 +16,7 @@ import { DocumentView } from './nodes/DocumentView'; type PropertiesDocBacklinksSelectorProps = { Document: Doc; - Stack?: any; + Stack?: string; hideTitle?: boolean; addDocTab(doc: Doc, location: OpenWhere): void; }; diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx index 1fea36d16..f494ff16a 100644 --- a/src/client/views/PropertiesDocContextSelector.tsx +++ b/src/client/views/PropertiesDocContextSelector.tsx @@ -1,6 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -/* eslint-disable jsx-a11y/anchor-is-valid */ import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -15,14 +12,14 @@ import { OpenWhere } from './nodes/OpenWhere'; type PropertiesDocContextSelectorProps = { DocView?: DocumentView; - Stack?: any; + Stack?: string; hideTitle?: boolean; addDocTab(doc: Doc, location: OpenWhere): void; }; @observer export class PropertiesDocContextSelector extends ObservableReactComponent { - constructor(props: any) { + constructor(props: PropertiesDocContextSelectorProps) { super(props); makeObservable(this); } diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx index b9a587719..12a46c7a4 100644 --- a/src/client/views/PropertiesSection.tsx +++ b/src/client/views/PropertiesSection.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable react/require-default-props */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed } from 'mobx'; @@ -12,7 +10,7 @@ export interface PropertiesSectionProps { title: string; children?: JSX.Element | string | null; isOpen: boolean; - setIsOpen: (bool: boolean) => any; + setIsOpen: (bool: boolean) => void; onDoubleClick?: () => void; } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 024db82a4..5952d6641 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1,7 +1,4 @@ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable prettier/prettier */ -import { IconLookup } from '@fortawesome/fontawesome-svg-core'; +import { IconLookup, IconProp } from '@fortawesome/fontawesome-svg-core'; import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, Tooltip } from '@mui/material'; @@ -12,6 +9,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { ColorResult, SketchPicker } from 'react-color'; import * as Icons from 'react-icons/bs'; // {BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs" +import ResizeObserver from 'resize-observer-polyfill'; import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; import { Doc, Field, FieldResult, FieldType, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc'; @@ -44,8 +42,6 @@ import { StyleProviderFuncType } from './nodes/FieldView'; import { OpenWhere } from './nodes/OpenWhere'; import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails'; -const _global = (window /* browser */ || global) /* node */ as any; - interface PropertiesViewProps { width: number; height: number; @@ -59,7 +55,7 @@ export class PropertiesView extends ObservableReactComponent (!this.selectedLayoutDoc ? 0 : Math.min(NumCast(this.selectedLayoutDoc?._width), this._props.width - 20)); @@ -275,7 +271,7 @@ export class PropertiesView extends ObservableReactComponent this.transform; propertiesDocViewRef = (ref: HTMLDivElement) => { - const resizeObserver = new _global.ResizeObserver( + const resizeObserver = new ResizeObserver( action(() => { const cliRect = ref.getBoundingClientRect(); this.transform = new Transform(-cliRect.x, -cliRect.y, 1); @@ -357,7 +353,7 @@ export class PropertiesView extends ObservableReactComponent { + changePermissions = (e: React.ChangeEvent, user: string) => { const docs = DocumentView.Selected().length < 2 ? [this.selectedDoc] : DocumentView.Selected().map(dv => (this.layoutDocAcls ? dv.layoutDoc : dv.dataDoc)); SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, docs, this.layoutDocAcls); }; @@ -456,7 +452,7 @@ export class PropertiesView extends ObservableReactComponent (u1 > u2 ? -1 : u1 === u2 ? 0 : 1); + sortUsers = (u1: string, u2: string) => (u1 > u2 ? -1 : u1 === u2 ? 0 : 1); /** * Sorting algorithm to sort groups. @@ -711,7 +707,7 @@ export class PropertiesView extends ObservableReactComponent {}, title: string) => ( + inputBox = (key: string, value: string | number | undefined, setter: (val: string) => void, title: string) => (
{title}
setter(e.target.value)} onKeyDown={e => e.stopPropagation()} />
-
this.upDownButtons('up', key)))}> +
this.upDownButtons('up', key)), + 'down btn' + )}>
-
this.upDownButtons('down', key)))}> +
this.upDownButtons('down', key)), + 'up btn' + )}>
); - inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => ( + inputBoxDuo = (key: string, value: string | number | undefined, setter: (val: string) => void, title1: string, key2: string, value2: string | number | undefined, setter2: (val: string) => void, title2: string) => (
{this.inputBox(key, value, setter, title1)} {title2 === '' ? null : this.inputBox(key2, value2, setter2, title2)} @@ -841,7 +849,7 @@ export class PropertiesView extends ObservableReactComponent {}) => ( + regInput = (key: string, value: string | number | undefined, setter: (val: string) => void) => (
setter(e.target.value)} />
-
this.upDownButtons('up', key)))}> +
this.upDownButtons('up', key)), + 'up' + )}>
-
this.upDownButtons('down', key)))}> +
this.upDownButtons('down', key)), + 'down' + )}>
@@ -1002,7 +1022,7 @@ export class PropertiesView extends ObservableReactComponent { this.markHead = this.markHead ? '' : 'arrow'; }))} + onChange={undoable(action(() => { this.markHead = this.markHead ? '' : 'arrow'; }), "change arrow head")} />
@@ -1012,8 +1032,8 @@ export class PropertiesView extends ObservableReactComponent { this.markTail = this.markTail ? '' : 'arrow'; }) + onChange={undoable( + action(() => { this.markTail = this.markTail ? '' : 'arrow'; }) ,"change arrow tail" )} />
@@ -1044,7 +1064,8 @@ export class PropertiesView extends ObservableReactComponent { this._sliderBatch?.end(); }; - getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: any, autorange?: number, autorangeMinVal?: number) => ( + + getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: (val: number) => void, autorange?: number, autorangeMinVal?: number) => (
this.changeEffectDirection(direction)}> - {icon ? : null} + {icon ? : null}
); @@ -1368,7 +1389,7 @@ export class PropertiesView extends ObservableReactComponent { this.selectedLink && (this.selectedLink[prop] = !this.selectedLink[prop]); })) // prettier-ignore + undoable(action(() => { this.selectedLink && (this.selectedLink[prop] = !this.selectedLink[prop]); }), `toggle prop: ${prop}`) // prettier-ignore ); }; @@ -1385,17 +1406,17 @@ export class PropertiesView extends ObservableReactComponent any = val => val) => { + toggleAnchorProp = (e: React.PointerEvent, prop: string, anchor?: Doc, value: FieldType = true, ovalue: FieldType = false, cb: (val: FieldType) => void = val => val) => { anchor && setupMoveUpEvents( this, e, returnFalse, emptyFunction, - undoBatch(action(() => { + undoable(action(() => { anchor[prop] = anchor[prop] === value ? ovalue : value; - this.selectedDoc && cb(anchor[prop]); - })) // prettier-ignore + this.selectedDoc && cb(anchor[prop] as boolean); + }), `toggle anchor prop: ${prop}`) // prettier-ignore ); }; @@ -1433,7 +1454,7 @@ export class PropertiesView extends ObservableReactComponent { + setZoom = (number: string, change?: number) => { let scale = Number(number) / 100; if (change) scale += change; if (scale < 0.01) scale = 0.01; @@ -1530,7 +1551,6 @@ export class PropertiesView extends ObservableReactComponent

Play Target Audio

{ - // eslint-disable-next-line jsx-a11y/control-has-associated-label ); + const searchTitle = `${!this._searching ? 'Open' : 'Close'} Search Bar`; const curPage = NumCast(this.Document._layout_curPage) || 1; return !this._props.isContentActive() || this._pdfViewer?.isAnnotating ? null : ( @@ -473,14 +473,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { specificContextMenu = (): void => { const cm = ContextMenu.Instance; const options = cm.findByDescription('Options...'); - const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : []; + const optionItems = options?.subitems ?? []; !Doc.noviceMode && optionItems.push({ description: 'Toggle Sidebar Type', event: this.toggleSidebarType, icon: 'expand-arrows-alt' }); !Doc.noviceMode && optionItems.push({ description: 'update icon', event: () => this.pdfUrl && this.updateIcon(), icon: 'expand-arrows-alt' }); // optionItems.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" }); !options && ContextMenu.Instance.addItem({ description: 'Options...', subitems: optionItems, icon: 'asterisk' }); const help = cm.findByDescription('Help...'); - const helpItems: ContextMenuProps[] = help && 'subitems' in help ? help.subitems : []; + const helpItems = help?.subitems ?? []; helpItems.push({ description: 'Copy path', event: () => this.pdfUrl && ClientUtils.CopyText(ClientUtils.prepend('') + this.pdfUrl.url.pathname), icon: 'expand-arrows-alt' }); !help && ContextMenu.Instance.addItem({ description: 'Help...', noexpand: true, subitems: helpItems, icon: 'asterisk' }); }; diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index 4d0e9efee..df1421a33 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -17,7 +17,7 @@ interface IEquationViewInternal { tbox: FormattedTextBox; width: number; height: number; - getPos: () => number; + getPos: () => number | undefined; setEditor: (editor: EquationEditor | undefined) => void; } @@ -47,7 +47,7 @@ export class EquationViewInternal extends React.Component className="equationView" onKeyDown={e => { if (e.key === 'Enter') { - this.props.tbox.EditorView!.dispatch(this.props.tbox.EditorView!.state.tr.setSelection(new TextSelection(this.props.tbox.EditorView!.state.doc.resolve(this.props.getPos() + 1)))); + this.props.tbox.EditorView!.dispatch(this.props.tbox.EditorView!.state.tr.setSelection(new TextSelection(this.props.tbox.EditorView!.state.doc.resolve((this.props.getPos() ?? 0) + 1)))); this.props.tbox.EditorView!.focus(); e.preventDefault(); } @@ -82,8 +82,8 @@ export class EquationView { tbox: FormattedTextBox; view: EditorView; _editor: EquationEditor | undefined; - getPos: () => number; - constructor(node: Node, view: EditorView, getPos: () => number, tbox: FormattedTextBox) { + getPos: () => number | undefined; + constructor(node: Node, view: EditorView, getPos: () => number | undefined, tbox: FormattedTextBox) { this.tbox = tbox; this.view = view; this.getPos = getPos; @@ -109,7 +109,7 @@ export class EquationView { this._editor?.mathField.focus(); } selectNode() { - this.view.dispatch(this.view.state.tr.setSelection(new TextSelection(this.view.state.doc.resolve(this.getPos())))); + this.view.dispatch(this.view.state.tr.setSelection(new TextSelection(this.view.state.doc.resolve(this.getPos() ?? 0)))); this.tbox._applyingChange = this.tbox.fieldKey; // setting focus will make prosemirror lose focus, which will cause it to change its selection to a text selection, which causes this view to get rebuilt but it's no longer node selected, so the equationview won't have focus setTimeout(() => { this._editor?.mathField.focus(); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index c8b25e184..478039ffa 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -875,7 +875,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { @@ -959,7 +959,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent RTFMarkup.Instance.setOpen(true), icon: }); !help && cm.addItem({ description: 'Help...', subitems: helpItems, icon: 'eye' }); }; -- cgit v1.2.3-70-g09d2 From b84bdc5a629dfa6310b24dd5eedee2843558b73a Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 12 Aug 2024 21:38:22 -0400 Subject: more any -> type fixes --- deploy/mobile/image.html | 16 - deploy/mobile/ink.html | 13 - src/.DS_Store | Bin 10244 -> 10244 bytes src/ClientUtils.ts | 4 - src/ServerUtils.ts | 1 + src/client/util/Scripting.ts | 2 +- src/client/util/type_decls.txt | 224 ++++++ src/client/views/EditableView.tsx | 4 +- src/client/views/GestureOverlay.tsx | 7 +- src/client/views/LightboxView.tsx | 12 +- src/client/views/MainView.tsx | 12 +- src/client/views/OverlayView.tsx | 8 +- src/client/views/PropertiesView.tsx | 8 +- src/client/views/TemplateMenu.tsx | 4 +- src/client/views/collections/CollectionMenu.tsx | 4 +- .../collections/CollectionStackedTimeline.tsx | 4 +- .../views/collections/CollectionStackingView.tsx | 5 +- .../CollectionStackingViewFieldColumn.tsx | 11 +- .../views/collections/CollectionTreeView.tsx | 7 +- src/client/views/collections/TabDocView.tsx | 14 +- src/client/views/collections/TreeView.tsx | 4 +- .../CollectionMulticolumnView.tsx | 8 +- .../CollectionMultirowView.tsx | 6 +- .../collectionMulticolumn/MulticolumnResizer.tsx | 2 +- .../collectionMulticolumn/MultirowResizer.tsx | 2 +- .../collectionSchema/CollectionSchemaView.tsx | 57 +- .../collectionSchema/SchemaColumnHeader.tsx | 4 +- .../collections/collectionSchema/SchemaRowBox.tsx | 4 +- .../collectionSchema/SchemaTableCell.tsx | 32 +- src/client/views/linking/LinkPopup.tsx | 4 +- src/client/views/newlightbox/NewLightboxView.tsx | 14 +- .../RecommendationList/RecommendationList.tsx | 7 +- src/client/views/nodes/KeyValuePair.tsx | 4 +- src/client/views/nodes/LabelBox.tsx | 5 +- src/client/views/nodes/LinkDocPreview.tsx | 7 +- .../views/nodes/MapboxMapBox/MapboxContainer.tsx | 13 +- src/client/views/nodes/trails/PresElementBox.tsx | 18 +- src/client/views/topbar/TopBar.tsx | 8 +- src/fields/Doc.ts | 4 + src/mobile/ImageUpload.scss | 139 ---- src/mobile/ImageUpload.tsx | 170 ---- src/mobile/InkControls.tsx | 0 src/mobile/MobileInkOverlay.scss | 39 - src/mobile/MobileInkOverlay.tsx | 183 ----- src/mobile/MobileInterface.scss | 445 ----------- src/mobile/MobileInterface.tsx | 871 --------------------- src/mobile/MobileMain.tsx | 26 - src/mobile/MobileMenu.scss | 271 ------- webpack.config.js | 6 +- 49 files changed, 382 insertions(+), 2331 deletions(-) delete mode 100644 deploy/mobile/image.html delete mode 100644 deploy/mobile/ink.html create mode 100644 src/client/util/type_decls.txt delete mode 100644 src/mobile/ImageUpload.scss delete mode 100644 src/mobile/ImageUpload.tsx delete mode 100644 src/mobile/InkControls.tsx delete mode 100644 src/mobile/MobileInkOverlay.scss delete mode 100644 src/mobile/MobileInkOverlay.tsx delete mode 100644 src/mobile/MobileInterface.scss delete mode 100644 src/mobile/MobileInterface.tsx delete mode 100644 src/mobile/MobileMain.tsx delete mode 100644 src/mobile/MobileMenu.scss diff --git a/deploy/mobile/image.html b/deploy/mobile/image.html deleted file mode 100644 index cca6f763b..000000000 --- a/deploy/mobile/image.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - Dash Mobile - - - - - - -
- - - - \ No newline at end of file diff --git a/deploy/mobile/ink.html b/deploy/mobile/ink.html deleted file mode 100644 index 938d85794..000000000 --- a/deploy/mobile/ink.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - Test view - - - - -
- - - - \ No newline at end of file diff --git a/src/.DS_Store b/src/.DS_Store index 75cff7b55..7a0b53ce0 100644 Binary files a/src/.DS_Store and b/src/.DS_Store differ diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts index f9e282993..fc048b155 100644 --- a/src/ClientUtils.ts +++ b/src/ClientUtils.ts @@ -82,10 +82,6 @@ export function returnEmptyFilter() { return [] as string[]; } -export function returnEmptyDoclist() { - return [] as any[]; -} - // eslint-disable-next-line @typescript-eslint/no-namespace export namespace ClientUtils { export const CLICK_TIME = 300; diff --git a/src/ServerUtils.ts b/src/ServerUtils.ts index ade4ca35d..7e821cda2 100644 --- a/src/ServerUtils.ts +++ b/src/ServerUtils.ts @@ -2,6 +2,7 @@ import { Socket } from 'socket.io'; import { Message } from './server/Message'; import { Utils } from './Utils'; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace ServerUtils { export function Emit(socket: Socket, message: Message, args: T) { Utils.log('Emit', message.Name, args, false); diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index 133f8f2ce..b9e0943b6 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -1,7 +1,7 @@ // export const ts = (window as any).ts; // import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts' // import * as typescriptes5 from '!!raw-loader!../../../node_modules/typescript/lib/lib.es5.d.ts' -import * as typescriptlib from '!!raw-loader!./type_decls.d'; +import * as typescriptlib from './type_decls.d'; import * as ts from 'typescript'; import { Doc, FieldType } from '../../fields/Doc'; import { RefField } from '../../fields/RefField'; diff --git a/src/client/util/type_decls.txt b/src/client/util/type_decls.txt new file mode 100644 index 000000000..1a93bbe59 --- /dev/null +++ b/src/client/util/type_decls.txt @@ -0,0 +1,224 @@ +//@ts-ignore +declare type PropertyKey = string | number | symbol; +interface Array { + length: number; + toString(): string; + toLocaleString(): string; + pop(): T | undefined; + push(...items: T[]): number; + concat(...items: ConcatArray[]): T[]; + concat(...items: (T | ConcatArray)[]): T[]; + join(separator?: string): string; + reverse(): T[]; + shift(): T | undefined; + slice(start?: number, end?: number): T[]; + sort(compareFn?: (a: T, b: T) => number): this; + splice(start: number, deleteCount?: number): T[]; + splice(start: number, deleteCount: number, ...items: T[]): T[]; + unshift(...items: T[]): number; + indexOf(searchElement: T, fromIndex?: number): number; + lastIndexOf(searchElement: T, fromIndex?: number): number; + every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; + some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; + forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; + map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; + filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; + filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; + reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; + reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; + reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; + reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; + reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; + reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; + + [n: number]: T; +} + +interface Function { + apply(this: Function, thisArg: any, argArray?: any): any; + call(this: Function, thisArg: any, ...argArray: any[]): any; + bind(this: Function, thisArg: any, ...argArray: any[]): any; + toString(): string; + + prototype: any; + readonly length: number; + + // Non-standard extensions + arguments: any; + caller: Function; +} +interface Boolean { + valueOf(): boolean; +} +interface Number { + toString(radix?: number): string; + toFixed(fractionDigits?: number): string; + toExponential(fractionDigits?: number): string; + toPrecision(precision?: number): string; + valueOf(): number; +} +interface IArguments { + [index: number]: any; + length: number; + callee: Function; +} +interface RegExp { + readonly flags: string; + readonly sticky: boolean; + readonly unicode: boolean; +} +interface Date { + now() : string; +} +interface String { + codePointAt(pos: number): number | undefined; + includes(searchString: string, position?: number): boolean; + endsWith(searchString: string, endPosition?: number): boolean; + normalize(form: "NFC" | "NFD" | "NFKC" | "NFKD"): string; + normalize(form?: string): string; + repeat(count: number): string; + replace(a:any, b:any):string; // bcz: fix this + startsWith(searchString: string, position?: number): boolean; + anchor(name: string): string; + big(): string; + blink(): string; + bold(): string; + fixed(): string; + fontcolor(color: string): string; + fontsize(size: number): string; + fontsize(size: string): string; + italics(): string; + link(url: string): string; + small(): string; + strike(): string; + sub(): string; + sup(): string; +} +interface Object { + constructor: Function; + toString(): string; + toLocaleString(): string; + valueOf(): Object; + hasOwnProperty(v: PropertyKey): boolean; + isPrototypeOf(v: Object): boolean; + propertyIsEnumerable(v: PropertyKey): boolean; +} +interface ConcatArray { + readonly length: number; + readonly [n: number]: T; + join(separator?: string): string; + slice(start?: number, end?: number): T[]; +} +interface URL { + hash: string; + host: string; + hostname: string; + href: string; + readonly origin: string; + password: string; + pathname: string; + port: string; + protocol: string; + search: string; + username: string; + toJSON(): string; +} +interface PromiseLike { + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): PromiseLike; +} +interface Promise { + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; +} + +declare const Update: unique symbol; +declare const Self: unique symbol; +declare const SelfProxy: unique symbol; +declare const DataSym: unique symbol; +declare const HandleUpdate: unique symbol; +declare const Id: unique symbol; +declare const OnUpdate: unique symbol; +declare const Parent: unique symbol; +declare const Copy: unique symbol; +declare const ToScriptString: unique symbol; + +declare abstract class RefField { + readonly [Id]: FieldId; + + constructor(); +} + +declare type FieldId = string; + +declare abstract class ObjectField { + abstract [Copy](): ObjectField; +} + +declare abstract class URLField extends ObjectField { + readonly url: URL; + + constructor(url: string); + constructor(url: URL); +} + +declare class RichTextField extends URLField { + [Copy](): ObjectField; + constructor(data:string, text: string); +} +declare class AudioField extends URLField { [Copy](): ObjectField; } +declare class VideoField extends URLField { [Copy](): ObjectField; } +declare class ImageField extends URLField { [Copy](): ObjectField; } +declare class WebField extends URLField { [Copy](): ObjectField; } +declare class PdfField extends URLField { [Copy](): ObjectField; } + +declare const ComputedField: any; +declare const CompileScript: any; + +// @ts-ignore +declare type Extract = T extends U ? T : never; +declare type Field = number | string | boolean | ObjectField | RefField; +declare type FieldWaiting = T extends undefined ? never : Promise; +declare type FieldResult = Opt | FieldWaiting>; + +declare type Opt = T | undefined; +declare class Doc extends RefField { + constructor(); + + [key: string]: FieldResult; + // [ToScriptString](): string; +} + +declare class List extends ObjectField { + constructor(fields?: T[]); + [index: number]: T | (T extends RefField ? Promise : never); + [Copy](): ObjectField; +} + +declare class InkField extends ObjectField { + constructor(data:Array<{X:number, Y:number}>); + [Copy](): ObjectField; +} + +// @ts-ignore +declare const console: any; + +interface DocumentOptions { } + +declare const Docs: { + ImageDocument(url: string, options?: DocumentOptions): Doc; + VideoDocument(url: string, options?: DocumentOptions): Doc; + TextDocument(options?: DocumentOptions): Doc; + PdfDocument(url: string, options?: DocumentOptions): Doc; + WebDocument(url: string, options?: DocumentOptions): Doc; + HtmlDocument(html: string, options?: DocumentOptions): Doc; + MapDocument(url: string, options?: DocumentOptions): Doc; + KVPDocument(document: Doc, options?: DocumentOptions): Doc; + FreeformDocument(documents: Doc[], options?: DocumentOptions): Doc; + SchemaDocument(columns: string[], documents: Doc[], options?: DocumentOptions): Doc; + TreeDocument(documents: Doc[], options?: DocumentOptions): Doc; + StackingDocument(documents: Doc[], options?: DocumentOptions): Doc; +}; + +declare function idToDoc(id:string):any; +declare function assignDoc(doc:Doc, field:any, id:any):string; +declare function d(...args:any[]):any; diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index e02e39b8b..23da5a666 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -26,7 +26,7 @@ export interface EditableProps { /** * The contents to render when not editing */ - contents: string; + contents: JSX.Element | string; fieldContents?: FieldViewProps; fontStyle?: string; fontSize?: number; @@ -301,7 +301,7 @@ export class EditableView extends ObservableReactComponent { fontStyle: this._props.fontStyle, fontSize: this._props.fontSize, }}> - {this._props.fieldContents ? : this._props.contents ? this._props.contents?.valueOf() : ''} + {this._props.fieldContents ? : (this._props.contents ?? '')}
); diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 804c41091..bcd4d1ee5 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -2,9 +2,9 @@ import * as fitCurve from 'fit-curve'; import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../ClientUtils'; +import { returnEmptyFilter, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; -import { Doc, Opt } from '../../fields/Doc'; +import { Doc, Opt, returnEmptyDoclist } from '../../fields/Doc'; import { InkData, InkField, InkTool } from '../../fields/InkField'; import { NumCast } from '../../fields/Types'; import { @@ -30,6 +30,7 @@ import { ScriptingGlobals } from '../util/ScriptingGlobals'; import { Transform } from '../util/Transform'; import './GestureOverlay.scss'; import { ObservableReactComponent } from './ObservableReactComponent'; +import { returnEmptyDocViewList } from './StyleProvider'; import { ActiveFillColor, DocumentView } from './nodes/DocumentView'; export enum ToolglassTools { @@ -466,7 +467,7 @@ export class GestureOverlay extends ObservableReactComponent { ScreenToLocalTransform={this.lightboxScreenToLocal} renderDepth={0} suppressSetHeight={!!this._doc._layout_fitWidth} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index ac30c5a14..62ad0a3fb 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -8,9 +8,9 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import ResizeObserver from 'resize-observer-polyfill'; import '../../../node_modules/browndash-components/dist/styles/global.min.css'; -import { ClientUtils, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../ClientUtils'; +import { ClientUtils, lightOrDark, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; -import { Doc, DocListCast, GetDocFromUrl, Opt } from '../../fields/Doc'; +import { Doc, DocListCast, GetDocFromUrl, Opt, returnEmptyDoclist } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { DocCast, StrCast, toList } from '../../fields/Types'; @@ -627,7 +627,7 @@ export class MainView extends ObservableReactComponent { Document={this.headerBarDoc} addDocTab={DocumentViewInternal.addDocTabFunc} pinToPres={emptyFunction} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} styleProvider={DefaultStyleProvider} addDocument={this.addHeaderDoc} removeDocument={this.removeHeaderDoc} @@ -662,7 +662,7 @@ export class MainView extends ObservableReactComponent { addDocument={undefined} addDocTab={DocumentViewInternal.addDocTabFunc} pinToPres={emptyFunction} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} styleProvider={this._hideUI ? DefaultStyleProvider : undefined} isContentActive={returnTrue} removeDocument={undefined} @@ -766,7 +766,7 @@ export class MainView extends ObservableReactComponent { addDocument={undefined} addDocTab={DocumentViewInternal.addDocTabFunc} pinToPres={DocumentView.PinDoc} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} styleProvider={this._sidebarContent.proto === Doc.MyDashboards || this._sidebarContent.proto === Doc.MyFilesystem || this._sidebarContent.proto === Doc.MyTrails ? DashboardStyleProvider : DefaultStyleProvider} removeDocument={returnFalse} ScreenToLocalTransform={this.mainContainerXf} @@ -799,7 +799,7 @@ export class MainView extends ObservableReactComponent { PanelWidth={this.leftMenuWidth} PanelHeight={this.leftMenuHeight} renderDepth={0} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} focus={emptyFunction} styleProvider={DefaultStyleProvider} isContentActive={returnTrue} diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index 7bf10467e..5e9677b45 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -4,9 +4,9 @@ import { computedFn } from 'mobx-utils'; import * as React from 'react'; import ReactLoading from 'react-loading'; import ResizeObserver from 'resize-observer-polyfill'; -import { returnEmptyDoclist, returnEmptyFilter, returnTrue, setupMoveUpEvents } from '../../ClientUtils'; +import { returnEmptyFilter, returnTrue, setupMoveUpEvents } from '../../ClientUtils'; import { Utils, emptyFunction } from '../../Utils'; -import { Doc } from '../../fields/Doc'; +import { Doc, returnEmptyDoclist } from '../../fields/Doc'; import { Height, Width } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { NumCast, toList } from '../../fields/Types'; @@ -16,7 +16,7 @@ import { dropActionType } from '../util/DropActionTypes'; import { Transform } from '../util/Transform'; import { ObservableReactComponent } from './ObservableReactComponent'; import './OverlayView.scss'; -import { DefaultStyleProvider } from './StyleProvider'; +import { DefaultStyleProvider, returnEmptyDocViewList } from './StyleProvider'; import { DocumentView, DocumentViewInternal } from './nodes/DocumentView'; export type OverlayDisposer = () => void; @@ -226,7 +226,7 @@ export class OverlayView extends ObservableReactComponent { whenChildContentsActiveChanged={emptyFunction} focus={emptyFunction} styleProvider={DefaultStyleProvider} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} addDocTab={DocumentViewInternal.addDocTabFunc} pinToPres={emptyFunction} childFilters={returnEmptyFilter} diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 5952d6641..daa8e1720 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -10,9 +10,9 @@ import * as React from 'react'; import { ColorResult, SketchPicker } from 'react-color'; import * as Icons from 'react-icons/bs'; // {BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs" import ResizeObserver from 'resize-observer-polyfill'; -import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../ClientUtils'; +import { ClientUtils, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; -import { Doc, Field, FieldResult, FieldType, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc'; +import { Doc, Field, FieldResult, FieldType, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast, returnEmptyDoclist } from '../../fields/Doc'; import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { InkField } from '../../fields/InkField'; @@ -36,7 +36,7 @@ import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector import { PropertiesDocContextSelector } from './PropertiesDocContextSelector'; import { PropertiesSection } from './PropertiesSection'; import './PropertiesView.scss'; -import { DefaultStyleProvider, SetFilterOpener as SetPropertiesFilterOpener } from './StyleProvider'; +import { DefaultStyleProvider, SetFilterOpener as SetPropertiesFilterOpener, returnEmptyDocViewList } from './StyleProvider'; import { DocumentView } from './nodes/DocumentView'; import { StyleProviderFuncType } from './nodes/FieldView'; import { OpenWhere } from './nodes/OpenWhere'; @@ -322,7 +322,7 @@ export class PropertiesView extends ObservableReactComponent boolean; createDropTarget: (ele: HTMLDivElement) => void; screenToLocalTransform: () => Transform; - refList: any[]; + refList: HTMLElement[]; } @observer @@ -64,7 +61,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< @observable _heading = ''; @observable _color = ''; - constructor(props: any) { + constructor(props: CSVFieldColumnProps) { super(props); makeObservable(this); this._heading = this._props.headingObject ? this._props.headingObject.heading : this._props.heading; @@ -118,7 +115,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< this._props.pivotField && drop.docs?.forEach(d => Doc.SetInPlace(d, this._props.pivotField, drop.val, false)); return true; }); - getValue = (value: string): any => { + getValue = (value: string) => { const parsed = parseInt(value); if (!isNaN(parsed)) return parsed; if (value.toLowerCase().indexOf('true') > -1) return true; @@ -212,7 +209,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
{colors.map(col => { const palette = PastelSchemaPalette.get(col); - return
this.changeColumnColor(palette!)} />; + return
this.changeColumnColor(palette!)} />; })}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 0557a9102..a60cd98ac 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -2,8 +2,8 @@ import { action, computed, IReactionDisposer, makeObservable, observable, reacti import { observer } from 'mobx-react'; import * as React from 'react'; import ResizeObserver from 'resize-observer-polyfill'; -import { DivHeight, returnAll, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnOne, returnTrue, returnZero } from '../../../ClientUtils'; -import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc'; +import { DivHeight, returnAll, returnEmptyFilter, returnFalse, returnNone, returnOne, returnTrue, returnZero } from '../../../ClientUtils'; +import { Doc, DocListCast, Opt, returnEmptyDoclist, StrListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { listSpec } from '../../../fields/Schema'; @@ -25,6 +25,7 @@ import { EditableView } from '../EditableView'; import { DocumentView } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { StyleProp } from '../StyleProp'; +import { returnEmptyDocViewList } from '../StyleProvider'; import { CollectionFreeFormView } from './collectionFreeForm'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import './CollectionTreeView.scss'; @@ -369,7 +370,7 @@ export class CollectionTreeView extends CollectionSubView { PanelWidth={this.PanelWidth} PanelHeight={this.PanelHeight} styleProvider={DefaultStyleProvider} - childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist} - childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist} + childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDocViewList} + childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDocViewList} searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist} addDocument={undefined} removeDocument={this.remDocTab} @@ -628,7 +628,7 @@ export class TabDocView extends ObservableReactComponent { dontCenter="y" whenChildContentsActiveChanged={this.whenChildContentActiveChanges} focus={this.focusFunc} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} pinToPres={TabDocView.PinDoc} /> {this.disableMinimap() ? null : } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 54053d038..c0fe7a894 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -4,9 +4,9 @@ import { IconButton, Size } from 'browndash-components'; import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { ClientUtils, lightOrDark, return18, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils'; +import { ClientUtils, lightOrDark, return18, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; -import { Doc, DocListCast, Field, FieldResult, FieldType, Opt, StrListCast } from '../../../fields/Doc'; +import { Doc, DocListCast, Field, FieldResult, FieldType, Opt, StrListCast, returnEmptyDoclist } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index b8509a005..5125bdb6c 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { Button, IconButton } from 'browndash-components'; @@ -14,7 +12,7 @@ import { SettingsManager } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; import { undoBatch, undoable } from '../../../util/UndoManager'; import { DocumentView } from '../../nodes/DocumentView'; -import { CollectionSubView } from '../CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import './CollectionMulticolumnView.scss'; import ResizeBar from './MulticolumnResizer'; import WidthLabel from './MulticolumnWidthLabel'; @@ -42,7 +40,7 @@ const resizerWidth = 8; export class CollectionMulticolumnView extends CollectionSubView() { @observable _startIndex = 0; - constructor(props: any) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); } @@ -305,7 +303,7 @@ export class CollectionMulticolumnView extends CollectionSubView() { whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} addDocTab={this._props.addDocTab} pinToPres={this._props.pinToPres} - dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy' + dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as 'x' | 'y' | 'xy'} /> ); }; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 3fe3d5343..2833ff2f8 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -8,7 +8,7 @@ import { dropActionType } from '../../../util/DropActionTypes'; import { Transform } from '../../../util/Transform'; import { undoBatch } from '../../../util/UndoManager'; import { DocumentView } from '../../nodes/DocumentView'; -import { CollectionSubView } from '../CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import './CollectionMultirowView.scss'; import HeightLabel from './MultirowHeightLabel'; import ResizeBar from './MultirowResizer'; @@ -33,7 +33,7 @@ const resizerHeight = 8; @observer export class CollectionMultirowView extends CollectionSubView() { - constructor(props: any) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); } @@ -284,7 +284,7 @@ export class CollectionMultirowView extends CollectionSubView() { whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} addDocTab={this._props.addDocTab} pinToPres={this._props.pinToPres} - dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy' + dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as 'y' | 'x' | 'xy'} /> ); }; diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx index 931e2c5e0..10a6fa2e9 100644 --- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx @@ -68,7 +68,7 @@ export default class ResizeBar extends React.Component { style={{ pointerEvents: this.props.isContentActive?.() ? 'all' : 'none', width: this.props.width, - backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor), + backgroundColor: !this.props.isContentActive?.() ? '' : (this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor) as string), }}>
this.registerResizing(e)} />
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx index cff0a8b4c..918365700 100644 --- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx @@ -66,7 +66,7 @@ export default class ResizeBar extends React.Component { style={{ pointerEvents: this.props.isContentActive?.() ? 'all' : 'none', height: this.props.height, - backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor), + backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor) as string, }}>
this.registerResizing(e)} />
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx index 6bea53355..8b0639b3b 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx @@ -4,7 +4,7 @@ import { Popup, PopupTrigger, Type } from 'browndash-components'; import { ObservableMap, action, computed, makeObservable, observable, observe, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../ClientUtils'; +import { returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; import { Doc, DocListCast, Field, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { DocData } from '../../../../fields/DocSymbols'; @@ -22,12 +22,12 @@ import { ContextMenu } from '../../ContextMenu'; import { EditableView } from '../../EditableView'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { StyleProp } from '../../StyleProp'; -import { DefaultStyleProvider } from '../../StyleProvider'; +import { DefaultStyleProvider, returnEmptyDocViewList } from '../../StyleProvider'; import { Colors } from '../../global/globalEnums'; import { DocumentView } from '../../nodes/DocumentView'; import { FieldViewProps } from '../../nodes/FieldView'; import { FocusViewOptions } from '../../nodes/FocusViewOptions'; -import { CollectionSubView } from '../CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import './CollectionSchemaView.scss'; import { SchemaColumnHeader } from './SchemaColumnHeader'; import { SchemaRowBox } from './SchemaRowBox'; @@ -49,14 +49,14 @@ const defaultColumnKeys: string[] = ['title', 'type', 'author', 'author_date', ' @observer export class CollectionSchemaView extends CollectionSubView() { - private _keysDisposer: any; + private _keysDisposer?: () => void; private _previewRef: HTMLDivElement | null = null; private _makeNewColumn: boolean = false; private _documentOptions: DocumentOptions = new DocumentOptions(); private _tableContentRef: HTMLDivElement | null = null; private _menuTarget = React.createRef(); - constructor(props: any) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); } @@ -76,7 +76,7 @@ export class CollectionSchemaView extends CollectionSubView() { @observable _columnMenuIndex: number | undefined = undefined; @observable _newFieldWarning: string = ''; @observable _makeNewField: boolean = false; - @observable _newFieldDefault: any = 0; + @observable _newFieldDefault: boolean | number | string | undefined = 0; @observable _newFieldType: ColumnType = ColumnType.Number; @observable _menuValue: string = ''; @observable _filterColumnIndex: number | undefined = undefined; @@ -161,11 +161,11 @@ export class CollectionSchemaView extends CollectionSubView() { Object.entries(this._documentOptions).forEach((pair: [string, FInfo]) => this.fieldInfos.set(pair[0], pair[1])); this._keysDisposer = observe( this.dataDoc[this.fieldKey ?? 'data'] as List, - (change: any) => { + change => { switch (change.type) { case 'splice': // prettier-ignore - (change as any).added.forEach((doc: Doc) => // for each document added + change.added.filter(doc => doc instanceof Doc).map(doc => doc as Doc).forEach((doc: Doc) => // for each document added Doc.GetAllPrototypes(doc.value as Doc).forEach(proto => // for all of its prototypes (and itself) Object.keys(proto).forEach(action(key => // check if any of its keys are new, and add them !this.fieldInfos.get(key) && this.fieldInfos.set(key, new FInfo("-no description-", key === 'author')))))); @@ -270,7 +270,7 @@ export class CollectionSchemaView extends CollectionSubView() { addRow = (doc: Doc | Doc[]) => this.addDocument(doc); @undoBatch - changeColumnKey = (index: number, newKey: string, defaultVal?: any) => { + changeColumnKey = (index: number, newKey: string, defaultVal?: string | number | boolean) => { if (!this.documentKeys.includes(newKey)) { this.addNewKey(newKey, defaultVal); } @@ -281,7 +281,7 @@ export class CollectionSchemaView extends CollectionSubView() { }; @undoBatch - addColumn = (key: string, defaultVal?: any) => { + addColumn = (key: string, defaultVal?: string | number | boolean) => { if (!this.documentKeys.includes(key)) { this.addNewKey(key, defaultVal); } @@ -298,7 +298,7 @@ export class CollectionSchemaView extends CollectionSubView() { }; @action - addNewKey = (key: string, defaultVal: any) => + addNewKey = (key: string, defaultVal?: string | number | boolean) => this.childDocs.forEach(doc => { doc[DocData][key] = defaultVal; }); @@ -317,7 +317,7 @@ export class CollectionSchemaView extends CollectionSubView() { }; @action - startResize = (e: any, index: number) => { + startResize = (e: React.PointerEvent, index: number) => { this._displayColumnWidths = this.storedColumnWidths; setupMoveUpEvents(this, e, moveEv => this.resizeColumn(moveEv, index), this.finishResize, emptyFunction); }; @@ -604,7 +604,7 @@ export class CollectionSchemaView extends CollectionSubView() { }; scrollToDoc = (doc: Doc, options: FocusViewOptions) => { - const found = this._tableContentRef && Array.from(this._tableContentRef.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]); + const found = this._tableContentRef && Array.from(this._tableContentRef.getElementsByClassName('documentView-node')).find(node => node.id === doc[Id]); if (found) { const rect = found.getBoundingClientRect(); const localRect = this.ScreenToLocalBoxXf().transformBounds(rect.left, rect.top, rect.width, rect.height); @@ -625,9 +625,9 @@ export class CollectionSchemaView extends CollectionSubView() { type="number" name="" id="" - value={this._newFieldDefault ?? 0} + value={Number(this._newFieldDefault ?? 0)} onPointerDown={e => e.stopPropagation()} - onChange={action((e: any) => { + onChange={action(e => { this._newFieldDefault = e.target.value; })} /> @@ -637,11 +637,9 @@ export class CollectionSchemaView extends CollectionSubView() { <> e.stopPropagation()} - onChange={action((e: any) => { + onChange={action(e => { this._newFieldDefault = e.target.checked; })} /> @@ -654,9 +652,9 @@ export class CollectionSchemaView extends CollectionSubView() { type="text" name="" id="" - value={this._newFieldDefault ?? ''} + value={this._newFieldDefault?.toString() ?? ''} onPointerDown={e => e.stopPropagation()} - onChange={action((e: any) => { + onChange={action(e => { this._newFieldDefault = e.target.value; })} /> @@ -683,7 +681,7 @@ export class CollectionSchemaView extends CollectionSubView() { }; @action - setKey = (key: string, defaultVal?: any) => { + setKey = (key: string, defaultVal?: string | number | boolean) => { if (this._makeNewColumn) { this.addColumn(key, defaultVal); } else { @@ -856,16 +854,16 @@ export class CollectionSchemaView extends CollectionSubView() { onKeysPassiveWheel = (e: WheelEvent) => { // if scrollTop is 0, then don't let wheel trigger scroll on any container (which it would since onScroll won't be triggered on this) - if (!this._oldKeysWheel.scrollTop && e.deltaY <= 0) e.preventDefault(); + if (!this._oldKeysWheel?.scrollTop && e.deltaY <= 0) e.preventDefault(); e.stopPropagation(); }; - _oldKeysWheel: any; + _oldKeysWheel: HTMLDivElement | null = null; @computed get keysDropdown() { return (
{ + onPointerDown={action(e => { e.stopPropagation(); this._makeNewField = true; })}> @@ -880,6 +878,7 @@ export class CollectionSchemaView extends CollectionSubView() { }}> {this._menuKeys.map(key => (
{ e.stopPropagation(); @@ -962,7 +961,7 @@ export class CollectionSchemaView extends CollectionSubView() { {this.renderFilterOptions}
{ + onPointerDown={action(e => { e.stopPropagation(); this.closeFilterMenu(); })}> @@ -1013,7 +1012,7 @@ export class CollectionSchemaView extends CollectionSubView() { screenToLocal = () => this.ScreenToLocalBoxXf().translate(-this.tableWidth, 0); previewWidthFunc = () => this.previewWidth; onPassiveWheel = (e: WheelEvent) => e.stopPropagation(); - _oldWheel: any; + _oldWheel: HTMLDivElement | null = null; render() { return (
this.createDashEventsTarget(ele)} onDrop={this.onExternalDrop.bind(this)} onPointerMove={e => this.onPointerMove(e)}> @@ -1112,7 +1111,7 @@ export class CollectionSchemaView extends CollectionSubView() { childFiltersByRanges={this.childDocRangeFilters} searchFilterDocs={this.searchFilterDocs} styleProvider={DefaultStyleProvider} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} moveDocument={this._props.moveDocument} addDocument={this.addRow} removeDocument={this._props.removeDocument} @@ -1137,7 +1136,7 @@ interface CollectionSchemaViewDocProps { @observer class CollectionSchemaViewDoc extends ObservableReactComponent { - constructor(props: any) { + constructor(props: CollectionSchemaViewDocProps) { super(props); makeObservable(this); } diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx index 6b5a34ec0..e0ed8d01e 100644 --- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx +++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx @@ -18,8 +18,8 @@ export interface SchemaColumnHeaderProps { setSort: (field: string | undefined, desc?: boolean) => void; removeColumn: (index: number) => void; rowHeight: () => number; - resizeColumn: (e: any, index: number) => void; - dragColumn: (e: any, index: number) => boolean; + resizeColumn: (e: React.PointerEvent, index: number) => void; + dragColumn: (e: PointerEvent, index: number) => boolean; openContextMenu: (x: number, y: number, index: number) => void; setColRef: (index: number, ref: HTMLDivElement) => void; } diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 760089ffb..a7e0e916b 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -58,8 +58,8 @@ export class SchemaRowBox extends ViewBoxBaseComponent() { selectCell = (doc: Doc, col: number, shift: boolean, ctrl: boolean) => this.schemaView?.selectCell(doc, col, shift, ctrl); deselectCell = () => this.schemaView?.deselectAllCells(); selectedCells = () => this.schemaView?._selectedDocs; - setColumnValues = (field: any, value: any) => this.schemaView?.setColumnValues(field, value) ?? false; - setSelectedColumnValues = (field: any, value: any) => this.schemaView?.setSelectedColumnValues(field, value) ?? false; + setColumnValues = (field: string, value: string) => this.schemaView?.setColumnValues(field, value) ?? false; + setSelectedColumnValues = (field: string, value: string) => this.schemaView?.setSelectedColumnValues(field, value) ?? false; columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth); render() { return ( diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 5874364e0..22506cac1 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -1,4 +1,3 @@ -/* eslint-disable jsx-a11y/alt-text */ /* eslint-disable react/jsx-props-no-spreading */ /* eslint-disable no-use-before-define */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -10,10 +9,10 @@ import * as React from 'react'; import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; import Select from 'react-select'; -import { ClientUtils, StopEvent, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../../ClientUtils'; +import { ClientUtils, StopEvent, returnEmptyFilter, returnFalse, returnZero } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; import { DateField } from '../../../../fields/DateField'; -import { Doc, DocListCast, Field } from '../../../../fields/Doc'; +import { Doc, DocListCast, Field, returnEmptyDoclist } from '../../../../fields/Doc'; import { RichTextField } from '../../../../fields/RichTextField'; import { ColumnType } from '../../../../fields/SchemaHeaderField'; import { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast, toList } from '../../../../fields/Types'; @@ -22,7 +21,7 @@ import { FInfo, FInfoFieldType } from '../../../documents/Documents'; import { dropActionType } from '../../../util/DropActionTypes'; import { SnappingManager } from '../../../util/SnappingManager'; import { Transform } from '../../../util/Transform'; -import { undoBatch, undoable } from '../../../util/UndoManager'; +import { undoable } from '../../../util/UndoManager'; import { EditableView } from '../../EditableView'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DefaultStyleProvider, returnEmptyDocViewList } from '../../StyleProvider'; @@ -138,7 +137,7 @@ export class SchemaTableCell extends ObservableReactComponent selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} oneLine={this._props.oneLine} allowCRs={this._props.allowCRs} - contents={undefined} + contents={''} fieldContents={fieldProps} editing={selectedCell(this._props) ? undefined : false} GetValue={() => Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)} @@ -209,7 +208,7 @@ export class SchemaTableCell extends ObservableReactComponent { - constructor(props: any) { + constructor(props: SchemaTableCellProps) { super(props); makeObservable(this); } @@ -276,7 +275,7 @@ export class SchemaImageCell extends ObservableReactComponent { - constructor(props: any) { + constructor(props: SchemaTableCellProps) { super(props); makeObservable(this); } @@ -324,7 +323,7 @@ export class SchemaDateCell extends ObservableReactComponent { - constructor(props: any) { + constructor(props: SchemaTableCellProps) { super(props); makeObservable(this); } @@ -343,7 +342,7 @@ export class SchemaRTFCell extends ObservableReactComponent { - constructor(props: any) { + constructor(props: SchemaTableCellProps) { super(props); makeObservable(this); } @@ -356,18 +355,19 @@ export class SchemaBoolCell extends ObservableReactComponent | undefined) => { - if ((value?.nativeEvent as any).shiftKey) { + onChange={undoable((value: React.ChangeEvent | undefined) => { + if ((value?.nativeEvent as MouseEvent | PointerEvent).shiftKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); } else Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); - })} + }, 'set bool cell')} /> + Field.toKeyValueString(this._props.Document, this._props.fieldKey)} - SetValue={undoBatch((value: string, shiftDown?: boolean, enterKey?: boolean) => { + SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); this._props.finishEdit?.(); @@ -376,7 +376,7 @@ export class SchemaBoolCell extends ObservableReactComponent
); @@ -384,7 +384,7 @@ export class SchemaBoolCell extends ObservableReactComponent { - constructor(props: any) { + constructor(props: SchemaTableCellProps) { super(props); makeObservable(this); } diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx index 76a8396ff..9ce5f8fc9 100644 --- a/src/client/views/linking/LinkPopup.tsx +++ b/src/client/views/linking/LinkPopup.tsx @@ -1,9 +1,9 @@ /* eslint-disable react/require-default-props */ import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils'; +import { returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; -import { Doc } from '../../../fields/Doc'; +import { Doc, returnEmptyDoclist } from '../../../fields/Doc'; import { Transform } from '../../util/Transform'; import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider'; import { SearchBox } from '../search/SearchBox'; diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx index c86ddb745..b060fc0b6 100644 --- a/src/client/views/newlightbox/NewLightboxView.tsx +++ b/src/client/views/newlightbox/NewLightboxView.tsx @@ -1,17 +1,15 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../../ClientUtils'; +import { returnEmptyFilter, returnTrue } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; -import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc'; +import { CreateLinkToActiveAudio, Doc, DocListCast, Opt, returnEmptyDoclist } from '../../../fields/Doc'; import { InkTool } from '../../../fields/InkField'; import { Cast, NumCast, StrCast, toList } from '../../../fields/Types'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { GestureOverlay } from '../GestureOverlay'; -import { DefaultStyleProvider } from '../StyleProvider'; +import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider'; import { DocumentView } from '../nodes/DocumentView'; import { OpenWhere } from '../nodes/OpenWhere'; import { ExploreView } from './ExploreView'; @@ -68,7 +66,7 @@ export class NewLightboxView extends React.Component { @action public static SetCookie(cookie: string) { if (this.LightboxDoc && cookie) { - this._docFilters = (f => (this._docFilters ? [this._docFilters.push(f) as any, this._docFilters][1] : [f]))(`cookies:${cookie}:provide`); + this._docFilters = (f => (this._docFilters ? ([this._docFilters.push(f) as unknown, this._docFilters][1] as string[]) : [f]))(`cookies:${cookie}:provide`); } } public static AddDocTab = (docsIn: Doc | Doc[], location: OpenWhere, layoutTemplate?: Doc | string) => { @@ -264,7 +262,7 @@ export class NewLightboxView extends React.Component { styleProvider={DefaultStyleProvider} ScreenToLocalTransform={this.newLightboxScreenToLocal} renderDepth={0} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} childFilters={this.docFilters} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} @@ -320,7 +318,7 @@ export class NewLightboxView extends React.Component {
)}
- +
); diff --git a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx index dc3339cd3..27413bac3 100644 --- a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx +++ b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx @@ -1,6 +1,4 @@ /* eslint-disable react/jsx-props-no-spreading */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable guard-for-in */ import { IconButton, Size, Type } from 'browndash-components'; import * as React from 'react'; @@ -168,7 +166,8 @@ export function RecommendationList() {
{keywordsLoc && keywordsLoc.map((word, ind) => ( -
+
+ {' '} {word} )}
-
{recs && recs.map((rec: IRecommendation) => )}
+
{recs && recs.map(rec => )}
); } diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 8e74e1ca2..85aff04c3 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -2,9 +2,9 @@ import { Tooltip } from '@mui/material'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../ClientUtils'; +import { returnEmptyFilter, returnFalse, returnZero } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; -import { Doc, Field } from '../../../fields/Doc'; +import { Doc, Field, returnEmptyDoclist } from '../../../fields/Doc'; import { DocCast } from '../../../fields/Types'; import { DocumentOptions, FInfo } from '../../documents/Documents'; import { Transform } from '../../util/Transform'; diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index d33d12603..e39caecb6 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -1,10 +1,11 @@ import { Property } from 'csstype'; -import { action, computed, makeObservable, trace } from 'mobx'; +import { action, computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import * as textfit from 'textfit'; import { Field, FieldType } from '../../../fields/Doc'; import { BoolCast, NumCast, StrCast } from '../../../fields/Types'; +import { TraceMobx } from '../../../fields/util'; import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; @@ -100,7 +101,7 @@ export class LabelBox extends ViewBoxBaseComponent() { return textfitParams; }; render() { - trace(); + TraceMobx(); const boxParams = this.fitTextToBox(undefined); // this causes mobx to trigger re-render when data changes const label = this.Title.startsWith('#') ? null : this.Title; return ( diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 10ff86a38..5026f52fb 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -4,9 +4,9 @@ import { action, computed, makeObservable, observable, runInAction } from 'mobx' import { observer } from 'mobx-react'; import * as React from 'react'; import wiki from 'wikijs'; -import { returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../ClientUtils'; +import { returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; -import { Doc, Opt } from '../../../fields/Doc'; +import { Doc, Opt, returnEmptyDoclist } from '../../../fields/Doc'; import { Cast, DocCast, NumCast, PromiseValue, StrCast } from '../../../fields/Types'; import { DocServer } from '../../DocServer'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -17,6 +17,7 @@ import { SearchUtil } from '../../util/SearchUtil'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { ObservableReactComponent } from '../ObservableReactComponent'; +import { returnEmptyDocViewList } from '../StyleProvider'; import { DocumentView } from './DocumentView'; import { StyleProviderFuncType } from './FieldView'; import './LinkDocPreview.scss'; @@ -286,7 +287,7 @@ export class LinkDocPreview extends ObservableReactComponent deselectPin = () => { if (this.selectedPin) { // Removes filter - Doc.setDocFilter(this.Document, 'latitude', this.selectedPin.latitude, 'remove'); - Doc.setDocFilter(this.Document, 'longitude', this.selectedPin.longitude, 'remove'); + Doc.setDocFilter(this.Document, 'latitude', NumCast(this.selectedPin.latitude), 'remove'); + Doc.setDocFilter(this.Document, 'longitude', NumCast(this.selectedPin.longitude), 'remove'); Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(DocCast(this.selectedPin))}`, 'remove'); const temp = this.selectedPin; @@ -536,8 +537,8 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent deleteSelectedPin = undoable(() => { if (this.selectedPin) { // Removes filter - Doc.setDocFilter(this.Document, 'latitude', this.selectedPin.latitude, 'remove'); - Doc.setDocFilter(this.Document, 'longitude', this.selectedPin.longitude, 'remove'); + Doc.setDocFilter(this.Document, 'latitude', NumCast(this.selectedPin.latitude), 'remove'); + Doc.setDocFilter(this.Document, 'longitude', NumCast(this.selectedPin.longitude), 'remove'); Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(DocCast(this.selectedPin))}`, 'remove'); this.removePushpin(this.selectedPin); diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 25adfba23..a76805960 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -1,11 +1,9 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils'; +import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils'; import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; @@ -23,6 +21,7 @@ import { EditableView } from '../../EditableView'; import { Colors } from '../../global/globalEnums'; import { PinDocView } from '../../PinFuncs'; import { StyleProp } from '../../StyleProp'; +import { returnEmptyDocViewList } from '../../StyleProvider'; import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { PresBox } from './PresBox'; @@ -105,7 +104,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { embedHeight = () => this.collapsedHeight + this.expandViewHeight; embedWidth = () => this._props.PanelWidth() / 2; // prettier-ignore - styleProvider = ( doc: Doc | undefined, props: Opt, property: string ): any => + styleProvider = ( doc: Doc | undefined, props: Opt, property: string ) => (property === StyleProp.Opacity ? 1 : this._props.styleProvider?.(doc, props, property)); /** * The function that is responsible for rendering a preview or not for this @@ -123,7 +122,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { hideLinkButton ScreenToLocalTransform={Transform.Identity} renderDepth={this._props.renderDepth + 1} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} childFilters={this._props.childFilters} childFiltersByRanges={this._props.childFiltersByRanges} searchFilterDocs={this._props.searchFilterDocs} @@ -144,6 +143,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { const childDocs = DocListCast(this.targetDoc.data); const groupSlides = childDocs.map((doc: Doc, ind: number) => (
{ e.stopPropagation(); @@ -156,7 +156,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { StrCast(doc.title)} SetValue={(value: string) => { @@ -179,7 +179,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { @action headerDown = (e: React.PointerEvent) => { - const element = e.target as any; + const element = e.target as HTMLDivElement; e.stopPropagation(); e.preventDefault(); if (element && !(e.ctrlKey || e.metaKey || e.button === 2)) { @@ -580,7 +580,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { className={`presItem-slide ${isCurrent ? 'active' : ''}${activeItem.runProcess ? ' testingv2' : ''}`} style={{ display: 'infline-block', - backgroundColor: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor), + backgroundColor: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string, // layout_boxShadow: presBoxColor && presBoxColor !== 'white' && presBoxColor !== 'transparent' ? (isCurrent ? '0 0 0px 1.5px' + presBoxColor : undefined) : undefined, border: presBoxColor && presBoxColor !== 'white' && presBoxColor !== 'transparent' ? (isCurrent ? presBoxColor + ' solid 2.5px' : undefined) : undefined, }}> @@ -602,7 +602,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { } }} onClick={e => e.stopPropagation()}>{`${this.indexInPres + 1}. `}
- StrCast(activeItem.title)} SetValue={this.onSetValue} /> + StrCast(activeItem.title)} SetValue={this.onSetValue} />
{/*
{"Movement speed"}
}>
{this.transition}
*/} {/*
{"Duration"}
}>
{this.duration}
*/} diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx index e558e14e3..a85606bc4 100644 --- a/src/client/views/topbar/TopBar.tsx +++ b/src/client/views/topbar/TopBar.tsx @@ -5,8 +5,8 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Flip } from 'react-awesome-reveal'; import { FaBug } from 'react-icons/fa'; -import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils'; -import { Doc, DocListCast } from '../../../fields/Doc'; +import { returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils'; +import { Doc, DocListCast, returnEmptyDoclist } from '../../../fields/Doc'; import { AclAdmin, DashVersion } from '../../../fields/DocSymbols'; import { StrCast } from '../../../fields/Types'; import { GetEffectiveAcl } from '../../../fields/util'; @@ -33,11 +33,11 @@ import './TopBar.scss'; * and settings and help buttons. Future scope for this bar is to include the collaborators that are on the same Dashboard. */ @observer -export class TopBar extends ObservableReactComponent<{}> { +export class TopBar extends ObservableReactComponent { // eslint-disable-next-line no-use-before-define static Instance: TopBar; @observable private _flipDocumentation = 0; - constructor(props: any) { + constructor(props: object) { super(props); makeObservable(this); TopBar.Instance = this; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index e6a95fd30..7e7c319bf 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1658,6 +1658,10 @@ export namespace Doc { } } +export function returnEmptyDoclist() { + return [] as Doc[]; +} + export function RTFIsFragment(html: string) { return html.indexOf('data-pm-slice') !== -1; } diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss deleted file mode 100644 index e4156ee8e..000000000 --- a/src/mobile/ImageUpload.scss +++ /dev/null @@ -1,139 +0,0 @@ -@import '../client/views/global/globalCssVariables.module.scss'; - -.imgupload_cont { - display: flex; - justify-content: center; - flex-direction: column; - align-items: center; - max-width: 400px; - min-width: 400px; - - .upload_label { - font-weight: 700; - color: black; - background-color: rgba(0, 0, 0, 0); - border: solid 3px black; - margin: 10px; - font-size: 30; - height: 70px; - width: 80%; - display: flex; - font-family: sans-serif; - text-transform: uppercase; - justify-content: center; - flex-direction: column; - border-radius: 10px; - } - - .file { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - direction: ltr; - } - - .button_file { - text-align: center; - height: 50%; - width: 50%; - background-color: paleturquoise; - color: grey; - font-size: 3em; - } - - .inputfile { - width: 0.1px; - height: 0.1px; - opacity: 0; - overflow: hidden; - position: absolute; - z-index: -1; - } - - .inputfile + label { - font-weight: 700; - color: black; - background-color: rgba(0, 0, 0, 0); - border: solid 3px black; - margin: 10px; - font-size: 30; - height: 70px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin-top: 30px; - width: 80%; - display: flex; - font-family: sans-serif; - text-transform: uppercase; - justify-content: center; - flex-direction: column; - border-radius: 10px; - } - - .inputfile.active + label { - font-style: italic; - color: black; - background-color: lightgreen; - border: solid 3px darkgreen; - } - - .status { - font-size: 2em; - } -} - -.image-upload { - top: 100%; - opacity: 0; -} - -.image-upload.active { - top: 0; - position: absolute; - z-index: 999; - height: 100vh; - width: 100vw; - opacity: 1; -} - -.uploadContainer { - top: 40; - position: absolute; - z-index: 1000; - height: 20vh; - width: 80vw; - opacity: 1; -} - -.closeUpload { - position: absolute; - border-radius: 10px; - top: 3; - color: black; - font-size: 30; - right: 3; - z-index: 1002; - padding: 0px 3px; - background: rgba(0, 0, 0, 0); - transition: 0.5s ease all; - border: 0px solid; -} - -.loadingImage { - display: inline-flex; - width: max-content; -} - -.loadingSlab { - position: relative; - width: 30px; - height: 30px; - margin: 10; - border-radius: 20px; - opacity: 0.2; - background-color: black; - transition: - all 2s, - opacity 1.5s; -} diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx deleted file mode 100644 index 36c0d6a4d..000000000 --- a/src/mobile/ImageUpload.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, observable } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import * as rp from 'request-promise'; -import { ClientUtils } from '../ClientUtils'; -import { DocServer } from '../client/DocServer'; -import { Networking } from '../client/Network'; -import { Docs } from '../client/documents/Documents'; -import { MainViewModal } from '../client/views/MainViewModal'; -import { Doc, Opt } from '../fields/Doc'; -import { List } from '../fields/List'; -import { listSpec } from '../fields/Schema'; -import { Cast } from '../fields/Types'; -import './ImageUpload.scss'; - -// eslint-disable-next-line @typescript-eslint/no-var-requires -const { DFLT_IMAGE_NATIVE_DIM } = require('../client/views/global/globalCssVariables.module.scss'); // prettier-ignore - -export interface ImageUploadProps { - Document: Doc; // Target document for upload (upload location) -} - -const inputRef = React.createRef(); -const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', '')); - -@observer -export class Uploader extends React.Component { - @observable nm: string = 'Choose files'; // Text of 'Choose Files' button - @observable process: string = ''; // Current status of upload - @observable private dialogueBoxOpacity = 1; - - onClick = async () => { - try { - // eslint-disable-next-line react/destructuring-assignment - const col = this.props.Document; - await Docs.Prototypes.initialize(); - const imgPrev = document.getElementById('img_preview'); - this.setOpacity(1, '1'); // Slab 1 - if (imgPrev && inputRef.current) { - const { files } = inputRef.current; - this.setOpacity(2, '1'); // Slab 2 - if (files && files.length !== 0) { - this.process = 'Uploading Files'; - for (let index = 0; index < files.length; ++index) { - const file = files[index]; - // eslint-disable-next-line no-await-in-loop - const res = await Networking.UploadFilesToServer({ file }); - this.setOpacity(3, '1'); // Slab 3 - // For each item that the user has selected - res.map(async ({ result }) => { - const { name } = file; - if (result instanceof Error) { - return; - } - const path = result.accessPaths.agnostic.client; - let doc = null; - // Case 1: File is a video - if (file.type === 'video/mp4') { - doc = Docs.Create.VideoDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name }); - // Case 2: File is a PDF document - } else if (file.type === 'application/pdf') { - doc = Docs.Create.PdfDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name }); - // Case 3: File is another document type (most likely Image) - } else { - doc = Docs.Create.ImageDocument(path, { _nativeWidth: defaultNativeImageDim, _width: 400, title: name }); - } - this.setOpacity(4, '1'); // Slab 4 - const docidsRes = await rp.get(ClientUtils.prepend('/getUserDocumentIds')); - if (!docidsRes) { - throw new Error('No user id returned'); - } - const field = await DocServer.GetRefField(JSON.parse(docidsRes).userDocumentId); - let pending: Opt; - if (field instanceof Doc) { - pending = col; - } - if (pending) { - const data = Cast(pending.data, listSpec(Doc)); - if (data) data.push(doc); - else pending.data = new List([doc]); - this.setOpacity(5, '1'); // Slab 5 - this.process = 'File ' + (index + 1).toString() + ' Uploaded'; - this.setOpacity(6, '1'); // Slab 6 - } - if (index + 1 === files.length) { - this.process = 'Uploads Completed'; - this.setOpacity(7, '1'); // Slab 7 - } - }); - } - // Case in which the user pressed upload and no files were selected - } else { - this.process = 'No file selected'; - } - // Three seconds after upload the menu will reset - setTimeout(this.clearUpload, 3000); - } - } catch (error) { - console.log(JSON.stringify(error)); - } - }; - - // Returns the upload interface for mobile - private get uploadInterface() { - return ( -
-
this.closeUpload()}> - -
- - - -
- Upload -
- -
-
-
-
-
-
-
-
-
-

{this.process}

-
- ); - } - - // Updates label after a files is selected (so user knows a file is uploaded) - inputLabel = async () => { - const files: FileList | null = await inputRef.current!.files; - if (files && files.length === 1) { - this.nm = files[0].name; - } else if (files && files.length > 1) { - this.nm = files.length.toString() + ' files selected'; - } - }; // Loops through load icons, and resets buttons - @action - clearUpload = () => { - for (let i = 1; i < 8; i++) { - this.setOpacity(i, '0.2'); - } - this.nm = 'Choose files'; - - if (inputRef.current) { - inputRef.current.value = ''; - } - this.process = ''; - }; - - // Clears the upload and closes the upload menu - closeUpload = () => { - this.clearUpload(); - }; - - // Handles the setting of the loading bar - setOpacity = (index: number, opacity: string) => { - const slab = document.getElementById('slab' + index); - if (slab) slab.style.opacity = opacity; - }; - - render() { - return ; - } -} diff --git a/src/mobile/InkControls.tsx b/src/mobile/InkControls.tsx deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/mobile/MobileInkOverlay.scss b/src/mobile/MobileInkOverlay.scss deleted file mode 100644 index b9c1fb146..000000000 --- a/src/mobile/MobileInkOverlay.scss +++ /dev/null @@ -1,39 +0,0 @@ -.mobileInkOverlay { - border: 10px dashed red; - background-color: rgba(0, 0, 0, .05); -} - -.mobileInkOverlay-border { - // background-color: rgba(0, 255, 0, .4); - position: absolute; - pointer-events: auto; - cursor: pointer; - - &.top { - width: calc(100% + 20px); - height: 10px; - top: -10px; - left: -10px; - } - - &.left { - width: 10px; - height: calc(100% + 20px); - top: -10px; - left: -10px; - } - - &.right { - width: 10px; - height: calc(100% + 20px); - top: -10px; - right: -10px; - } - - &.bottom { - width: calc(100% + 20px); - height: 10px; - bottom: -10px; - left: -10px; - } -} \ No newline at end of file diff --git a/src/mobile/MobileInkOverlay.tsx b/src/mobile/MobileInkOverlay.tsx deleted file mode 100644 index 6babd2f39..000000000 --- a/src/mobile/MobileInkOverlay.tsx +++ /dev/null @@ -1,183 +0,0 @@ -import { action, observable } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { DocServer } from '../client/DocServer'; -import { DragManager } from '../client/util/DragManager'; -import { Doc } from '../fields/Doc'; -import { Gestures } from '../pen-gestures/GestureTypes'; -import { GestureContent, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent } from '../server/Message'; -import './MobileInkOverlay.scss'; - -@observer -export default class MobileInkOverlay extends React.Component { - public static Instance: MobileInkOverlay; - - @observable private _scale: number = 1; - @observable private _width: number = 0; - @observable private _height: number = 0; - @observable private _x: number = -300; - @observable private _y: number = -300; - @observable private _text: string = ''; - - @observable private _offsetX: number = 0; - @observable private _offsetY: number = 0; - @observable private _isDragging: boolean = false; - private _mainCont: React.RefObject = React.createRef(); - - constructor(props: Readonly<{}>) { - super(props); - MobileInkOverlay.Instance = this; - } - - initialSize(mobileWidth: number, mobileHeight: number) { - const maxWidth = window.innerWidth - 30; - const maxHeight = window.innerHeight - 30; // -30 for padding - if (mobileWidth > maxWidth || mobileHeight > maxHeight) { - const scale = Math.min(maxWidth / mobileWidth, maxHeight / mobileHeight); - return { width: mobileWidth * scale, height: mobileHeight * scale, scale: scale }; - } - return { width: mobileWidth, height: mobileHeight, scale: 1 }; - } - - @action - initMobileInkOverlay(content: MobileInkOverlayContent) { - const { width, height, text } = content; - const scaledSize = this.initialSize(width ? width : 0, height ? height : 0); - this._width = scaledSize.width; - this._height = scaledSize.height; - this._scale = scaledSize.scale; - this._x = 300; // TODO: center on screen - this._y = 25; // TODO: center on screen - this._text = text ? text : ''; - } - - @action - updatePosition(content: UpdateMobileInkOverlayPositionContent) { - const { dx, dy, dsize } = content; - if (dx) this._x += dx; - if (dy) this._y += dy; - // TODO: scale dsize - } - - drawStroke = (content: GestureContent) => { - // TODO: figure out why strokes drawn in corner of mobile interface dont get inserted - - const { points, bounds } = content; - console.log('received points', points, bounds); - - const B = { - right: bounds.right * this._scale + this._x, - left: bounds.left * this._scale + this._x, // TODO: scale - bottom: bounds.bottom * this._scale + this._y, - top: bounds.top * this._scale + this._y, // TODO: scale - width: bounds.width * this._scale, - height: bounds.height * this._scale, - }; - - const target = document.elementFromPoint(this._x + 10, this._y + 10); - target?.dispatchEvent( - new CustomEvent('dashOnGesture', { - bubbles: true, - detail: { - points: points, - gesture: Gestures.Stroke, - bounds: B, - }, - }) - ); - }; - - uploadDocument = async (content: MobileDocumentUploadContent) => { - const { docId } = content; - const doc = await DocServer.GetRefField(docId); - - if (doc && doc instanceof Doc) { - const target = document.elementFromPoint(this._x + 10, this._y + 10); - const dragData = new DragManager.DocumentDragData([doc]); - const complete = new DragManager.DragCompleteEvent(false, dragData); - - if (target) { - console.log('dispatching upload doc!!!!', target, doc); - target.dispatchEvent( - new CustomEvent('dashOnDrop', { - bubbles: true, - detail: { - x: this._x, - y: this._y, - complete: complete, - altKey: false, - metaKey: false, - ctrlKey: false, - shiftKey: false, - embedKey: false, - }, - }) - ); - } else { - alert('TARGET IS UNDEFINED'); - } - } - }; - - @action - dragStart = (e: React.PointerEvent) => { - document.removeEventListener('pointermove', this.dragging); - document.removeEventListener('pointerup', this.dragEnd); - document.addEventListener('pointermove', this.dragging); - document.addEventListener('pointerup', this.dragEnd); - - this._isDragging = true; - this._offsetX = e.pageX - this._mainCont.current!.getBoundingClientRect().left; - this._offsetY = e.pageY - this._mainCont.current!.getBoundingClientRect().top; - - e.preventDefault(); - e.stopPropagation(); - }; - - @action - dragging = (e: PointerEvent) => { - const x = e.pageX - this._offsetX; - const y = e.pageY - this._offsetY; - - // TODO: don't allow drag over library? - this._x = Math.min(Math.max(x, 0), window.innerWidth - this._width); - this._y = Math.min(Math.max(y, 0), window.innerHeight - this._height); - - e.preventDefault(); - e.stopPropagation(); - }; - - @action - dragEnd = (e: PointerEvent) => { - document.removeEventListener('pointermove', this.dragging); - document.removeEventListener('pointerup', this.dragEnd); - - this._isDragging = false; - - e.preventDefault(); - e.stopPropagation(); - }; - - render() { - return ( -
-

{this._text}

-
-
-
-
-
- ); - } -} diff --git a/src/mobile/MobileInterface.scss b/src/mobile/MobileInterface.scss deleted file mode 100644 index 4b32c3da0..000000000 --- a/src/mobile/MobileInterface.scss +++ /dev/null @@ -1,445 +0,0 @@ -$navbar-height: 120px; -$pathbar-height: 50px; - -@media only screen and (max-device-width: 480px) { - * { - margin: 0px; - padding: 0px; - box-sizing: border-box; - font-family: sans-serif; - } -} - -body { - overflow: hidden; -} - -.mobileInterface-container { - height: 100%; - position: relative; - touch-action: none; - width: 100%; - - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} - -// Topbar of Dash Mobile -.navbar { - position: fixed; - top: 0px; - left: 0px; - width: 100vw; - height: $navbar-height; - background-color: whitesmoke; - z-index: 150; - - .cover { - position: absolute; - right: 0px; - top: 0px; - height: 120px; - width: 120px; - background-color: whitesmoke; - z-index: 200; - } - - .toggle-btn { - position: absolute; - right: 20px; - top: 30px; - height: 70px; - width: 70px; - transition: all 400ms ease-in-out 200ms; - z-index: 180; - } - - .background { - position: absolute; - right: 0px; - top: 0px; - height: 120px; - width: 120px; - //border: 1px solid black; - } - - .background.active { - background-color: lightgrey; - } - - .toggle-btn-home { - right: -200px; - } - - .header { - position: absolute; - top: 50%; - top: calc(9px + 50%); - right: 50%; - transform: translate(50%, -50%); - font-size: 40; - font-weight: 700; - text-align: center; - user-select: none; - text-transform: uppercase; - font-family: Arial, Helvetica, sans-serif; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - direction: ltr; - width: 600px; - } - - .toggle-btn span { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 70%; - height: 4px; - background: black; - transition: all 200ms ease; - z-index: 180; - } - - .toggle-btn span:nth-child(1) { - transition: top 200ms ease-in-out; - top: 30%; - } - - .toggle-btn span:nth-child(3) { - transition: top 200ms ease-in-out; - top: 70%; - } - - .toggle-btn.active { - transition: transform 200ms ease-in-out 200ms; - transform: rotate(135deg); - } - - .toggle-btn.active span:nth-child(1) { - top: 50%; - } - - .toggle-btn.active span:nth-child(2) { - transform: translate(-50%, -50%) rotate(90deg); - } - - .toggle-btn.active span:nth-child(3) { - top: 50%; - } -} - -.sidebar { - position: fixed; - top: 120px; - opacity: 0; - right: -100%; - width: 80%; - height: calc(80% - (120px)); - z-index: 101; - background-color: whitesmoke; - transition: all 400ms ease 50ms; - padding: 20px; - box-shadow: 0 0 5px 5px grey; - - .item { - width: 100%; - padding: 13px 12px; - border-bottom: 1px solid rgba(200, 200, 200, 0.7); - font-family: Arial, Helvetica, sans-serif; - font-style: normal; - font-weight: normal; - user-select: none; - display: inline-flex; - font-size: 35px; - text-transform: uppercase; - color: black; - } - - .ink:focus { - outline: 1px solid blue; - } - - .sidebarButtons { - top: 80px; - position: relative; - } -} - - - - - - -.blanket { - position: fixed; - top: 120px; - opacity: 0.5; - right: -100%; - width: 100%; - height: calc(100% - (120px)); - z-index: 101; - background-color: grey; - padding: 20px; -} - -.blanket.active { - position: absolute; - right: 0%; - z-index: 100; -} - -.home { - position: absolute; - top: 30px; - left: 30px; - font-size: 60; - user-select: none; - text-transform: uppercase; - font-family: Arial, Helvetica, sans-serif; - z-index: 200; -} - -.item-type { - display: inline; - text-transform: lowercase; - margin-left: 20px; - font-size: 35px; - font-style: italic; - color: rgb(28, 28, 28); -} - -.item-title { - max-width: 70%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.right { - margin-left: 20px; - z-index: 200; -} - -.open { - right: 20px; - font-size: 35; - position: absolute; -} - -.left { - width: 100%; - height: 100%; -} - - - -.sidebar.active { - position: absolute; - right: 0%; - opacity: 1; - z-index: 101; -} - -.back { - position: absolute; - left: 42px; - top: 0; - background: #1a1a1a; - width: 50px; - height: 100%; - display: flex; - justify-content: center; - text-align: center; - flex-direction: column; - align-items: center; - border-radius: 10px; - font-size: 25px; - user-select: none; - z-index: 100; -} - -.pathbar { - position: fixed; - top: 118px; - left: 0px; - background: #1a1a1a; - z-index: 120; - border-radius: 0px; - width: 100%; - height: 80px; - overflow: hidden; - - .pathname { - position: relative; - font-size: 25; - top: 50%; - width: 86%; - left: 12%; - color: whitesmoke; - transform: translate(0%, -50%); - z-index: 20; - font-family: sans-serif; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - direction: rtl; - text-align: left; - text-transform: uppercase; - } - - .scrollmenu { - overflow: auto; - width: 100%; - height: 100%; - white-space: nowrap; - display: inline-flex; - } - - .hidePath { - position: absolute; - height: 100%; - width: 200px; - left: 0px; - top: 0px; - background-image: linear-gradient(to right, #1a1a1a, rgba(0, 0, 0, 0)); - text-align: center; - user-select: none; - z-index: 99; - pointer-events: none; - } - - .pathbarItem { - position: relative; - display: flex; - align-items: center; - color: whitesmoke; - text-align: center; - justify-content: center; - user-select: none; - transform: translate(100px, 0px); - font-size: 30px; - padding: 10px; - text-transform: uppercase; - - .pathbarText { - font-family: sans-serif; - text-align: center; - height: 50px; - padding: 10px; - font-size: 30px; - border-radius: 10px; - text-transform: uppercase; - margin-left: 20px; - position: relative; - } - - .pathIcon { - transform: translate(0px, 0px); - position: relative; - } - } -} - - -/** -* docButton appears at the bottom of mobile document -* Buttons include: pin to presentation, download, upload, reload -*/ -.docButton { - position: relative; - width: 100px; - display: flex; - height: 100px; - font-size: 70px; - text-align: center; - border: 3px solid black; - margin: 20px; - z-index: 100; - border-radius: 100%; - justify-content: center; - flex-direction: column; - align-items: center; -} - -.docButtonContainer { - top: 80%; - position: absolute; - display: flex; - transform: translate(-50%, 0); - left: 50%; - z-index: 100; -} - -.toolbar { - left: 50%; - transform: translate(-50%); - position: absolute; - height: max-content; - top: 0px; - border-radius: 20px; - background-color: lightgrey; - opacity: 0; - transition: all 400ms ease 50ms; -} - -.toolbar.active { - display: inline-block; - width: 300px; - padding: 5px; - opacity: 1; - height: max-content; - top: -450px; -} - -.colorSelector { - position: absolute; - top: 550px; - left: 280px; - transform: translate(-50%, 0); - z-index: 100; - display: inline-flex; - width: max-content; - height: max-content; - pointer-events: all; - font-size: 80px; - user-select: none; -} - -// Menu buttons for toggling between list and icon view -.homeSwitch { - position: fixed; - top: 212; - right: 36px; - display: inline-flex; - width: max-content; - z-index: 99; - height: 70px; - - .list { - width: 70px; - height: 70px; - margin: 5; - padding: 10; - align-items: center; - text-align: center; - font-size: 50; - border-style: solid; - border-width: 3; - border-color: black; - background: whitesmoke; - align-self: center; - border-radius: 10px; - } - - .list.active { - color: darkred; - border-color: darkred; - } -} \ No newline at end of file diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx deleted file mode 100644 index 4f37c45a8..000000000 --- a/src/mobile/MobileInterface.tsx +++ /dev/null @@ -1,871 +0,0 @@ -import { library } from '@fortawesome/fontawesome-svg-core'; -import { - faAddressCard, - faAlignLeft, - faAlignRight, - faAngleDoubleLeft, - faAngleRight, - faArrowDown, - faArrowLeft, - faArrowRight, - faArrowUp, - faArrowsAltH, - faAsterisk, - faBars, - faBell, - faBolt, - faBook, - faBrain, - faBullseye, - faCalculator, - faCamera, - faCaretDown, - faCaretLeft, - faCaretRight, - faCaretSquareDown, - faCaretSquareRight, - faCaretUp, - faCat, - faCheck, - faChevronLeft, - faChevronRight, - faClipboard, - faClone, - faCloudUploadAlt, - faCommentAlt, - faCompressArrowsAlt, - faCut, - faEdit, - faEllipsisV, - faEraser, - faExclamation, - faExpand, - faExternalLinkAlt, - faExternalLinkSquareAlt, - faEye, - faFileAlt, - faFileAudio, - faFileDownload, - faFilePdf, - faFilm, - faFilter, - faFolderOpen, - faFont, - faGlobeAsia, - faHandPointLeft, - faHighlighter, - faHome, - faImage, - faLocationArrow, - faLongArrowAltLeft, - faLongArrowAltRight, - faMicrophone, - faCircleHalfStroke, - faMinus, - faMobile, - faMousePointer, - faMusic, - faObjectGroup, - faPaintBrush, - faPalette, - faPause, - faPen, - faPenNib, - faPhone, - faPlay, - faPlus, - faPortrait, - faQuestionCircle, - faQuoteLeft, - faRedoAlt, - faReply, - faSearch, - faStamp, - faStickyNote, - faStop, - faTasks, - faTerminal, - faTh, - faThLarge, - faThumbtack, - faTimes, - faToggleOn, - faTrash, - faTrashAlt, - faTree, - faTv, - faUndoAlt, - faVideo, - faWindowClose, - faWindowMaximize, - faFile as fileSolid, -} from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, runInAction } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../ClientUtils'; -import { CollectionViewType, DocumentType } from '../client/documents/DocumentTypes'; -import { Docs, DocumentOptions } from '../client/documents/Documents'; -import { CurrentUserUtils } from '../client/util/CurrentUserUtils'; -import { ScriptingGlobals } from '../client/util/ScriptingGlobals'; -import { SettingsManager } from '../client/util/SettingsManager'; -import { Transform } from '../client/util/Transform'; -import { UndoManager } from '../client/util/UndoManager'; -import { DashboardView } from '../client/views/DashboardView'; -import { GestureOverlay } from '../client/views/GestureOverlay'; -import { AudioBox } from '../client/views/nodes/AudioBox'; -import { DocumentView } from '../client/views/nodes/DocumentView'; -import { RadialMenu } from '../client/views/nodes/RadialMenu'; -import { RichTextMenu } from '../client/views/nodes/formattedText/RichTextMenu'; -import { Doc, DocListCast } from '../fields/Doc'; -import { InkTool } from '../fields/InkField'; -import { List } from '../fields/List'; -import { ScriptField } from '../fields/ScriptField'; -import { Cast, FieldValue, StrCast } from '../fields/Types'; -import './AudioUpload.scss'; -import { Uploader } from './ImageUpload'; -import './ImageUpload.scss'; -import './MobileInterface.scss'; -import { emptyFunction } from '../Utils'; - -library.add( - ...[ - faTasks, - faReply, - faQuoteLeft, - faHandPointLeft, - faFolderOpen, - faAngleDoubleLeft, - faExternalLinkSquareAlt, - faMobile, - faThLarge, - faWindowClose, - faEdit, - faTrashAlt, - faPalette, - faAngleRight, - faBell, - faTrash, - faCamera, - faExpand, - faCaretDown, - faCaretLeft, - faCaretRight, - faCaretSquareDown, - faCaretSquareRight, - faArrowsAltH, - faPlus, - faMinus, - faTerminal, - faToggleOn, - fileSolid, - faExternalLinkAlt, - faLocationArrow, - faSearch, - faFileDownload, - faStop, - faCalculator, - faWindowMaximize, - faAddressCard, - faQuestionCircle, - faArrowLeft, - faArrowRight, - faArrowDown, - faArrowUp, - faBolt, - faBullseye, - faCaretUp, - faCat, - faCheck, - faChevronRight, - faClipboard, - faClone, - faCloudUploadAlt, - faCommentAlt, - faCompressArrowsAlt, - faCut, - faEllipsisV, - faEraser, - faExclamation, - faFileAlt, - faFileAudio, - faFilePdf, - faFilm, - faFilter, - faFont, - faGlobeAsia, - faHighlighter, - faLongArrowAltRight, - faMicrophone, - faCircleHalfStroke, - faMousePointer, - faMusic, - faObjectGroup, - faPause, - faPen, - faPenNib, - faPhone, - faPlay, - faPortrait, - faRedoAlt, - faStamp, - faStickyNote, - faThumbtack, - faTree, - faTv, - faUndoAlt, - faBook, - faVideo, - faAsterisk, - faBrain, - faImage, - faPaintBrush, - faTimes, - faEye, - faHome, - faLongArrowAltLeft, - faBars, - faTh, - faChevronLeft, - faAlignLeft, - faAlignRight, - ].map(m => m as any) -); - -@observer -export class MobileInterface extends React.Component { - static Instance: MobileInterface; - private _library: Doc; - private _mainDoc: any = CurrentUserUtils.setupActiveMobileMenu(Doc.UserDoc()); - @observable private _sidebarActive: boolean = false; //to toggle sidebar display - @observable private _imageUploadActive: boolean = false; //to toggle image upload - @observable private _audioUploadActive: boolean = false; - @observable private _menuListView: boolean = false; //to switch between menu view (list / icon) - @observable private _ink: boolean = false; //toggle whether ink is being dispalyed - @observable private _homeMenu: boolean = true; // to determine whether currently at home menu - @observable private dashboards: Doc | null = null; // currently selected document - @observable private _activeDoc: Doc = this._mainDoc; // doc updated as the active mobile page is updated (initially home menu) - @observable private _homeDoc: Doc = this._mainDoc; // home menu as a document - @observable private _parents: Array = []; // array of parent docs (for pathbar) - - @computed private get mainContainer() { - return Doc.UserDoc() ? FieldValue(Cast(Doc.UserDoc().activeMobile, Doc)) : Doc.GuestMobile; - } - - constructor(props: Readonly<{}>) { - super(props); - this._library = CurrentUserUtils.setupDashboards(Doc.UserDoc(), 'myDashboards'); // to access documents in Dash Web - MobileInterface.Instance = this; - } - - @action - componentDidMount() { - // if the home menu is in list view -> adjust the menu toggle appropriately - this._menuListView = this._homeDoc._type_collection === 'stacking' ? true : false; - Doc.ActiveTool = InkTool.None; // ink should intially be set to none - Doc.UserDoc().activeMobile = this._homeDoc; // active mobile set to home - - // remove double click to avoid mobile zoom in - document.removeEventListener('dblclick', this.onReactDoubleClick); - document.addEventListener('dblclick', this.onReactDoubleClick); - } - - @action - componentWillUnmount = () => { - document.removeEventListener('dblclick', this.onReactDoubleClick); - }; - - // Prevent zooming in when double tapping the screen - onReactDoubleClick = (e: MouseEvent) => { - e.stopPropagation(); - }; - - // Switch the mobile view to the given doc - @action - switchCurrentView = (doc: Doc, renderView?: () => JSX.Element, onSwitch?: () => void) => { - if (!Doc.UserDoc()) return; - if (this._activeDoc === this._homeDoc) { - this._parents.push(this._activeDoc); - this._homeMenu = false; - } - this._activeDoc = doc; - Doc.UserDoc().activeMobile = doc; - onSwitch?.(); - - // Ensures that switching to home is not registed - UndoManager.undoStack.length = 0; - UndoManager.redoStack.length = 0; - }; - - // For toggling the hamburger menu - @action - toggleSidebar = () => { - this._sidebarActive = !this._sidebarActive; - - if (this._ink) { - this.onSwitchInking(); - } - }; - /** - * Method called when 'Library' button is pressed on the home screen - */ - switchToLibrary = async () => { - this.switchCurrentView(this._library); - runInAction(() => (this._homeMenu = false)); - this.toggleSidebar(); - }; - - /** - * Back method for navigating through items - */ - @action - back = () => { - const header = document.getElementById('header') as HTMLElement; - const doc = Cast(this._parents.pop(), Doc) as Doc; // Parent document - // Case 1: Parent document is 'dashboards' - if (doc === (Cast(this._library, Doc) as Doc)) { - this.dashboards = null; - this.switchCurrentView(this._library); - // Case 2: Parent document is the 'home' menu (root node) - } else if (doc === (Cast(this._homeDoc, Doc) as Doc)) { - this._homeMenu = true; - this._parents = []; - this.dashboards = null; - this.switchCurrentView(this._homeDoc); - // Case 3: Parent document is any document - } else if (doc) { - this.dashboards = doc; - this.switchCurrentView(doc); - this._homeMenu = false; - header.textContent = String(doc.title); - } - this._ink = false; // turns ink off - }; - - /** - * Return 'Home", which implies returning to 'Home' menu buttons - */ - @action - returnHome = () => { - if (!this._homeMenu || this._sidebarActive) { - this._homeMenu = true; - this._parents = []; - this.dashboards = null; - this.switchCurrentView(this._homeDoc); - } - if (this._sidebarActive) { - this.toggleSidebar(); - } - }; - - /** - * Return to primary Dashboard in library (Dashboards Doc) - */ - @action - returnMain = () => { - this._parents = [this._homeDoc]; - this.switchCurrentView(this._library); - this._homeMenu = false; - this.dashboards = null; - }; - - /** - * Note: window.innerWidth and window.screen.width compute different values. - * window.screen.width is the display size, however window.innerWidth is the - * display resolution which computes differently. - */ - returnWidth = () => window.innerWidth; //The windows width - returnHeight = () => window.innerHeight - 300; //Calculating the windows height (-300 to account for topbar) - whitebackground = () => 'white'; - /** - * DocumentView for graphic display of all documents - */ - @computed get displayDashboards() { - return !this.mainContainer ? null : ( -
- -
- ); - } - - /** - * Handles the click functionality in the library panel. - * Navigates to the given doc and updates the sidebar. - * @param doc: doc for which the method is called - */ - handleClick = async (doc: Doc) => { - runInAction(() => { - if (doc.type !== 'collection' && this._sidebarActive) { - this._parents.push(this._activeDoc); - this.switchCurrentView(doc); - this._homeMenu = false; - this.toggleSidebar(); - } else { - this._parents.push(this._activeDoc); - this.switchCurrentView(doc); - this._homeMenu = false; - this.dashboards = doc; - } - }); - }; - - /** - * Called when an item in the library is clicked and should - * be opened (open icon on RHS of all menu items) - * @param doc doc to be opened - */ - @action - openFromSidebar = (doc: Doc) => { - this._parents.push(this._activeDoc); - this.switchCurrentView(doc); - this._homeMenu = false; - this.dashboards = doc; - this.toggleSidebar(); - }; - - // Renders the graphical pathbar - renderPathbar = () => { - const docPath = [...this._parents, this._activeDoc]; - const items = docPath.map((doc: Doc, index: any) => ( -
- {index === 0 ? null : } -
this.handlePathClick(doc, index)}> - {StrCast(doc.title)} -
-
- )); - return ( -
-
{items}
- {!this._parents.length ? null : ( -
- -
- )} -
-
- ); - }; - - // Handles when user clicks on a document in the pathbar - @action - handlePathClick = async (doc: Doc, index: number) => { - const library = await this._library; - if (doc === library) { - this.dashboards = null; - this.switchCurrentView(doc); - this._parents.length = index; - } else if (doc === this._homeDoc) { - this.returnHome(); - } else { - this.dashboards = doc; - this.switchCurrentView(doc); - this._parents.length = index; - } - }; - - // Renders the contents of the menu and sidebar - @computed get renderDefaultContent() { - if (this._homeMenu) { - return ( -
-
- - -
e.stopPropagation()}>
- -
- {this.renderPathbar()} -
- ); - } - // stores dashboards documents as 'dashboards' variable - let dashboards = Doc.MyDashboards; - if (this.dashboards) { - dashboards = this.dashboards; - } - // returns a list of navbar buttons as 'buttons' - const buttons = DocListCast(dashboards.data).map((doc: Doc, index: any) => { - if (doc.type !== 'ink') { - return ( -
-
this.handleClick(doc)}> - {' '} - {doc.title as string}{' '} -
-
this.handleClick(doc)}> - {doc.type as string} -
- this.handleClick(doc)} className="right" icon="angle-right" size="lg" style={{ display: `${doc.type === 'collection' ? 'block' : 'none'}` }} /> - this.openFromSidebar(doc)} icon="external-link-alt" size="lg" /> -
- ); - } - }); - - return ( -
-
- - -
- - - -
-
-
- {this.renderPathbar()} -
-
- {this.dashboards ? ( - <> - {buttons} -
- -
Return to dashboards
-
- - ) : ( - <> - {buttons} -
this.createNewDashboard()}> - -
Create New Dashboard
-
- - )} -
-
-
-
- ); - } - - /** - * Handles the 'Create New Dashboard' button in the menu (taken from MainView.tsx) - */ - @action - createNewDashboard = (id?: string) => { - const scens = Doc.MyDashboards; - const dashboardCount = DocListCast(scens.data).length + 1; - const freeformOptions: DocumentOptions = { - x: 0, - y: 400, - title: 'Collection ' + dashboardCount, - }; - - const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); - const dashboardDoc = DashboardView.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, 'row'); - - const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); - const cloneDashboard = ScriptField.MakeScript(`cloneDashboard()`); - dashboardDoc.contextMenuScripts = new List([toggleComic!, cloneDashboard!]); - dashboardDoc.contextMenuLabels = new List(['Toggle Comic Mode', 'New Dashboard Layout']); - - Doc.AddDocToList(scens, 'data', dashboardDoc); - }; - - // Button for switching between pen and ink mode - @action - onSwitchInking = () => { - const button = document.getElementById('inkButton') as HTMLElement; - button.style.backgroundColor = this._ink ? 'white' : 'black'; - button.style.color = this._ink ? 'black' : 'white'; - - if (!this._ink) { - Doc.ActiveTool = InkTool.Pen; - this._ink = true; - } else { - Doc.ActiveTool = InkTool.None; - this._ink = false; - } - }; - - // The static ink menu that appears at the top - @computed get inkMenu() { - return this._activeDoc._type_collection !== CollectionViewType.Docking || !this._ink ? null :
{/* */}
; - } - - // DocButton that uses UndoManager and handles the opacity change if CanUndo is true - @computed get undo() { - if (this.mainContainer && this._activeDoc.type === 'collection' && this._activeDoc !== this._homeDoc && this._activeDoc !== Doc.SharingDoc() && this._activeDoc.title !== 'WORKSPACES') { - return ( -
{ - UndoManager.Undo(); - e.stopPropagation(); - }}> - -
- ); - } else return null; - } - - // DocButton that uses UndoManager and handles the opacity change if CanRedo is true - @computed get redo() { - if (this.mainContainer && this._activeDoc.type === 'collection' && this._activeDoc !== this._homeDoc && this._activeDoc !== Doc.SharingDoc() && this._activeDoc.title !== 'WORKSPACES') { - return ( -
{ - UndoManager.Redo(); - e.stopPropagation(); - }}> - -
- ); - } else return null; - } - - // DocButton for switching into ink mode - @computed get drawInk() { - return !this.mainContainer || this._activeDoc._type_collection !== CollectionViewType.Docking ? null : ( -
- -
- ); - } - - // DocButton: Button that appears on the bottom of the screen to initiate image upload - @computed get uploadImageButton() { - if (this._activeDoc.type === DocumentType.COL && this._activeDoc !== this._homeDoc && this._activeDoc._type_collection !== CollectionViewType.Docking && this._activeDoc.title !== 'WORKSPACES') { - return ( -
- -
- ); - } else return null; - } - - // DocButton to download images on the mobile - @computed get downloadDocument() { - if (this._activeDoc.type === 'image' || this._activeDoc.type === 'pdf' || this._activeDoc.type === 'video') { - return ( -
window.open(this._activeDoc['data-path']?.toString())}> - {' '} - {/* daa-path holds the url */} - -
- ); - } else return null; - } - - // DocButton for pinning images to presentation - @computed get pinToPresentation() { - // Only making button available if it is an image - if (!(this._activeDoc.type === 'collection' || this._activeDoc.type === 'presentation')) { - return ( -
DocumentView.PinDoc(this._activeDoc, {})}> - -
- ); - } else return null; - } - - // Buttons for switching the menu between large and small icons - @computed get switchMenuView() { - return this._activeDoc.title !== this._homeDoc.title ? null : ( -
-
- -
-
- -
-
- ); - } - - // Logic for switching the menu into the icons - @action - changeToIconView = () => { - if ((this._homeDoc._type_collection = 'stacking')) { - this._menuListView = false; - this._homeDoc._type_collection = 'masonry'; - this._homeDoc.columnWidth = 300; - this._homeDoc._columnWidth = 300; - const menuButtons = DocListCast(this._homeDoc.data); - menuButtons.map(doc => { - const buttonData = DocListCast(doc.data); - buttonData[1]._nativeWidth = 0.1; - buttonData[1]._width = 0.1; - buttonData[1]._dimMagnitude = 0; - buttonData[1]._opacity = 0; - doc._nativeWidth = 400; - }); - } - }; - - // Logic for switching the menu into the stacking view - @action - changeToListView = () => { - if ((this._homeDoc._type_collection = 'masonry')) { - this._homeDoc._type_collection = 'stacking'; - this._menuListView = true; - const menuButtons = DocListCast(this._homeDoc.data); - menuButtons.map(doc => { - const buttonData = DocListCast(doc.data); - buttonData[1]._nativeWidth = 450; - buttonData[1]._dimMagnitude = 2; - buttonData[1]._opacity = 1; - doc._nativeWidth = 900; - }); - } - }; - - // For setting up the presentation document for the home menu - @action - setupDefaultPresentation = () => { - const presentation = Doc.ActivePresentation; - - if (presentation) { - this.switchCurrentView(presentation); - this._homeMenu = false; - } - }; - - // For toggling image upload pop up - @action - toggleUpload = () => (this._imageUploadActive = !this._imageUploadActive); - - // For toggling audio record and dictate pop up - @action - toggleAudio = () => (this._audioUploadActive = !this._audioUploadActive); - - // Button for toggling the upload pop up in a collection - @action - toggleUploadInCollection = () => { - const button = document.getElementById('imageButton') as HTMLElement; - button.style.backgroundColor = this._imageUploadActive ? 'white' : 'black'; - button.style.color = this._imageUploadActive ? 'black' : 'white'; - - this._imageUploadActive = !this._imageUploadActive; - }; - - // For closing the image upload pop up - @action - closeUpload = () => { - this._imageUploadActive = false; - }; - - // Returns the image upload pop up - @computed get uploadImage() { - const doc = !this._homeMenu ? this._activeDoc : (Cast(Doc.SharingDoc(), Doc) as Doc); - return ; - } - - // Radial menu can only be used if it is a colleciton and it is not a homeDoc - // (and cannot be used on Dashboard to avoid pin to presentation opening on right) - @computed get displayRadialMenu() { - return this._activeDoc.type === 'collection' && this._activeDoc !== this._homeDoc && this._activeDoc._type_collection !== CollectionViewType.Docking ? : null; - } - - onDragOver = (e: React.DragEvent) => { - e.preventDefault(); - e.stopPropagation(); - }; - - /** - * MENU BUTTON - * Switch view from mobile menu to access the mobile uploads - * Global function name: openMobileUploads() - */ - @action - switchToMobileUploads = () => { - const mobileUpload = Cast(Doc.SharingDoc(), Doc) as Doc; - this.switchCurrentView(mobileUpload); - this._homeMenu = false; - }; - - render() { - return ( -
- -
{this.uploadImage}
- {this.switchMenuView} - {this.inkMenu} - -
- -
-
- {this.pinToPresentation} - {this.downloadDocument} - {this.undo} - {this.redo} - {this.drawInk} - {this.uploadImageButton} -
- {this.displayDashboards} - {this.renderDefaultContent} -
- {this.displayRadialMenu} -
- ); - } -} - -//Global functions for mobile menu -ScriptingGlobals.add(function switchToMobileLibrary() { - return MobileInterface.Instance.switchToLibrary(); -}, 'opens the library to navigate through dashboards on Dash Mobile'); -ScriptingGlobals.add(function openMobileUploads() { - return MobileInterface.Instance.toggleUpload(); -}, 'opens the upload files menu for Dash Mobile'); -ScriptingGlobals.add(function switchToMobileUploadCollection() { - return MobileInterface.Instance.switchToMobileUploads(); -}, 'opens the mobile uploads collection on Dash Mobile'); -ScriptingGlobals.add(function openMobileAudio() { - return MobileInterface.Instance.toggleAudio(); -}, 'opens the record and dictate menu on Dash Mobile'); -ScriptingGlobals.add(function switchToMobilePresentation() { - return MobileInterface.Instance.setupDefaultPresentation(); -}, 'opens the presentation on Dash Mobile'); -ScriptingGlobals.add(function openMobileSettings() { - return SettingsManager.Instance.openMgr(); -}, 'opens settings on Dash Mobile'); - -// Other global functions for mobile -ScriptingGlobals.add( - function switchMobileView(doc: Doc, renderView?: () => JSX.Element, onSwitch?: () => void) { - return MobileInterface.Instance.switchCurrentView(doc, renderView, onSwitch); - }, - 'changes the active document displayed on the Dash Mobile', - '(doc: any)' -); diff --git a/src/mobile/MobileMain.tsx b/src/mobile/MobileMain.tsx deleted file mode 100644 index 07839b6f6..000000000 --- a/src/mobile/MobileMain.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { DocServer } from '../client/DocServer'; -import { Docs } from '../client/documents/Documents'; -import { CurrentUserUtils } from '../client/util/CurrentUserUtils'; -import { AssignAllExtensions } from '../extensions/Extensions'; -import { MobileInterface } from './MobileInterface'; - -AssignAllExtensions(); - -(async () => { - const info = await CurrentUserUtils.loadCurrentUser(); - DocServer.init(window.location.protocol, window.location.hostname, 4321, info.email + ' (mobile)'); - await Docs.Prototypes.initialize(); - await CurrentUserUtils.loadUserDocument(info); - document.getElementById('root')!.addEventListener( - 'wheel', - event => { - if (event.ctrlKey) { - event.preventDefault(); - } - }, - true - ); - ReactDOM.render(, document.getElementById('root')); -})(); diff --git a/src/mobile/MobileMenu.scss b/src/mobile/MobileMenu.scss deleted file mode 100644 index 7f286efc4..000000000 --- a/src/mobile/MobileMenu.scss +++ /dev/null @@ -1,271 +0,0 @@ -$navbar-height: 120px; -$pathbar-height: 50px; - -* { - margin: 0px; - padding: 0px; - box-sizing: border-box; - font-family: "Open Sans"; -} - -body { - overflow: hidden; -} - -.navbar { - position: fixed; - top: 0px; - left: 0px; - width: 100vw; - height: $navbar-height; - background-color: whitesmoke; - border-bottom: 5px solid black; -} - -.navbar .toggle-btn { - position: absolute; - right: 20px; - top: 30px; - height: 70px; - width: 70px; - transition: all 300ms ease-in-out 200ms; -} - -.navbar .header { - position: absolute; - top: 50%; - top: calc(9px + 50%); - right: 50%; - transform: translate(50%, -50%); - font-size: 40; - user-select: none; - text-transform: uppercase; - font-family: Arial, Helvetica, sans-serif; -} - -.navbar .toggle-btn span { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 70%; - height: 4px; - background: black; - transition: all 200ms ease; -} - -.navbar .toggle-btn span:nth-child(1) { - transition: top 200ms ease-in-out; - top: 30%; -} - -.navbar .toggle-btn span:nth-child(3) { - transition: top 200ms ease-in-out; - top: 70%; -} - -.navbar .toggle-btn.active { - transition: transform 200ms ease-in-out 200ms; - transform: rotate(135deg); -} - -.navbar .toggle-btn.active span:nth-child(1) { - top: 50%; -} - -.navbar .toggle-btn.active span:nth-child(2) { - transform: translate(-50%, -50%) rotate(90deg); -} - -.navbar .toggle-btn.active span:nth-child(3) { - top: 50%; -} -// .navbar .home { -// position: relative; -// right: 5px; -// transform: translate(50%, -50%); -// font-size: 40; -// user-select: none; -// text-transform: uppercase; -// font-family: Arial, Helvetica, sans-serif; -// z-index: 200; -// } - -.sidebar { - position: absolute; - top: 200px; - opacity: 0; - right: -100%; - width: 100%; - height: calc(100% - (200px)); - z-index: 5; - background-color: whitesmoke; - transition: all 400ms ease 50ms; - padding: 20px; - // overflow-y: auto; - // -webkit-overflow-scrolling: touch; - - // border-right: 5px solid black; -} - -.sidebar .item { - width: 100%; - padding: 13px 12px; - border-bottom: 1px solid rgba(200, 200, 200, 0.7); - font-family: Arial, Helvetica, sans-serif; - font-style: normal; - font-weight: normal; - user-select: none; - font-size: 35px; - text-transform: uppercase; - color: black; - -} - -.sidebar .ink { - width: 100%; - padding: 13px 12px; - border-bottom: 1px solid rgba(200, 200, 200, 0.7); - font-family: Arial, Helvetica, sans-serif; - font-style: normal; - font-weight: normal; - user-select: none; - font-size: 35px; - text-transform: uppercase; - color: black; -} - -.sidebar .ink:focus { - outline: 1px solid blue; -} - -.sidebar .home { - position: absolute; - top: -135px; - right: calc(50% + 80px); - transform: translate(0%, -50%); - font-size: 40; - user-select: none; - text-transform: uppercase; - font-family: Arial, Helvetica, sans-serif; - z-index: 200; -} - -.type { - display: inline; - text-transform: lowercase; - margin-left: 20px; - font-size: 35px; - font-style: italic; - color: rgb(28, 28, 28); -} - -.right { - margin-left: 20px; - z-index: 200; -} - -.left { - width: 100%; - height: 100%; -} - -.sidebar .logout { - width: 100%; - padding: 13px 12px; - border-bottom: 1px solid rgba(200, 200, 200, 0.7); - font-family: Arial, Helvetica, sans-serif; - font-style: normal; - font-weight: normal; - user-select: none; - font-size: 30px; - text-transform: uppercase; - color: black; -} - -.sidebar .settings { - width: 100%; - padding: 13px 12px; - border-bottom: 1px solid rgba(200, 200, 200, 0.7); - font-family: Arial, Helvetica, sans-serif; - font-style: normal; - font-weight: normal; - user-select: none; - font-size: 30px; - text-transform: uppercase; - color: black; -} - - -.sidebar.active { - right: 0%; - opacity: 1; -} - -.back { - position: absolute; - top: -140px; - left: 50px; - transform: translate(0%, -50%); - color: black; - font-size: 60; - user-select: none; - text-transform: uppercase; - z-index: 100; - font-family: Arial, Helvetica, sans-serif; -} - - -.pathbar { - position: absolute; - top: 118px; - background: #1a1a1a; - z-index: 20; - border-radius: 0px; - width: 100%; - height: 80px; - transition: all 400ms ease 50ms; -} - -.pathname { - position: relative; - font-size: 25; - top: 50%; - width: 90%; - left: 3%; - color: whitesmoke; - transform: translate(0%, -50%); - z-index: 20; - font-family: sans-serif; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - direction: rtl; - text-align: left; - text-transform: uppercase; -} - -.homeContainer { - position: relative; - top: 200px; - height: calc(100% - 250px); - width: 90%; - overflow: scroll; - left: 5%; - background-color: lightpink; -} - -.pinButton { - position: relative; - width: 100px; - height: 100px; - font-size: 90px; - text-align: center; - left: 50%; - transform: translate(-50%, 0); - border-style: solid; - border-radius: 50px; - border-width: medium; - background-color: pink; - z-index: 100; -} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index 9c74bf24e..e1afc64e5 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -53,8 +53,6 @@ module.exports = { viewer: ['./src/debug/Viewer.tsx', 'webpack-hot-middleware/client?reload=true'], repl: ['./src/debug/Repl.tsx', 'webpack-hot-middleware/client?reload=true'], test: ['./src/debug/Test.tsx', 'webpack-hot-middleware/client?reload=true'], - inkControls: ['./src/mobile/InkControls.tsx', 'webpack-hot-middleware/client?reload=true'], - mobileInterface: ['./src/client/views/Main.tsx', 'webpack-hot-middleware/client?reload=true'], }, devtool: 'source-map', output: { @@ -119,6 +117,10 @@ module.exports = { { loader: 'sass-loader' }, ], }, + { + test: /\.(txt|d)$/i, + type: 'asset/source', + }, // -------- // SCSS MODULES - all have .module. in their name and can export to .tsx -- cgit v1.2.3-70-g09d2 From 0974c8c92e48d5d278fb9bed79bc144fd79ddb1a Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 12 Aug 2024 22:15:59 -0400 Subject: fixed typescript types module inclusion --- src/client/util/Scripting.ts | 4 +- src/client/util/type_decls.d | 224 ----------------------------------------- src/client/util/type_decls.txt | 224 ----------------------------------------- src/typings/index.d.ts | 27 ++--- src/typings/type_decls.d | 224 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 240 insertions(+), 463 deletions(-) delete mode 100644 src/client/util/type_decls.d delete mode 100644 src/client/util/type_decls.txt create mode 100644 src/typings/type_decls.d diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index b9e0943b6..c63d3d7cb 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -1,7 +1,7 @@ // export const ts = (window as any).ts; // import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts' // import * as typescriptes5 from '!!raw-loader!../../../node_modules/typescript/lib/lib.es5.d.ts' -import * as typescriptlib from './type_decls.d'; +import typescriptlib from 'type_decls.d'; import * as ts from 'typescript'; import { Doc, FieldType } from '../../fields/Doc'; import { RefField } from '../../fields/RefField'; @@ -248,7 +248,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp const funcScript = `(function(${paramString})${reqTypes} { ${body} })`; host.writeFile('file.ts', funcScript); - if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib.default); + if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); const program = ts.createProgram(['file.ts'], {}, host); const testResult = program.emit(); const outputText = host.readFile('file.js'); diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d deleted file mode 100644 index 1a93bbe59..000000000 --- a/src/client/util/type_decls.d +++ /dev/null @@ -1,224 +0,0 @@ -//@ts-ignore -declare type PropertyKey = string | number | symbol; -interface Array { - length: number; - toString(): string; - toLocaleString(): string; - pop(): T | undefined; - push(...items: T[]): number; - concat(...items: ConcatArray[]): T[]; - concat(...items: (T | ConcatArray)[]): T[]; - join(separator?: string): string; - reverse(): T[]; - shift(): T | undefined; - slice(start?: number, end?: number): T[]; - sort(compareFn?: (a: T, b: T) => number): this; - splice(start: number, deleteCount?: number): T[]; - splice(start: number, deleteCount: number, ...items: T[]): T[]; - unshift(...items: T[]): number; - indexOf(searchElement: T, fromIndex?: number): number; - lastIndexOf(searchElement: T, fromIndex?: number): number; - every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; - some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; - forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; - map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; - filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; - filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; - reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; - reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; - reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; - reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; - reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; - reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; - - [n: number]: T; -} - -interface Function { - apply(this: Function, thisArg: any, argArray?: any): any; - call(this: Function, thisArg: any, ...argArray: any[]): any; - bind(this: Function, thisArg: any, ...argArray: any[]): any; - toString(): string; - - prototype: any; - readonly length: number; - - // Non-standard extensions - arguments: any; - caller: Function; -} -interface Boolean { - valueOf(): boolean; -} -interface Number { - toString(radix?: number): string; - toFixed(fractionDigits?: number): string; - toExponential(fractionDigits?: number): string; - toPrecision(precision?: number): string; - valueOf(): number; -} -interface IArguments { - [index: number]: any; - length: number; - callee: Function; -} -interface RegExp { - readonly flags: string; - readonly sticky: boolean; - readonly unicode: boolean; -} -interface Date { - now() : string; -} -interface String { - codePointAt(pos: number): number | undefined; - includes(searchString: string, position?: number): boolean; - endsWith(searchString: string, endPosition?: number): boolean; - normalize(form: "NFC" | "NFD" | "NFKC" | "NFKD"): string; - normalize(form?: string): string; - repeat(count: number): string; - replace(a:any, b:any):string; // bcz: fix this - startsWith(searchString: string, position?: number): boolean; - anchor(name: string): string; - big(): string; - blink(): string; - bold(): string; - fixed(): string; - fontcolor(color: string): string; - fontsize(size: number): string; - fontsize(size: string): string; - italics(): string; - link(url: string): string; - small(): string; - strike(): string; - sub(): string; - sup(): string; -} -interface Object { - constructor: Function; - toString(): string; - toLocaleString(): string; - valueOf(): Object; - hasOwnProperty(v: PropertyKey): boolean; - isPrototypeOf(v: Object): boolean; - propertyIsEnumerable(v: PropertyKey): boolean; -} -interface ConcatArray { - readonly length: number; - readonly [n: number]: T; - join(separator?: string): string; - slice(start?: number, end?: number): T[]; -} -interface URL { - hash: string; - host: string; - hostname: string; - href: string; - readonly origin: string; - password: string; - pathname: string; - port: string; - protocol: string; - search: string; - username: string; - toJSON(): string; -} -interface PromiseLike { - then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): PromiseLike; -} -interface Promise { - then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; - catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; -} - -declare const Update: unique symbol; -declare const Self: unique symbol; -declare const SelfProxy: unique symbol; -declare const DataSym: unique symbol; -declare const HandleUpdate: unique symbol; -declare const Id: unique symbol; -declare const OnUpdate: unique symbol; -declare const Parent: unique symbol; -declare const Copy: unique symbol; -declare const ToScriptString: unique symbol; - -declare abstract class RefField { - readonly [Id]: FieldId; - - constructor(); -} - -declare type FieldId = string; - -declare abstract class ObjectField { - abstract [Copy](): ObjectField; -} - -declare abstract class URLField extends ObjectField { - readonly url: URL; - - constructor(url: string); - constructor(url: URL); -} - -declare class RichTextField extends URLField { - [Copy](): ObjectField; - constructor(data:string, text: string); -} -declare class AudioField extends URLField { [Copy](): ObjectField; } -declare class VideoField extends URLField { [Copy](): ObjectField; } -declare class ImageField extends URLField { [Copy](): ObjectField; } -declare class WebField extends URLField { [Copy](): ObjectField; } -declare class PdfField extends URLField { [Copy](): ObjectField; } - -declare const ComputedField: any; -declare const CompileScript: any; - -// @ts-ignore -declare type Extract = T extends U ? T : never; -declare type Field = number | string | boolean | ObjectField | RefField; -declare type FieldWaiting = T extends undefined ? never : Promise; -declare type FieldResult = Opt | FieldWaiting>; - -declare type Opt = T | undefined; -declare class Doc extends RefField { - constructor(); - - [key: string]: FieldResult; - // [ToScriptString](): string; -} - -declare class List extends ObjectField { - constructor(fields?: T[]); - [index: number]: T | (T extends RefField ? Promise : never); - [Copy](): ObjectField; -} - -declare class InkField extends ObjectField { - constructor(data:Array<{X:number, Y:number}>); - [Copy](): ObjectField; -} - -// @ts-ignore -declare const console: any; - -interface DocumentOptions { } - -declare const Docs: { - ImageDocument(url: string, options?: DocumentOptions): Doc; - VideoDocument(url: string, options?: DocumentOptions): Doc; - TextDocument(options?: DocumentOptions): Doc; - PdfDocument(url: string, options?: DocumentOptions): Doc; - WebDocument(url: string, options?: DocumentOptions): Doc; - HtmlDocument(html: string, options?: DocumentOptions): Doc; - MapDocument(url: string, options?: DocumentOptions): Doc; - KVPDocument(document: Doc, options?: DocumentOptions): Doc; - FreeformDocument(documents: Doc[], options?: DocumentOptions): Doc; - SchemaDocument(columns: string[], documents: Doc[], options?: DocumentOptions): Doc; - TreeDocument(documents: Doc[], options?: DocumentOptions): Doc; - StackingDocument(documents: Doc[], options?: DocumentOptions): Doc; -}; - -declare function idToDoc(id:string):any; -declare function assignDoc(doc:Doc, field:any, id:any):string; -declare function d(...args:any[]):any; diff --git a/src/client/util/type_decls.txt b/src/client/util/type_decls.txt deleted file mode 100644 index 1a93bbe59..000000000 --- a/src/client/util/type_decls.txt +++ /dev/null @@ -1,224 +0,0 @@ -//@ts-ignore -declare type PropertyKey = string | number | symbol; -interface Array { - length: number; - toString(): string; - toLocaleString(): string; - pop(): T | undefined; - push(...items: T[]): number; - concat(...items: ConcatArray[]): T[]; - concat(...items: (T | ConcatArray)[]): T[]; - join(separator?: string): string; - reverse(): T[]; - shift(): T | undefined; - slice(start?: number, end?: number): T[]; - sort(compareFn?: (a: T, b: T) => number): this; - splice(start: number, deleteCount?: number): T[]; - splice(start: number, deleteCount: number, ...items: T[]): T[]; - unshift(...items: T[]): number; - indexOf(searchElement: T, fromIndex?: number): number; - lastIndexOf(searchElement: T, fromIndex?: number): number; - every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; - some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; - forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; - map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; - filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; - filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; - reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; - reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; - reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; - reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; - reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; - reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; - - [n: number]: T; -} - -interface Function { - apply(this: Function, thisArg: any, argArray?: any): any; - call(this: Function, thisArg: any, ...argArray: any[]): any; - bind(this: Function, thisArg: any, ...argArray: any[]): any; - toString(): string; - - prototype: any; - readonly length: number; - - // Non-standard extensions - arguments: any; - caller: Function; -} -interface Boolean { - valueOf(): boolean; -} -interface Number { - toString(radix?: number): string; - toFixed(fractionDigits?: number): string; - toExponential(fractionDigits?: number): string; - toPrecision(precision?: number): string; - valueOf(): number; -} -interface IArguments { - [index: number]: any; - length: number; - callee: Function; -} -interface RegExp { - readonly flags: string; - readonly sticky: boolean; - readonly unicode: boolean; -} -interface Date { - now() : string; -} -interface String { - codePointAt(pos: number): number | undefined; - includes(searchString: string, position?: number): boolean; - endsWith(searchString: string, endPosition?: number): boolean; - normalize(form: "NFC" | "NFD" | "NFKC" | "NFKD"): string; - normalize(form?: string): string; - repeat(count: number): string; - replace(a:any, b:any):string; // bcz: fix this - startsWith(searchString: string, position?: number): boolean; - anchor(name: string): string; - big(): string; - blink(): string; - bold(): string; - fixed(): string; - fontcolor(color: string): string; - fontsize(size: number): string; - fontsize(size: string): string; - italics(): string; - link(url: string): string; - small(): string; - strike(): string; - sub(): string; - sup(): string; -} -interface Object { - constructor: Function; - toString(): string; - toLocaleString(): string; - valueOf(): Object; - hasOwnProperty(v: PropertyKey): boolean; - isPrototypeOf(v: Object): boolean; - propertyIsEnumerable(v: PropertyKey): boolean; -} -interface ConcatArray { - readonly length: number; - readonly [n: number]: T; - join(separator?: string): string; - slice(start?: number, end?: number): T[]; -} -interface URL { - hash: string; - host: string; - hostname: string; - href: string; - readonly origin: string; - password: string; - pathname: string; - port: string; - protocol: string; - search: string; - username: string; - toJSON(): string; -} -interface PromiseLike { - then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): PromiseLike; -} -interface Promise { - then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; - catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; -} - -declare const Update: unique symbol; -declare const Self: unique symbol; -declare const SelfProxy: unique symbol; -declare const DataSym: unique symbol; -declare const HandleUpdate: unique symbol; -declare const Id: unique symbol; -declare const OnUpdate: unique symbol; -declare const Parent: unique symbol; -declare const Copy: unique symbol; -declare const ToScriptString: unique symbol; - -declare abstract class RefField { - readonly [Id]: FieldId; - - constructor(); -} - -declare type FieldId = string; - -declare abstract class ObjectField { - abstract [Copy](): ObjectField; -} - -declare abstract class URLField extends ObjectField { - readonly url: URL; - - constructor(url: string); - constructor(url: URL); -} - -declare class RichTextField extends URLField { - [Copy](): ObjectField; - constructor(data:string, text: string); -} -declare class AudioField extends URLField { [Copy](): ObjectField; } -declare class VideoField extends URLField { [Copy](): ObjectField; } -declare class ImageField extends URLField { [Copy](): ObjectField; } -declare class WebField extends URLField { [Copy](): ObjectField; } -declare class PdfField extends URLField { [Copy](): ObjectField; } - -declare const ComputedField: any; -declare const CompileScript: any; - -// @ts-ignore -declare type Extract = T extends U ? T : never; -declare type Field = number | string | boolean | ObjectField | RefField; -declare type FieldWaiting = T extends undefined ? never : Promise; -declare type FieldResult = Opt | FieldWaiting>; - -declare type Opt = T | undefined; -declare class Doc extends RefField { - constructor(); - - [key: string]: FieldResult; - // [ToScriptString](): string; -} - -declare class List extends ObjectField { - constructor(fields?: T[]); - [index: number]: T | (T extends RefField ? Promise : never); - [Copy](): ObjectField; -} - -declare class InkField extends ObjectField { - constructor(data:Array<{X:number, Y:number}>); - [Copy](): ObjectField; -} - -// @ts-ignore -declare const console: any; - -interface DocumentOptions { } - -declare const Docs: { - ImageDocument(url: string, options?: DocumentOptions): Doc; - VideoDocument(url: string, options?: DocumentOptions): Doc; - TextDocument(options?: DocumentOptions): Doc; - PdfDocument(url: string, options?: DocumentOptions): Doc; - WebDocument(url: string, options?: DocumentOptions): Doc; - HtmlDocument(html: string, options?: DocumentOptions): Doc; - MapDocument(url: string, options?: DocumentOptions): Doc; - KVPDocument(document: Doc, options?: DocumentOptions): Doc; - FreeformDocument(documents: Doc[], options?: DocumentOptions): Doc; - SchemaDocument(columns: string[], documents: Doc[], options?: DocumentOptions): Doc; - TreeDocument(documents: Doc[], options?: DocumentOptions): Doc; - StackingDocument(documents: Doc[], options?: DocumentOptions): Doc; -}; - -declare function idToDoc(id:string):any; -declare function assignDoc(doc:Doc, field:any, id:any):string; -declare function d(...args:any[]):any; diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts index a9ebbb480..bee79a38d 100644 --- a/src/typings/index.d.ts +++ b/src/typings/index.d.ts @@ -12,13 +12,14 @@ declare module 'fit-curve'; declare module 'iink-js'; declare module 'pdfjs-dist/web/pdf_viewer'; declare module 'react-jsx-parser'; +declare module 'type_decls.d'; declare module '@react-pdf/renderer' { import * as React from 'react'; namespace ReactPDF { interface Style { - [property: string]: any; + [property: string]: unknown; } interface Styles { [key: string]: Style; @@ -32,7 +33,7 @@ declare module '@react-pdf/renderer' { keywords?: string; creator?: string; producer?: string; - onRender?: () => any; + onRender?: () => unknown; } /** @@ -213,13 +214,13 @@ declare module '@react-pdf/renderer' { src: string; loaded: boolean; loading: boolean; - data: any; - [key: string]: any; + data: unknown; + [key: string]: unknown; } - type HyphenationCallback = (words: string[], glyphString: { [key: string]: any }) => string[]; + type HyphenationCallback = (words: string[], glyphString: { [key: string]: unknown }) => string[]; const Font: { - register: (src: string, options: { family: string; [key: string]: any }) => void; + register: (src: string, options: { family: string; [key: string]: unknown }) => void; getEmojiSource: () => EmojiSource; getRegisteredFonts: () => string[]; registerEmojiSource: (emojiSource: EmojiSource) => void; @@ -252,21 +253,21 @@ declare module '@react-pdf/renderer' { }; }; - const version: any; + const version: unknown; - const PDFRenderer: any; + const PDFRenderer: unknown; const createInstance: ( element: { type: string; - props: { [key: string]: any }; + props: { [key: string]: unknown }; }, - root?: any - ) => any; + root?: unknown + ) => unknown; const pdf: (document: React.ReactElement) => { isDirty: () => boolean; - updateContainer: (document: React.ReactElement) => void; + updateContainer: (document: React.ReactElement) => void; toBuffer: () => NodeJS.ReadableStream; toBlob: () => Blob; toString: () => string; @@ -274,7 +275,7 @@ declare module '@react-pdf/renderer' { const renderToStream: (document: React.ReactElement) => NodeJS.ReadableStream; - const renderToFile: (document: React.ReactElement, filePath: string, callback?: (output: NodeJS.ReadableStream, filePath: string) => any) => Promise; + const renderToFile: (document: React.ReactElement, filePath: string, callback?: (output: NodeJS.ReadableStream, filePath: string) => unknown) => Promise; const render: typeof renderToFile; } diff --git a/src/typings/type_decls.d b/src/typings/type_decls.d new file mode 100644 index 000000000..1a93bbe59 --- /dev/null +++ b/src/typings/type_decls.d @@ -0,0 +1,224 @@ +//@ts-ignore +declare type PropertyKey = string | number | symbol; +interface Array { + length: number; + toString(): string; + toLocaleString(): string; + pop(): T | undefined; + push(...items: T[]): number; + concat(...items: ConcatArray[]): T[]; + concat(...items: (T | ConcatArray)[]): T[]; + join(separator?: string): string; + reverse(): T[]; + shift(): T | undefined; + slice(start?: number, end?: number): T[]; + sort(compareFn?: (a: T, b: T) => number): this; + splice(start: number, deleteCount?: number): T[]; + splice(start: number, deleteCount: number, ...items: T[]): T[]; + unshift(...items: T[]): number; + indexOf(searchElement: T, fromIndex?: number): number; + lastIndexOf(searchElement: T, fromIndex?: number): number; + every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; + some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; + forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; + map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; + filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; + filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; + reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; + reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; + reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; + reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; + reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; + reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; + + [n: number]: T; +} + +interface Function { + apply(this: Function, thisArg: any, argArray?: any): any; + call(this: Function, thisArg: any, ...argArray: any[]): any; + bind(this: Function, thisArg: any, ...argArray: any[]): any; + toString(): string; + + prototype: any; + readonly length: number; + + // Non-standard extensions + arguments: any; + caller: Function; +} +interface Boolean { + valueOf(): boolean; +} +interface Number { + toString(radix?: number): string; + toFixed(fractionDigits?: number): string; + toExponential(fractionDigits?: number): string; + toPrecision(precision?: number): string; + valueOf(): number; +} +interface IArguments { + [index: number]: any; + length: number; + callee: Function; +} +interface RegExp { + readonly flags: string; + readonly sticky: boolean; + readonly unicode: boolean; +} +interface Date { + now() : string; +} +interface String { + codePointAt(pos: number): number | undefined; + includes(searchString: string, position?: number): boolean; + endsWith(searchString: string, endPosition?: number): boolean; + normalize(form: "NFC" | "NFD" | "NFKC" | "NFKD"): string; + normalize(form?: string): string; + repeat(count: number): string; + replace(a:any, b:any):string; // bcz: fix this + startsWith(searchString: string, position?: number): boolean; + anchor(name: string): string; + big(): string; + blink(): string; + bold(): string; + fixed(): string; + fontcolor(color: string): string; + fontsize(size: number): string; + fontsize(size: string): string; + italics(): string; + link(url: string): string; + small(): string; + strike(): string; + sub(): string; + sup(): string; +} +interface Object { + constructor: Function; + toString(): string; + toLocaleString(): string; + valueOf(): Object; + hasOwnProperty(v: PropertyKey): boolean; + isPrototypeOf(v: Object): boolean; + propertyIsEnumerable(v: PropertyKey): boolean; +} +interface ConcatArray { + readonly length: number; + readonly [n: number]: T; + join(separator?: string): string; + slice(start?: number, end?: number): T[]; +} +interface URL { + hash: string; + host: string; + hostname: string; + href: string; + readonly origin: string; + password: string; + pathname: string; + port: string; + protocol: string; + search: string; + username: string; + toJSON(): string; +} +interface PromiseLike { + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): PromiseLike; +} +interface Promise { + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; +} + +declare const Update: unique symbol; +declare const Self: unique symbol; +declare const SelfProxy: unique symbol; +declare const DataSym: unique symbol; +declare const HandleUpdate: unique symbol; +declare const Id: unique symbol; +declare const OnUpdate: unique symbol; +declare const Parent: unique symbol; +declare const Copy: unique symbol; +declare const ToScriptString: unique symbol; + +declare abstract class RefField { + readonly [Id]: FieldId; + + constructor(); +} + +declare type FieldId = string; + +declare abstract class ObjectField { + abstract [Copy](): ObjectField; +} + +declare abstract class URLField extends ObjectField { + readonly url: URL; + + constructor(url: string); + constructor(url: URL); +} + +declare class RichTextField extends URLField { + [Copy](): ObjectField; + constructor(data:string, text: string); +} +declare class AudioField extends URLField { [Copy](): ObjectField; } +declare class VideoField extends URLField { [Copy](): ObjectField; } +declare class ImageField extends URLField { [Copy](): ObjectField; } +declare class WebField extends URLField { [Copy](): ObjectField; } +declare class PdfField extends URLField { [Copy](): ObjectField; } + +declare const ComputedField: any; +declare const CompileScript: any; + +// @ts-ignore +declare type Extract = T extends U ? T : never; +declare type Field = number | string | boolean | ObjectField | RefField; +declare type FieldWaiting = T extends undefined ? never : Promise; +declare type FieldResult = Opt | FieldWaiting>; + +declare type Opt = T | undefined; +declare class Doc extends RefField { + constructor(); + + [key: string]: FieldResult; + // [ToScriptString](): string; +} + +declare class List extends ObjectField { + constructor(fields?: T[]); + [index: number]: T | (T extends RefField ? Promise : never); + [Copy](): ObjectField; +} + +declare class InkField extends ObjectField { + constructor(data:Array<{X:number, Y:number}>); + [Copy](): ObjectField; +} + +// @ts-ignore +declare const console: any; + +interface DocumentOptions { } + +declare const Docs: { + ImageDocument(url: string, options?: DocumentOptions): Doc; + VideoDocument(url: string, options?: DocumentOptions): Doc; + TextDocument(options?: DocumentOptions): Doc; + PdfDocument(url: string, options?: DocumentOptions): Doc; + WebDocument(url: string, options?: DocumentOptions): Doc; + HtmlDocument(html: string, options?: DocumentOptions): Doc; + MapDocument(url: string, options?: DocumentOptions): Doc; + KVPDocument(document: Doc, options?: DocumentOptions): Doc; + FreeformDocument(documents: Doc[], options?: DocumentOptions): Doc; + SchemaDocument(columns: string[], documents: Doc[], options?: DocumentOptions): Doc; + TreeDocument(documents: Doc[], options?: DocumentOptions): Doc; + StackingDocument(documents: Doc[], options?: DocumentOptions): Doc; +}; + +declare function idToDoc(id:string):any; +declare function assignDoc(doc:Doc, field:any, id:any):string; +declare function d(...args:any[]):any; -- cgit v1.2.3-70-g09d2 From 5c7964173d80752200727d8340825210c2704265 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 13 Aug 2024 10:42:24 -0400 Subject: removed youtube query calls --- src/server/websocket.ts | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/server/websocket.ts b/src/server/websocket.ts index 821607df5..4a127f099 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -8,7 +8,7 @@ import { logPort } from './ActionUtilities'; import { Client } from './Client'; import { DashStats } from './DashStats'; import { DocumentsCollection } from './IDatabase'; -import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent, YoutubeQueryInput, YoutubeQueryTypes } from './Message'; +import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent } from './Message'; import { Search } from './Search'; import { resolvedPorts, socketMap, timeMap, userOperations } from './SocketData'; import { GoogleCredentialsLoader } from './apis/google/CredentialsLoader'; @@ -39,22 +39,6 @@ export namespace WebSocket { socket.broadcast.emit('receiveMobileDocumentUpload', content); } - function HandleYoutubeQuery([query, callback]: [YoutubeQueryInput, (result?: any[]) => void]) { - const { ProjectCredentials } = GoogleCredentialsLoader; - switch (query.type) { - case YoutubeQueryTypes.Channels: - YoutubeApi.authorizedGetChannel(ProjectCredentials); - break; - case YoutubeQueryTypes.SearchVideo: - YoutubeApi.authorizedGetVideos(ProjectCredentials, query.userInput, callback); - break; - case YoutubeQueryTypes.VideoDetails: - YoutubeApi.authorizedGetVideoDetails(ProjectCredentials, query.videoIds, callback); - break; - default: - } - } - export async function doDelete(onlyFields = true) { const target: string[] = []; onlyFields && target.push(DocumentsCollection); @@ -448,7 +432,6 @@ export namespace WebSocket { } ServerUtils.AddServerHandler(socket, MessageStore.CreateField, CreateField); - ServerUtils.AddServerHandlerCallback(socket, MessageStore.YoutubeApiQuery, HandleYoutubeQuery); ServerUtils.AddServerHandler(socket, MessageStore.UpdateField, diff => UpdateField(socket, diff)); ServerUtils.AddServerHandler(socket, MessageStore.DeleteField, id => DeleteField(socket, id)); ServerUtils.AddServerHandler(socket, MessageStore.DeleteFields, ids => DeleteFields(socket, ids)); -- cgit v1.2.3-70-g09d2 From ef79ab121c881d3e6a2982ce2e01da40294af656 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 13 Aug 2024 10:44:53 -0400 Subject: from last --- src/server/Message.ts | 18 +++--------------- src/server/Search.ts | 1 + src/server/websocket.ts | 4 +--- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/server/Message.ts b/src/server/Message.ts index 03150c841..8e30cd6df 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -47,19 +47,7 @@ export enum Types { export interface Transferable { readonly id: string; readonly type: Types; - readonly data?: any; -} - -export enum YoutubeQueryTypes { - Channels, - SearchVideo, - VideoDetails, -} - -export interface YoutubeQueryInput { - readonly type: YoutubeQueryTypes; - readonly userInput?: string; - readonly videoIds?: string; + readonly data?: unknown; } export interface Reference { @@ -99,6 +87,7 @@ export interface RoomMessage { readonly room: string; } +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace MessageStore { export const Foo = new Message('Foo'); export const Bar = new Message('Bar'); @@ -106,7 +95,7 @@ export namespace MessageStore { export const GetField = new Message('Get Field'); // send string 'id' get Transferable back export const GetFields = new Message('Get Fields'); // send string[] of 'id' get Transferable[] back export const GetDocument = new Message('Get Document'); - export const DeleteAll = new Message('Delete All'); + export const DeleteAll = new Message('Delete All'); export const ConnectionTerminated = new Message('Connection Terminated'); export const GesturePoints = new Message('Gesture Points'); @@ -118,7 +107,6 @@ export namespace MessageStore { export const GetRefFields = new Message('Get Ref Fields'); export const UpdateField = new Message('Update Ref Field'); export const CreateField = new Message('Create Ref Field'); - export const YoutubeApiQuery = new Message('Youtube Api Query'); export const DeleteField = new Message('Delete field'); export const DeleteFields = new Message('Delete fields'); diff --git a/src/server/Search.ts b/src/server/Search.ts index b21ee853a..06af18776 100644 --- a/src/server/Search.ts +++ b/src/server/Search.ts @@ -3,6 +3,7 @@ import * as rp from 'request-promise'; const pathTo = (relative: string) => `http://localhost:8983/solr/dash/${relative}`; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Search { export async function updateDocument(document: any) { try { diff --git a/src/server/websocket.ts b/src/server/websocket.ts index 4a127f099..905dbcf57 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -11,8 +11,6 @@ import { DocumentsCollection } from './IDatabase'; import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent } from './Message'; import { Search } from './Search'; import { resolvedPorts, socketMap, timeMap, userOperations } from './SocketData'; -import { GoogleCredentialsLoader } from './apis/google/CredentialsLoader'; -import YoutubeApi from './apis/youtube/youtubeApiSample'; import { initializeGuest } from './authentication/DashUserModel'; import { Database } from './database'; @@ -77,7 +75,7 @@ export namespace WebSocket { Database.Instance.update(newValue.id, newValue, () => socket.broadcast.emit(MessageStore.SetField.Message, newValue)); // broadcast set value to all other clients if (newValue.type === Types.Text) { // if the newValue has sring type, then it's suitable for searching -- pass it to SOLR - Search.updateDocument({ id: newValue.id, data: { set: (newValue as any).data } }); + Search.updateDocument({ id: newValue.id, data: { set: newValue.data } }); } } -- cgit v1.2.3-70-g09d2 From 4d45f8a046ce5300f0b046457a381d219eef3363 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 13 Aug 2024 15:14:05 -0400 Subject: cleaning up database types --- src/client/DocServer.ts | 21 +------- src/client/views/GestureOverlay.tsx | 5 -- src/fields/Doc.ts | 3 +- src/fields/ObjectField.ts | 15 ++++-- src/fields/util.ts | 20 ++++---- src/server/IDatabase.ts | 8 ++-- src/server/MemoryDatabase.ts | 6 +-- src/server/Message.ts | 66 +------------------------- src/server/apis/google/GoogleApiServerUtils.ts | 1 + src/server/database.ts | 12 +++-- src/server/server_Initialization.ts | 7 ++- 11 files changed, 44 insertions(+), 120 deletions(-) diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index 2bf3a6f9f..33fa928f2 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -8,7 +8,7 @@ import { UpdatingFromServer } from '../fields/DocSymbols'; import { FieldLoader } from '../fields/FieldLoader'; import { HandleUpdate, Id, Parent } from '../fields/FieldSymbols'; import { ObjectField, serverOpType } from '../fields/ObjectField'; -import { GestureContent, Message, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent } from '../server/Message'; +import { Message, MessageStore } from '../server/Message'; import { SerializationHelper } from './util/SerializationHelper'; /** @@ -109,25 +109,6 @@ export namespace DocServer { } } - export namespace Mobile { - export function dispatchGesturePoints(content: GestureContent) { - DocServer.Emit(_socket, MessageStore.GesturePoints, content); - } - - export function dispatchOverlayTrigger(content: MobileInkOverlayContent) { - // _socket.emit("dispatchBoxTrigger"); - DocServer.Emit(_socket, MessageStore.MobileInkOverlayTrigger, content); - } - - export function dispatchOverlayPositionUpdate(content: UpdateMobileInkOverlayPositionContent) { - DocServer.Emit(_socket, MessageStore.UpdateMobileInkOverlayPosition, content); - } - - export function dispatchMobileDocumentUpload(content: MobileDocumentUploadContent) { - DocServer.Emit(_socket, MessageStore.MobileDocumentUpload, content); - } - } - const instructions = 'This page will automatically refresh after this alert is closed. Expect to reconnect after about 30 seconds.'; function alertUser(connectionTerminationReason: string) { switch (connectionTerminationReason) { diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index bcd4d1ee5..3a2738c3b 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -21,10 +21,8 @@ import { SetActiveInkColor, SetActiveInkWidth, } from './nodes/DocumentView'; -// import MobileInkOverlay from '../../mobile/MobileInkOverlay'; import { Gestures } from '../../pen-gestures/GestureTypes'; import { GestureUtils } from '../../pen-gestures/GestureUtils'; -// import { MobileInkOverlayContent } from '../../server/Message'; import { InteractionUtils } from '../util/InteractionUtils'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; import { Transform } from '../util/Transform'; @@ -71,8 +69,6 @@ export class GestureOverlay extends ObservableReactComponent(); private _d1: Doc | undefined; private _inkToTextDoc: Doc | undefined; @@ -485,7 +481,6 @@ export class GestureOverlay extends ObservableReactComponent - {/* {this.showMobileInkOverlay ? : null} */} {this.elements}
void | Promise } = {}; public [Initializing]: boolean = false; - public [FieldChanged] = (diff: { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: unknown } | undefined, serverOp: serverOpType) => { + public [FieldChanged] = (diff: { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: { start: number; deleteCount: number } } | undefined, serverOp: serverOpType) => { if (!this[UpdatingFromServer] || this[ForceServerWrite]) { DocServer.UpdateField(this[Id], serverOp); } diff --git a/src/fields/ObjectField.ts b/src/fields/ObjectField.ts index 21c4af608..5f31208eb 100644 --- a/src/fields/ObjectField.ts +++ b/src/fields/ObjectField.ts @@ -2,11 +2,18 @@ import { ScriptingGlobals } from '../client/util/ScriptingGlobals'; import { Copy, FieldChanged, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols'; import { RefField } from './RefField'; +export type serializedFieldType = { fieldId: string; heading?: string; __type: string }; +export type serializedFieldsType = { [key: string]: { fields: serializedFieldType[] } }; +export interface serializedDoctype { + readonly id: string; + readonly fields?: serializedFieldsType; +} + export type serverOpType = { - $set?: { [key: string]: unknown }; // + $set?: serializedFieldsType; // $unset?: { [key: string]: unknown }; - $remFromSet?: { [key: string]: unknown }; - $addToSet?: { [key: string]: unknown }; + $remFromSet?: { [key: string]: { fields: serializedFieldType[] } | { deleteCount: number; start: number } | undefined; hint?: { deleteCount: number; start: number } }; + $addToSet?: serializedFieldsType; length?: number; }; export abstract class ObjectField { @@ -15,7 +22,7 @@ export abstract class ObjectField { // eslint-disable-next-line no-use-before-define items: FieldType[] | undefined; length: number | undefined; - hint?: unknown }, + hint?: { deleteCount: number, start: number} }, serverOp?: serverOpType) => void; // eslint-disable-next-line no-use-before-define public [Parent]?: RefField | ObjectField; diff --git a/src/fields/util.ts b/src/fields/util.ts index 69ece82a2..a5c56607c 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -8,7 +8,7 @@ import { Doc, DocListCast, FieldType, FieldResult, HierarchyMapping, ReverseHier import { AclAdmin, AclAugment, AclEdit, AclPrivate, DirectLinks, DocAcl, DocData, DocLayout, FieldKeys, ForceServerWrite, Height, Initializing, SelfProxy, UpdatingFromServer, Width } from './DocSymbols'; import { FieldChanged, Id, Parent, ToValue } from './FieldSymbols'; import { List, ListImpl } from './List'; -import { ObjectField } from './ObjectField'; +import { ObjectField, serializedFieldType, serverOpType } from './ObjectField'; import { PrefetchProxy, ProxyField } from './Proxy'; import { RefField } from './RefField'; import { RichTextField } from './RichTextField'; @@ -112,9 +112,9 @@ const _setterImpl = action((target: Doc | ListImpl, prop: string | sy if (writeToServer) { // prettier-ignore - if (value === undefined) + if (value === undefined || value === null) (target as Doc|ObjectField)[FieldChanged]?.(undefined, { $unset: { ['fields.' + prop]: '' } }); - else (target as Doc|ObjectField)[FieldChanged]?.(undefined, { $set: { ['fields.' + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) :value}}); + else (target as Doc|ObjectField)[FieldChanged]?.(undefined, { $set: { ['fields.' + prop]: (value instanceof ObjectField ? SerializationHelper.Serialize(value) :value) as { fields: serializedFieldType[]}}}); if (prop === 'author' || prop.toString().startsWith('acl_')) updateCachedAcls(target); } else if (receiver instanceof Doc) { DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue); @@ -393,15 +393,15 @@ export function deleteProperty(target: Doc | ListImpl, prop: string | // able to undo and redo the partial change. // export function containedFieldChangedHandler(container: ListImpl | Doc, prop: string | number, liveContainedField: ObjectField) { - let lastValue: FieldResult = liveContainedField instanceof ObjectField ? ObjectField.MakeCopy(liveContainedField) : liveContainedField; - return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: (FieldType & { value?: FieldType })[] | undefined; length: number | undefined; hint?: unknown } /* , dummyServerOp?: any */) => { - const serializeItems = () => ({ __type: 'list', fields: diff?.items?.map((item: FieldType) => SerializationHelper.Serialize(item)) }); + let lastValue = ObjectField.MakeCopy(liveContainedField); + return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: (FieldType & { value?: FieldType })[] | undefined; length: number | undefined; hint?: { start: number; deleteCount: number } } /* , dummyServerOp?: any */) => { + const serializeItems = () => ({ __type: 'list', fields: diff?.items?.map((item: FieldType) => SerializationHelper.Serialize(item) as serializedFieldType) ?? [] }); // prettier-ignore - const serverOp = diff?.op === '$addToSet' + const serverOp: serverOpType = diff?.op === '$addToSet' ? { $addToSet: { ['fields.' + prop]: serializeItems() }, length: diff.length } : diff?.op === '$remFromSet' ? { $remFromSet: { ['fields.' + prop]: serializeItems(), hint: diff.hint}, length: diff.length } - : { $set: { ['fields.' + prop]: liveContainedField ? SerializationHelper.Serialize(liveContainedField) as FieldType : undefined } }; + : { $set: { ['fields.' + prop]: SerializationHelper.Serialize(liveContainedField) as {fields: serializedFieldType[]}} }; if (!(container instanceof Doc) || !container[UpdatingFromServer]) { const cont = container as { [key: string | number]: FieldType }; @@ -477,13 +477,13 @@ export function containedFieldChangedHandler(container: ListImpl | Do // console.log('redo list: ' + prop, fieldVal()); // bcz: uncomment to log undo setFieldVal(ObjectField.MakeCopy(newValue)); const containerProp = cont[prop]; - lastValue = containerProp instanceof ObjectField && ObjectField.MakeCopy(containerProp); + if (containerProp instanceof ObjectField) lastValue = ObjectField.MakeCopy(containerProp); }, undo: () => { // console.log('undo list: ' + prop, fieldVal()); // bcz: uncomment to log undo setFieldVal(ObjectField.MakeCopy(prevValue)); const containerProp = cont[prop]; - lastValue = containerProp instanceof ObjectField && ObjectField.MakeCopy(containerProp); + if (containerProp instanceof ObjectField) lastValue = ObjectField.MakeCopy(containerProp); }, prop: 'set list field', }, diff --git a/src/server/IDatabase.ts b/src/server/IDatabase.ts index 2274792b3..481b64d4a 100644 --- a/src/server/IDatabase.ts +++ b/src/server/IDatabase.ts @@ -1,5 +1,5 @@ import * as mongodb from 'mongodb'; -import { Transferable } from './Message'; +import { serializedDoctype } from '../fields/ObjectField'; export const DocumentsCollection = 'documents'; export interface IDatabase { @@ -13,10 +13,10 @@ export interface IDatabase { dropSchema(...schemaNames: string[]): Promise; - insert(value: any, collectionName?: string): Promise; + insert(value: { _id: string }, collectionName?: string): Promise; - getDocument(id: string, fn: (result?: Transferable) => void, collectionName?: string): void; - getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName?: string): void; + getDocument(id: string, fn: (result?: serializedDoctype) => void, collectionName?: string): void; + getDocuments(ids: string[], fn: (result: serializedDoctype[]) => void, collectionName?: string): void; getCollectionNames(): Promise; visit(ids: string[], fn: (result: any) => string[] | Promise, collectionName?: string): Promise; diff --git a/src/server/MemoryDatabase.ts b/src/server/MemoryDatabase.ts index 1432d91c4..b838cb61b 100644 --- a/src/server/MemoryDatabase.ts +++ b/src/server/MemoryDatabase.ts @@ -1,6 +1,6 @@ import * as mongodb from 'mongodb'; +import { serializedDoctype } from '../fields/ObjectField'; import { DocumentsCollection, IDatabase } from './IDatabase'; -import { Transferable } from './Message'; export class MemoryDatabase implements IDatabase { private db: { [collectionName: string]: { [id: string]: any } } = {}; @@ -81,10 +81,10 @@ export class MemoryDatabase implements IDatabase { return Promise.resolve(); } - public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = DocumentsCollection): void { + public getDocument(id: string, fn: (result?: serializedDoctype) => void, collectionName = DocumentsCollection): void { fn(this.getCollection(collectionName)[id]); } - public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = DocumentsCollection): void { + public getDocuments(ids: string[], fn: (result: serializedDoctype[]) => void, collectionName = DocumentsCollection): void { fn(ids.map(id => this.getCollection(collectionName)[id])); } diff --git a/src/server/Message.ts b/src/server/Message.ts index 03150c841..26b41539b 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -1,5 +1,6 @@ import * as uuid from 'uuid'; import { Point } from '../pen-gestures/ndollar'; +import { serverOpType } from '../fields/ObjectField'; function GenerateDeterministicGuid(seed: string): string { return uuid.v5(seed, uuid.v5.URL); @@ -22,52 +23,12 @@ export class Message { } } -export enum Types { - Number, - List, - Key, - Image, - Web, - Document, - Text, - Icon, - RichText, - DocumentReference, - Html, - Video, - Audio, - Ink, - PDF, - Tuple, - Boolean, - Script, - Templates, -} - -export interface Transferable { - readonly id: string; - readonly type: Types; - readonly data?: any; -} - -export enum YoutubeQueryTypes { - Channels, - SearchVideo, - VideoDetails, -} - -export interface YoutubeQueryInput { - readonly type: YoutubeQueryTypes; - readonly userInput?: string; - readonly videoIds?: string; -} - export interface Reference { readonly id: string; } export interface Diff extends Reference { - readonly diff: any; + readonly diff: serverOpType; } export interface GestureContent { @@ -77,23 +38,6 @@ export interface GestureContent { readonly color?: string; } -export interface MobileInkOverlayContent { - readonly enableOverlay: boolean; - readonly width?: number; - readonly height?: number; - readonly text?: string; -} - -export interface UpdateMobileInkOverlayPositionContent { - readonly dx?: number; - readonly dy?: number; - readonly dsize?: number; -} - -export interface MobileDocumentUploadContent { - readonly docId: string; -} - export interface RoomMessage { readonly message: string; readonly room: string; @@ -102,17 +46,11 @@ export interface RoomMessage { export namespace MessageStore { export const Foo = new Message('Foo'); export const Bar = new Message('Bar'); - export const SetField = new Message('Set Field'); // send Transferable (no reply) - export const GetField = new Message('Get Field'); // send string 'id' get Transferable back - export const GetFields = new Message('Get Fields'); // send string[] of 'id' get Transferable[] back export const GetDocument = new Message('Get Document'); export const DeleteAll = new Message('Delete All'); export const ConnectionTerminated = new Message('Connection Terminated'); export const GesturePoints = new Message('Gesture Points'); - export const MobileInkOverlayTrigger = new Message('Trigger Mobile Ink Overlay'); - export const UpdateMobileInkOverlayPosition = new Message('Update Mobile Ink Overlay Position'); - export const MobileDocumentUpload = new Message('Upload Document From Mobile'); export const GetRefField = new Message('Get Ref Field'); export const GetRefFields = new Message('Get Ref Fields'); diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts index d3acc968b..47206f415 100644 --- a/src/server/apis/google/GoogleApiServerUtils.ts +++ b/src/server/apis/google/GoogleApiServerUtils.ts @@ -21,6 +21,7 @@ const scope = ['documents.readonly', 'documents', 'presentations', 'presentation * This namespace manages server side authentication for Google API queries, either * from the standard v1 APIs or the Google Photos REST API. */ +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace GoogleApiServerUtils { /** * As we expand out to more Google APIs that are accessible from diff --git a/src/server/database.ts b/src/server/database.ts index ff8584cd7..a93117349 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import * as mongodb from 'mongodb'; import * as mongoose from 'mongoose'; import { Opt } from '../fields/Doc'; @@ -5,11 +6,11 @@ import { emptyFunction, Utils } from '../Utils'; import { GoogleApiServerUtils } from './apis/google/GoogleApiServerUtils'; import { DocumentsCollection, IDatabase } from './IDatabase'; import { MemoryDatabase } from './MemoryDatabase'; -import { Transferable } from './Message'; import { Upload } from './SharedMediaTypes'; +import { serializedDoctype } from '../fields/ObjectField'; export namespace Database { - export let disconnect: Function; + export let disconnect: () => void; class DocSchema implements mongodb.BSON.Document { _id!: string; @@ -84,6 +85,7 @@ export namespace Database { if (this.db) { const collection = this.db.collection(collectionName); const prom = this.currentWrites[id]; + // eslint-disable-next-line prefer-const let newProm: Promise; const run = (): Promise => new Promise(resolve => { @@ -112,6 +114,7 @@ export namespace Database { if (this.db) { const collection = this.db.collection(collectionName); const prom = this.currentWrites[id]; + // eslint-disable-next-line prefer-const let newProm: Promise; const run = (): Promise => new Promise(resolve => { @@ -196,6 +199,7 @@ export namespace Database { const id = value._id; const collection = this.db.collection(collectionName); const prom = this.currentWrites[id]; + // eslint-disable-next-line prefer-const let newProm: Promise; const run = (): Promise => new Promise(resolve => { @@ -219,7 +223,7 @@ export namespace Database { return undefined; } - public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = DocumentsCollection) { + public getDocument(id: string, fn: (result?: serializedDoctype) => void, collectionName = DocumentsCollection) { if (this.db) { const collection = this.db.collection(collectionName); collection.findOne({ _id: id }).then(resultIn => { @@ -237,7 +241,7 @@ export namespace Database { } } - public async getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = DocumentsCollection) { + public async getDocuments(ids: string[], fn: (result: serializedDoctype[]) => void, collectionName = DocumentsCollection) { if (this.db) { const found = await this.db .collection(collectionName) diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index 9183688c6..2190e27c7 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -29,7 +29,6 @@ import { WebSocket } from './websocket'; export type RouteSetter = (server: RouteManager) => void; // export let disconnect: Function; -// eslint-disable-next-line import/no-mutable-exports export let resolvedServerUrl: string; const week = 7 * 24 * 60 * 60 * 1000; @@ -115,12 +114,12 @@ function registerEmbeddedBrowseRelativePathHandler(server: express.Express) { } function proxyServe(req: any, requrl: string, response: any) { - // eslint-disable-next-line global-require + // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires const htmlBodyMemoryStream = new (require('memorystream'))(); let wasinBrFormat = false; const sendModifiedBody = () => { const header = response.headers['content-encoding']; - const refToCors = (match: any, tag: string, sym: string, href: string) => `${tag}=${sym + resolvedServerUrl}/corsProxy/${href + sym}`; + const refToCors = (match: string, tag: string, sym: string, href: string) => `${tag}=${sym + resolvedServerUrl}/corsProxy/${href + sym}`; // const relpathToCors = (match: any, href: string, offset: any, string: any) => `="${resolvedServerUrl + '/corsProxy/' + decodeURIComponent(req.originalUrl.split('/corsProxy/')[1].match(/https?:\/\/[^\/]*/)?.[0] ?? '') + '/' + href}"`; if (header) { try { @@ -238,7 +237,7 @@ function registerAuthenticationRoutes(server: express.Express) { export default async function InitializeServer(routeSetter: RouteSetter) { const isRelease = determineEnvironment(); const app = buildWithMiddleware(express()); - const compiler = webpack(config as any); + const compiler = webpack(config as webpack.Configuration); // route table managed by express. routes are tested sequentially against each of these map rules. when a match is found, the handler is called to process the request app.use(wdm(compiler, { publicPath: config.output.publicPath })); -- cgit v1.2.3-70-g09d2 From a0774ccdd2de7953b9822df2e106d7395cc0f216 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 13 Aug 2024 15:31:42 -0400 Subject: updated list ops on server --- src/server/websocket.ts | 244 ++++++++++++++++++------------------------------ 1 file changed, 89 insertions(+), 155 deletions(-) diff --git a/src/server/websocket.ts b/src/server/websocket.ts index 905dbcf57..f10455680 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -3,13 +3,14 @@ import { createServer } from 'https'; import * as _ from 'lodash'; import { networkInterfaces } from 'os'; import { Server, Socket } from 'socket.io'; +import { SecureContextOptions } from 'tls'; import { ServerUtils } from '../ServerUtils'; +import { serializedDoctype, serializedFieldsType } from '../fields/ObjectField'; import { logPort } from './ActionUtilities'; import { Client } from './Client'; import { DashStats } from './DashStats'; import { DocumentsCollection } from './IDatabase'; -import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent } from './Message'; -import { Search } from './Search'; +import { Diff, GestureContent, MessageStore } from './Message'; import { resolvedPorts, socketMap, timeMap, userOperations } from './SocketData'; import { initializeGuest } from './authentication/DashUserModel'; import { Database } from './database'; @@ -25,25 +26,10 @@ export namespace WebSocket { socket.broadcast.emit('receiveGesturePoints', content); } - function processOverlayTrigger(socket: Socket, content: MobileInkOverlayContent) { - socket.broadcast.emit('receiveOverlayTrigger', content); - } - - function processUpdateOverlayPosition(socket: Socket, content: UpdateMobileInkOverlayPositionContent) { - socket.broadcast.emit('receiveUpdateOverlayPosition', content); - } - - function processMobileDocumentUpload(socket: Socket, content: MobileDocumentUploadContent) { - socket.broadcast.emit('receiveMobileDocumentUpload', content); - } - export async function doDelete(onlyFields = true) { const target: string[] = []; onlyFields && target.push(DocumentsCollection); await Database.Instance.dropSchema(...target); - if (process.env.DISABLE_SEARCH !== 'true') { - await Search.clear(); - } initializeGuest(); } @@ -63,31 +49,15 @@ export namespace WebSocket { DashStats.logUserLogin(userEmail); } - function getField([id, callback]: [string, (result?: Transferable) => void]) { - Database.Instance.getDocument(id, (result?: Transferable) => callback(result)); - } - - function getFields([ids, callback]: [string[], (result: Transferable[]) => void]) { - Database.Instance.getDocuments(ids, callback); - } - - function setField(socket: Socket, newValue: Transferable) { - Database.Instance.update(newValue.id, newValue, () => socket.broadcast.emit(MessageStore.SetField.Message, newValue)); // broadcast set value to all other clients - if (newValue.type === Types.Text) { - // if the newValue has sring type, then it's suitable for searching -- pass it to SOLR - Search.updateDocument({ id: newValue.id, data: { set: newValue.data } }); - } - } - - function GetRefFieldLocal([id, callback]: [string, (result?: Transferable) => void]) { + function GetRefFieldLocal([id, callback]: [string, (result?: serializedDoctype) => void]) { return Database.Instance.getDocument(id, callback); } - function GetRefField([id, callback]: [string, (result?: Transferable) => void]) { + function GetRefField([id, callback]: [string, (result?: serializedDoctype) => void]) { process.stdout.write(`+`); GetRefFieldLocal([id, callback]); } - function GetRefFields([ids, callback]: [string[], (result?: Transferable[]) => void]) { + function GetRefFields([ids, callback]: [string[], (result?: serializedDoctype[]) => void]) { process.stdout.write(`${ids.length}…`); Database.Instance.getDocuments(ids, callback); } @@ -151,11 +121,11 @@ export namespace WebSocket { const { diff, socket } = next; if (diff.diff.$addToSet) { // eslint-disable-next-line no-use-before-define - return GetRefFieldLocal([diff.id, (result?: Transferable) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own + return GetRefFieldLocal([diff.id, (result?: serializedDoctype) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own } if (diff.diff.$remFromSet) { // eslint-disable-next-line no-use-before-define - return GetRefFieldLocal([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own + return GetRefFieldLocal([diff.id, (result?: serializedDoctype) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own } // eslint-disable-next-line no-use-before-define return SetField(socket, diff); @@ -163,37 +133,41 @@ export namespace WebSocket { return !pendingOps.get(id)!.length && pendingOps.delete(id); } - function addToListField(socket: Socket, diffIn: Diff, curListItems?: Transferable): void { + function addToListField(socket: Socket, diffIn: Diff, listDoc?: serializedDoctype): void { const diff = diffIn; diff.diff.$set = diff.diff.$addToSet; delete diff.diff.$addToSet; // convert add to set to a query of the current fields, and then a set of the composition of the new fields with the old ones - const updatefield = Array.from(Object.keys(diff.diff.$set))[0]; - const newListItems = diff.diff.$set[updatefield]?.fields; + const updatefield = Array.from(Object.keys(diff.diff.$set ?? {}))[0]; + const newListItems = diff.diff.$set?.[updatefield]?.fields; if (!newListItems) { console.log('Error: addToListField - no new list items'); return; } - const curList = (curListItems as any)?.fields?.[updatefield.replace('fields.', '')]?.fields.filter((item: any) => item !== undefined) || []; - diff.diff.$set[updatefield].fields = [...curList, ...newListItems]; // , ...newListItems.filter((newItem: any) => newItem === null || !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))]; - const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length; - delete diff.diff.length; - Database.Instance.update( - diff.id, - diff.diff, - () => { - if (sendBack) { - console.log('Warning: list modified during update. Composite list is being returned.'); - const { id } = socket; - (socket as any).id = ''; // bcz: HACK. this prevents the update message from going back to the client that made the change. - socket.broadcast.emit(MessageStore.UpdateField.Message, diff); - (socket as any).id = id; - } else { - socket.broadcast.emit(MessageStore.UpdateField.Message, diff); - } - dispatchNextOp(diff.id); - }, - false - ); + const listItems = listDoc?.fields?.[updatefield.replace('fields.', '')]?.fields.filter(item => item !== undefined) ?? []; + if (diff.diff.$set?.[updatefield]?.fields !== undefined) { + diff.diff.$set[updatefield]!.fields = [...listItems, ...newListItems]; // , ...newListItems.filter((newItem: any) => newItem === null || !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))]; + const sendBack = diff.diff.length !== diff.diff.$set[updatefield]!.fields?.length; + delete diff.diff.length; + Database.Instance.update( + diff.id, + diff.diff, + () => { + if (sendBack) { + console.log('Warning: list modified during update. Composite list is being returned.'); + const { id } = socket; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (socket as any).id = ''; // bcz: HACK to reference private variable. this allows the update message to go back to the client that made the change. + socket.broadcast.emit(MessageStore.UpdateField.Message, diff); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (socket as any).id = id; + } else { + socket.broadcast.emit(MessageStore.UpdateField.Message, diff); + } + dispatchNextOp(diff.id); + }, + false + ); + } } /** @@ -208,7 +182,7 @@ export namespace WebSocket { * the data * @returns the closest index with the same value or -1 if the element was not found. */ - function findClosestIndex(list: any, indexesToDelete: number[], value: any, hintIndex: number) { + function findClosestIndex(list: { fieldId: string; __type: string }[], indexesToDelete: number[], value: { fieldId: string; __type: string }, hintIndex: number) { let closestIndex = -1; for (let i = 0; i < list.length; i++) { if (list[i] === value && !indexesToDelete.includes(i)) { @@ -232,63 +206,63 @@ export namespace WebSocket { * items to delete) * @param curListItems the server's current copy of the data */ - function remFromListField(socket: Socket, diffIn: Diff, curListItems?: Transferable): void { + function remFromListField(socket: Socket, diffIn: Diff, curListItems?: serializedDoctype): void { const diff = diffIn; - diff.diff.$set = diff.diff.$remFromSet; + diff.diff.$set = diff.diff.$remFromSet as serializedFieldsType; + const hint = diff.diff.$remFromSet?.hint; delete diff.diff.$remFromSet; - const updatefield = Array.from(Object.keys(diff.diff.$set))[0]; - const remListItems = diff.diff.$set[updatefield].fields; - const curList = (curListItems as any)?.fields?.[updatefield.replace('fields.', '')]?.fields.filter((f: any) => f !== null) || []; - const { hint } = diff.diff.$set; - - if (hint) { - // indexesToRemove stores the indexes that we mark for deletion, which is later used to filter the list (delete the elements) - const indexesToRemove: number[] = []; - for (let i = 0; i < hint.deleteCount; i++) { - if (curList.length > i + hint.start && _.isEqual(curList[i + hint.start], remListItems[i])) { - indexesToRemove.push(i + hint.start); - } else { - const closestIndex = findClosestIndex(curList, indexesToRemove, remListItems[i], i + hint.start); - if (closestIndex !== -1) { - indexesToRemove.push(closestIndex); + const updatefield = Array.from(Object.keys(diff.diff.$set ?? {}))[0]; + const remListItems = diff.diff.$set[updatefield]?.fields; + if (diff.diff.$set[updatefield] !== undefined && remListItems) { + const curList = curListItems?.fields?.[updatefield.replace('fields.', '')]?.fields.filter(f => f !== null) || []; + + if (hint) { + // indexesToRemove stores the indexes that we mark for deletion, which is later used to filter the list (delete the elements) + const indexesToRemove: number[] = []; + for (let i = 0; i < hint.deleteCount; i++) { + if (curList.length > i + hint.start && _.isEqual(curList[i + hint.start], remListItems[i])) { + indexesToRemove.push(i + hint.start); } else { - console.log('Item to delete was not found - index = -1'); + const closestIndex = findClosestIndex(curList, indexesToRemove, remListItems[i], i + hint.start); + if (closestIndex !== -1) { + indexesToRemove.push(closestIndex); + } else { + console.log('Item to delete was not found - index = -1'); + } } } + diff.diff.$set[updatefield]!.fields = curList.filter((curItem, index) => !indexesToRemove.includes(index)); + } else { + // go back to the original way to delete if we didn't receive + // a hint from the client + diff.diff.$set[updatefield]!.fields = curList?.filter(curItem => !remListItems.some(remItem => (remItem.fieldId ? remItem.fieldId === curItem.fieldId : remItem.heading ? remItem.heading === curItem.heading : remItem === curItem))); } - - diff.diff.$set[updatefield].fields = curList?.filter((curItem: any, index: number) => !indexesToRemove.includes(index)); - } else { - // go back to the original way to delete if we didn't receive - // a hint from the client - diff.diff.$set[updatefield].fields = curList?.filter( - (curItem: any) => !remListItems.some((remItem: any) => (remItem.fieldId ? remItem.fieldId === curItem.fieldId : remItem.heading ? remItem.heading === curItem.heading : remItem === curItem)) + // if the client and server have different versions of the data after + // deletion, they will have different lengths and the server will + // send its version of the data to the client + const sendBack = diff.diff.length !== remListItems.length; + delete diff.diff.length; + Database.Instance.update( + diff.id, + diff.diff, + () => { + if (sendBack) { + // the two copies are different, so the server sends its copy. + console.log('SEND BACK'); + const { id } = socket; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (socket as any).id = ''; // bcz: HACK to access private variable this allows the update message to go back to the client that made the change. + socket.broadcast.emit(MessageStore.UpdateField.Message, diff); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (socket as any).id = id; + } else { + socket.broadcast.emit(MessageStore.UpdateField.Message, diff); + } + dispatchNextOp(diff.id); + }, + false ); } - - // if the client and server have different versions of the data after - // deletion, they will have different lengths and the server will - // send its version of the data to the client - const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length; - delete diff.diff.length; - Database.Instance.update( - diff.id, - diff.diff, - () => { - if (sendBack) { - // the two copies are different, so the server sends its copy. - console.log('SEND BACK'); - const { id } = socket; - (socket as any).id = ''; // bcz: HACK. this prevents the update message from going back to the client that made the change. - socket.broadcast.emit(MessageStore.UpdateField.Message, diff); - (socket as any).id = id; - } else { - socket.broadcast.emit(MessageStore.UpdateField.Message, diff); - } - dispatchNextOp(diff.id); - }, - false - ); } function UpdateField(socket: Socket, diff: Diff) { @@ -307,43 +281,16 @@ export namespace WebSocket { } pendingOps.set(diff.id, [{ diff, socket }]); if (diff.diff.$addToSet) { - return GetRefFieldLocal([diff.id, (result?: Transferable) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own + return GetRefFieldLocal([diff.id, (result?: serializedDoctype) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own } if (diff.diff.$remFromSet) { - return GetRefFieldLocal([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own + return GetRefFieldLocal([diff.id, (result?: serializedDoctype) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own } // eslint-disable-next-line no-use-before-define return SetField(socket, diff); } function SetField(socket: Socket, diff: Diff /* , curListItems?: Transferable */) { Database.Instance.update(diff.id, diff.diff, () => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false); - const docfield = diff.diff.$set || diff.diff.$unset; - if (docfield) { - const update: any = { id: diff.id }; - let dynfield = false; - // eslint-disable-next-line no-restricted-syntax - for (let key in docfield) { - // eslint-disable-next-line no-continue - if (!key.startsWith('fields.')) continue; - dynfield = true; - const val = docfield[key]; - key = key.substring(7); - Object.values(suffixMap).forEach(suf => { - update[key + getSuffix(suf)] = { set: null }; - }); - const term = ToSearchTerm(val); - if (term !== undefined) { - const { suffix, value } = term; - update[key + suffix] = { set: value }; - if (key.endsWith('modificationDate')) { - update['modificationDate' + suffix] = value; - } - } - } - if (dynfield) { - Search.updateDocument(update); - } - } dispatchNextOp(diff.id); } @@ -351,21 +298,15 @@ export namespace WebSocket { Database.Instance.delete({ _id: id }).then(() => { socket.broadcast.emit(MessageStore.DeleteField.Message, id); }); - - Search.deleteDocuments([id]); } function DeleteFields(socket: Socket, ids: string[]) { Database.Instance.delete({ _id: { $in: ids } }).then(() => { socket.broadcast.emit(MessageStore.DeleteFields.Message, ids); }); - Search.deleteDocuments(ids); } - function CreateField(newValue: any) { - Database.Instance.insert(newValue); - } - export async function initialize(isRelease: boolean, credentials: any) { + export async function initialize(isRelease: boolean, credentials: SecureContextOptions) { let io: Server; if (isRelease) { const { socketPort } = process.env; @@ -422,21 +363,14 @@ export namespace WebSocket { ServerUtils.Emit(socket, MessageStore.Foo, 'handshooken'); ServerUtils.AddServerHandler(socket, MessageStore.Bar, guid => barReceived(socket, guid)); - ServerUtils.AddServerHandler(socket, MessageStore.SetField, args => setField(socket, args)); - ServerUtils.AddServerHandlerCallback(socket, MessageStore.GetField, getField); - ServerUtils.AddServerHandlerCallback(socket, MessageStore.GetFields, getFields); if (isRelease) { ServerUtils.AddServerHandler(socket, MessageStore.DeleteAll, () => doDelete(false)); } - ServerUtils.AddServerHandler(socket, MessageStore.CreateField, CreateField); ServerUtils.AddServerHandler(socket, MessageStore.UpdateField, diff => UpdateField(socket, diff)); ServerUtils.AddServerHandler(socket, MessageStore.DeleteField, id => DeleteField(socket, id)); ServerUtils.AddServerHandler(socket, MessageStore.DeleteFields, ids => DeleteFields(socket, ids)); ServerUtils.AddServerHandler(socket, MessageStore.GesturePoints, content => processGesturePoints(socket, content)); - ServerUtils.AddServerHandler(socket, MessageStore.MobileInkOverlayTrigger, content => processOverlayTrigger(socket, content)); - ServerUtils.AddServerHandler(socket, MessageStore.UpdateMobileInkOverlayPosition, content => processUpdateOverlayPosition(socket, content)); - ServerUtils.AddServerHandler(socket, MessageStore.MobileDocumentUpload, content => processMobileDocumentUpload(socket, content)); ServerUtils.AddServerHandlerCallback(socket, MessageStore.GetRefField, GetRefField); ServerUtils.AddServerHandlerCallback(socket, MessageStore.GetRefFields, GetRefFields); -- cgit v1.2.3-70-g09d2 From fe91a8cd62ee1793f4a1d38c3ed4a1b451f4e3a4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 13 Aug 2024 15:55:01 -0400 Subject: fix for linear views --- src/client/views/collections/collectionLinear/CollectionLinearView.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index 3af8464c2..ceae43c04 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -22,6 +22,7 @@ import { DocumentLinksButton } from '../../nodes/DocumentLinksButton'; import { DocumentView } from '../../nodes/DocumentView'; import { LinkDescriptionPopup } from '../../nodes/LinkDescriptionPopup'; import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; +import './CollectionLinearView.scss'; /** * CollectionLinearView is the class for rendering the horizontal collection -- cgit v1.2.3-70-g09d2 From 5960fa9635c28c2b609826005cb7595ec6b9fb75 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 13 Aug 2024 16:31:13 -0400 Subject: fixed bugs introduced cleaning up database list ops. --- src/client/DocServer.ts | 16 ++++++++-------- src/fields/Doc.ts | 2 +- src/server/Message.ts | 2 +- src/server/websocket.ts | 7 ++++++- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index 33fa928f2..c644308b7 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -34,7 +34,7 @@ export namespace DocServer { throw new Error("Can't use DocServer without calling init first"); } let _UpdateField: (id: string, diff: serverOpType) => void = errorFunc; - let _CreateField: (field: Doc) => void = errorFunc; + let _CreateDocField: (field: Doc) => void = errorFunc; export function AddServerHandler(socket: Socket, message: Message, handler: (args: T) => void) { socket.on(message.Message, Utils.loggingCallback('Incoming', handler, message.Name)); @@ -132,7 +132,7 @@ export namespace DocServer { export function makeReadOnly() { if (!_isReadOnly) { _isReadOnly = true; - _CreateField = field => { + _CreateDocField = field => { _cache[field[Id]] = field; }; _UpdateField = emptyFunction; @@ -357,20 +357,20 @@ export namespace DocServer { } /** - * A wrapper around the function local variable _createField. + * A wrapper around the function local variable _CreateDocField. * This allows us to swap in different executions while comfortably * calling the same function throughout the code base (such as in Util.makeReadonly()) * @param field the [RefField] to be serialized and sent to the server to be stored in the database */ - export function CreateField(field: Doc) { + export function CreateDocField(field: Doc) { _cacheNeedsUpdate = true; - _CreateField(field); + _CreateDocField(field); } - function _CreateFieldImpl(field: Doc) { + function _CreateDocFieldImpl(field: Doc) { _cache[field[Id]] = field; const initialState = SerializationHelper.Serialize(field); - ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.CreateField, initialState); + ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.CreateDocField, initialState); } // NOTIFY THE SERVER OF AN UPDATE TO A DOC'S STATE @@ -462,7 +462,7 @@ export namespace DocServer { _GetCachedRefField = _GetCachedRefFieldImpl; SetObjGetRefField((_GetRefField = _GetRefFieldImpl)); SetObjGetRefFields((_GetRefFields = _GetRefFieldsImpl)); - _CreateField = _CreateFieldImpl; + _CreateDocField = _CreateDocFieldImpl; _UpdateField = _UpdateFieldImpl; /** diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index ad7609895..2ae9dbf02 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -329,7 +329,7 @@ export class Doc extends RefField { }); this[SelfProxy] = docProxy; if (!id || forceSave) { - DocServer.CreateField(docProxy); + DocServer.CreateDocField(docProxy); } // eslint-disable-next-line no-constructor-return return docProxy; // need to return the proxy from the constructor so that all our added fields will get called diff --git a/src/server/Message.ts b/src/server/Message.ts index 4599708c9..b904a5ba3 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -56,7 +56,7 @@ export namespace MessageStore { export const GetRefField = new Message('Get Ref Field'); export const GetRefFields = new Message('Get Ref Fields'); export const UpdateField = new Message('Update Ref Field'); - export const CreateField = new Message('Create Ref Field'); + export const CreateDocField = new Message('Create Ref Field'); export const DeleteField = new Message('Delete field'); export const DeleteFields = new Message('Delete fields'); diff --git a/src/server/websocket.ts b/src/server/websocket.ts index f10455680..f588151a5 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -240,7 +240,7 @@ export namespace WebSocket { // if the client and server have different versions of the data after // deletion, they will have different lengths and the server will // send its version of the data to the client - const sendBack = diff.diff.length !== remListItems.length; + const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length; delete diff.diff.length; Database.Instance.update( diff.id, @@ -306,6 +306,10 @@ export namespace WebSocket { }); } + function CreateDocField(newValue: serializedDoctype) { + Database.Instance.insert(newValue); + } + export async function initialize(isRelease: boolean, credentials: SecureContextOptions) { let io: Server; if (isRelease) { @@ -367,6 +371,7 @@ export namespace WebSocket { ServerUtils.AddServerHandler(socket, MessageStore.DeleteAll, () => doDelete(false)); } + ServerUtils.AddServerHandler(socket, MessageStore.CreateDocField, CreateDocField); ServerUtils.AddServerHandler(socket, MessageStore.UpdateField, diff => UpdateField(socket, diff)); ServerUtils.AddServerHandler(socket, MessageStore.DeleteField, id => DeleteField(socket, id)); ServerUtils.AddServerHandler(socket, MessageStore.DeleteFields, ids => DeleteFields(socket, ids)); -- cgit v1.2.3-70-g09d2 From 25ea424ab2e6c32272e828b98822eb32f1fe2cab Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 15 Aug 2024 11:14:04 -0400 Subject: cleaned up server list add/rem. --- src/ServerUtils.ts | 10 +- src/Utils.ts | 16 +- src/client/views/DocComponent.tsx | 4 +- src/client/views/StyleProvider.tsx | 3 +- src/client/views/collections/TabDocView.tsx | 10 +- src/client/views/collections/TreeView.tsx | 6 +- src/client/views/nodes/DocumentContentsView.tsx | 3 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 38 ++-- src/client/views/nodes/trails/PresBox.tsx | 98 ++++---- src/client/views/nodes/trails/SlideEffect.tsx | 2 +- src/fields/ObjectField.ts | 5 +- src/fields/RichTextUtils.ts | 56 +++-- src/fields/util.ts | 4 +- src/server/database.ts | 2 +- src/server/websocket.ts | 248 +++++++-------------- 15 files changed, 201 insertions(+), 304 deletions(-) diff --git a/src/ServerUtils.ts b/src/ServerUtils.ts index 7e821cda2..904541fc7 100644 --- a/src/ServerUtils.ts +++ b/src/ServerUtils.ts @@ -9,20 +9,20 @@ export namespace ServerUtils { socket.emit(message.Message, args); } - export function AddServerHandler(socket: Socket, message: Message, handler: (args: T) => any) { + export function AddServerHandler(socket: Socket, message: Message, handler: (args: T) => void) { socket.on(message.Message, Utils.loggingCallback('Incoming', handler, message.Name)); } - export function AddServerHandlerCallback(socket: Socket, message: Message, handler: (args: [T, (res: any) => any]) => any) { - socket.on(message.Message, (arg: T, fn: (res: any) => any) => { + export function AddServerHandlerCallback(socket: Socket, message: Message, handler: (args: [T, (res: unknown) => void]) => void) { + socket.on(message.Message, (arg: T, fn: (res: unknown) => void) => { Utils.log('S receiving', message.Name, arg, true); handler([arg, Utils.loggingCallback('S sending', fn, message.Name)]); }); } - export type RoomHandler = (socket: Socket, room: string) => any; + export type RoomHandler = (socket: Socket, room: string) => void; export type UsedSockets = Socket; export type RoomMessage = 'create or join' | 'created' | 'joined'; export function AddRoomHandler(socket: Socket, message: RoomMessage, handler: RoomHandler) { - socket.on(message, (room: any) => handler(socket, room)); + socket.on(message, room => handler(socket, room)); } } diff --git a/src/Utils.ts b/src/Utils.ts index 23ae38bdb..0590c6930 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-namespace */ import * as uuid from 'uuid'; export function clamp(n: number, lower: number, upper: number) { @@ -23,6 +24,7 @@ export namespace Utils { export const loggingEnabled = false; export const logFilter: number | undefined = undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any export function log(prefixIn: string, messageName: string, messageIn: any, receiving: boolean) { let prefix = prefixIn; let message = messageIn; @@ -38,8 +40,9 @@ export namespace Utils { console.log(`${prefix}: ${idString}, ${receiving ? 'receiving' : 'sending'} ${messageName} with data ${JSON.stringify(message)} `); } - export function loggingCallback(prefix: string, func: (args: any) => any, messageName: string) { - return (args: any) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + export function loggingCallback(prefix: string, func: (args: any) => void, messageName: string) { + return (args: unknown) => { log(prefix, messageName, args, true); func(args); }; @@ -47,7 +50,9 @@ export namespace Utils { export function TraceConsoleLog() { ['log', 'warn'].forEach(method => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const old = (console as any)[method]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any (console as any)[method] = function (...args: any[]) { let stack = new Error('').stack?.split(/\n/); // Chrome includes a single "Error" line, FF doesn't. @@ -158,7 +163,7 @@ export function timenow() { const now = new Date(); let ampm = 'am'; let h = now.getHours(); - let m: any = now.getMinutes(); + let m: string | number = now.getMinutes(); if (h >= 12) { if (h > 12) h -= 12; ampm = 'pm'; @@ -201,7 +206,7 @@ export function intersectRect(r1: { left: number; top: number; width: number; he export function stringHash(s?: string) { // eslint-disable-next-line no-bitwise - return !s ? undefined : Math.abs(s.split('').reduce((a: any, b: any) => (n => n & n)((a << 5) - a + b.charCodeAt(0)), 0)); + return !s ? undefined : Math.abs(s.split('').reduce((a, b) => (n => n & n)((a << 5) - a + b.charCodeAt(0)), 0)); } export function percent2frac(percent: string) { @@ -224,8 +229,6 @@ export function emptyFunction() { return undefined; } -export const emptyPath: any[] = []; - export function unimplementedFunction() { throw new Error('This function is not implemented, but should be.'); } @@ -246,6 +249,7 @@ export function DeepCopy(source: Map, predicate?: Predicate) { export namespace JSONUtils { export function tryParse(source: string) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any let results: any; try { results = JSON.parse(source); diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index e5752dcd2..e351e2dec 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -93,7 +93,7 @@ export function ViewBoxBaseComponent

() { * This is the unique data repository for a dcoument that stores the intrinsic document data */ @computed get dataDoc() { - return this.Document.isTemplateForField || this.Document.isTemplateDoc ? this._props.TemplateDataDocument ?? this.Document[DocData] : this.Document[DocData]; + return this.Document.isTemplateForField || this.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this.Document[DocData]) : this.Document[DocData]; } /** @@ -151,7 +151,7 @@ export function ViewBoxAnnotatableComponent

() { * This is the unique data repository for a dcoument that stores the intrinsic document data */ @computed get dataDoc() { - return this.Document.isTemplateForField || this.Document.isTemplateDoc ? this._props.TemplateDataDocument ?? this.Document[DocData] : this.Document[DocData]; + return this.Document.isTemplateForField || this.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this.Document[DocData]) : this.Document[DocData]; } /** diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 2792955a0..374f8ca3a 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -13,7 +13,6 @@ import { Id } from '../../fields/FieldSymbols'; import { ScriptField } from '../../fields/ScriptField'; import { BoolCast, Cast, DocCast, ImageCast, NumCast, ScriptCast, StrCast } from '../../fields/Types'; import { AudioAnnoState } from '../../server/SharedMediaTypes'; -import { emptyPath } from '../../Utils'; import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; import { IsFollowLinkScript } from '../documents/DocUtils'; import { SnappingManager } from '../util/SnappingManager'; @@ -406,5 +405,5 @@ export function DashboardStyleProvider(doc: Opt, props: Opt } export function returnEmptyDocViewList() { - return emptyPath; + return [] as DocumentView[]; } diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index f168db81b..31b6be927 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -7,7 +7,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; import ResizeObserver from 'resize-observer-polyfill'; -import { ClientUtils, DashColor, lightOrDark, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils'; +import { ClientUtils, DashColor, lightOrDark, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; import { Doc, Opt, returnEmptyDoclist } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; @@ -157,8 +157,8 @@ export class TabMinimapView extends ObservableReactComponent { PanelWidth={this.PanelWidth} PanelHeight={this.PanelHeight} styleProvider={DefaultStyleProvider} - childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDocViewList} - childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDocViewList} + childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyFilter} + childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyFilter} searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist} addDocument={undefined} removeDocument={this.remDocTab} diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index c0fe7a894..b10a521ca 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { ClientUtils, lightOrDark, return18, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; -import { Doc, DocListCast, Field, FieldResult, FieldType, Opt, StrListCast, returnEmptyDoclist } from '../../../fields/Doc'; +import { Doc, DocListCast, Field, FieldType, Opt, StrListCast, returnEmptyDoclist } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; @@ -249,7 +249,7 @@ export class TreeView extends ObservableReactComponent { return []; } - const runningChildren: FieldResult[] = []; + const runningChildren: Doc[] = []; childList.forEach(child => { if (child.runProcess && TreeView.GetRunningChildren.get(child)) { if (child.runProcess) { @@ -261,7 +261,7 @@ export class TreeView extends ObservableReactComponent { return runningChildren; }; - static GetRunningChildren = new Map FieldResult[]>(); + static GetRunningChildren = new Map Doc[]>(); static ToggleChildrenRun = new Map void>(); constructor(props: TreeViewProps) { super(props); diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index b178d6554..15baebae1 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -192,6 +192,7 @@ export class DocumentContentsView extends ObservableReactComponent 12 || !layoutFrame || !this.layoutDoc || GetEffectiveAcl(this.layoutDoc) === AclPrivate ? null : ( new FormattedTextBoxComment() }), + ], + }; + } private static nodeViews: (self: FormattedTextBox) => { [key: string]: NodeViewConstructor }; /** * Initialize the class with all the plugin node view components @@ -108,7 +123,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent; - private _keymap: KeyMap | undefined = undefined; private _rules: RichTextRules | undefined; private _forceUncollapse = true; // if the cursor doesn't move between clicks, then the selection will disappear for some reason. This flags the 2nd click as happening on a selection which allows bullet points to toggle private _break = true; @@ -128,20 +142,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent new FormattedTextBoxComment() }), - ], - }; + return FormattedTextBox.MakeConfig(this._rules, this._props); } public get EditorView() { @@ -1380,11 +1382,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - this._props.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView); - return new RichTextMenuPlugin({ editorProps: this._props }); + props?.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView); + return new RichTextMenuPlugin({ editorProps: props }); }), }); } diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 0c73400a9..c403f9415 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import Slider from '@mui/material/Slider'; @@ -32,7 +30,7 @@ import { dropActionType } from '../../../util/DropActionTypes'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { SerializationHelper } from '../../../util/SerializationHelper'; import { SnappingManager } from '../../../util/SnappingManager'; -import { undoBatch, UndoManager } from '../../../util/UndoManager'; +import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager'; import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; import { CollectionFreeFormPannableContents } from '../../collections/collectionFreeForm/CollectionFreeFormPannableContents'; import { CollectionView } from '../../collections/CollectionView'; @@ -191,7 +189,7 @@ export class PresBox extends ViewBoxBaseComponent() { @computed get isTreeOrStack() { - return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._type_collection) as any); + return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._type_collection) as CollectionViewType); } @computed get isTree() { return this.layoutDoc._type_collection === CollectionViewType.Tree; @@ -304,7 +302,7 @@ export class PresBox extends ViewBoxBaseComponent() { // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played startTempMedia = (targetDoc: Doc, activeItem: Doc) => { const duration: number = NumCast(activeItem.config_clipEnd) - NumCast(activeItem.config_clipStart); - if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as any)) { + if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as DocumentType)) { const targMedia = DocumentView.getDocumentView(targetDoc); targMedia?.ComponentView?.playFrom?.(NumCast(activeItem.config_clipStart), NumCast(activeItem.config_clipStart) + duration); } @@ -312,7 +310,7 @@ export class PresBox extends ViewBoxBaseComponent() { stopTempMedia = (targetDocField: FieldResult) => { const targetDoc = DocCast(DocCast(targetDocField).annotationOn) ?? DocCast(targetDocField); - if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as any)) { + if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as DocumentType)) { const targMedia = DocumentView.getDocumentView(targetDoc); targMedia?.ComponentView?.Pause?.(); } @@ -364,7 +362,7 @@ export class PresBox extends ViewBoxBaseComponent() { this.setIsRecording(false); this.setIsLoading(true); - const currSlideProperties: { [key: string]: any } = {}; + const currSlideProperties: { [key: string]: FieldResult } = {}; gptSlideProperties.forEach(key => { if (this.activeItem[key]) { currSlideProperties[key] = this.activeItem[key]; @@ -554,7 +552,7 @@ export class PresBox extends ViewBoxBaseComponent() { } }); static pinDataTypes(target?: Doc): dataTypes { - const targetType = target?.type as any; + const targetType = target?.type as DocumentType; const inkable = [DocumentType.INK].includes(targetType); const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetType) || target?._type_collection === CollectionViewType.Stacking; const pannable = [DocumentType.IMG, DocumentType.PDF].includes(targetType) || (targetType === DocumentType.COL && target?._type_collection === CollectionViewType.Freeform); @@ -759,8 +757,8 @@ export class PresBox extends ViewBoxBaseComponent() { const doc = DocCast(DocServer.GetCachedRefField(data.id)); if (doc) { transitioned.add(doc); - const field = !data.data ? undefined : await SerializationHelper.Deserialize(data.data); - const tfield = !data.text ? undefined : await SerializationHelper.Deserialize(data.text); + const field = !data.data ? undefined : ((await SerializationHelper.Deserialize(data.data)) as FieldType); + const tfield = !data.text ? undefined : ((await SerializationHelper.Deserialize(data.text)) as FieldType); doc._dataTransition = `all ${transTime}ms`; doc.x = data.x; doc.y = data.y; @@ -858,7 +856,7 @@ export class PresBox extends ViewBoxBaseComponent() { effect: activeItem, noSelect: true, openLocation: targetDoc.type === DocumentType.PRES ? ((OpenWhere.replace + ':' + PresBox.PanelName) as OpenWhere) : OpenWhere.addLeft, - easeFunc: StrCast(activeItem.presentation_easeFunc, 'ease') as any, + easeFunc: StrCast(activeItem.presentation_easeFunc, 'ease') as 'linear' | 'ease', zoomTextSelections: BoolCast(activeItem.presentation_zoomText), playAudio: BoolCast(activeItem.presentation_playAudio), playMedia: activeItem.presentation_mediaStart === 'auto', @@ -1101,7 +1099,7 @@ export class PresBox extends ViewBoxBaseComponent() { */ @undoBatch viewChanged = action((e: React.ChangeEvent) => { - const typeCollection = (e.target as any).selectedOptions[0].value as CollectionViewType; + const typeCollection = (e.target as HTMLSelectElement).selectedOptions[0].value as CollectionViewType; this.layoutDoc.presFieldKey = this.fieldKey + (typeCollection === CollectionViewType.Tree ? '-linearized' : ''); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here [CollectionViewType.Tree || CollectionViewType.Stacking].includes(typeCollection) && (this.Document._pivotField = undefined); @@ -1111,30 +1109,8 @@ export class PresBox extends ViewBoxBaseComponent() { } }); - /** - * Called when the user changes the view type - * Either 'List' (stacking) or 'Slides' (carousel) - */ - // @undoBatch - mediaStopChanged = action((e: React.ChangeEvent) => { - const { activeItem } = this; - const stopDoc = (e.target as any).selectedOptions[0].value as string; - const stopDocIndex = Number(stopDoc[0]); - activeItem.mediaStopDoc = stopDocIndex; - if (this.childDocs[stopDocIndex - 1].mediaStopTriggerList) { - const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList); - list.push(activeItem); - // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;\ - } else { - this.childDocs[stopDocIndex - 1].mediaStopTriggerList = new List(); - const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList); - list.push(activeItem); - // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list; - } - }); - movementName = action((activeItem: Doc) => { - if (![PresMovement.Zoom, PresMovement.Pan, PresMovement.Center, PresMovement.Jump, PresMovement.None].includes(StrCast(activeItem.presentation_movement) as any)) { + if (![PresMovement.Zoom, PresMovement.Pan, PresMovement.Center, PresMovement.Jump, PresMovement.None].includes(StrCast(activeItem.presentation_movement) as PresMovement)) { return PresMovement.Zoom; } return StrCast(activeItem.presentation_movement); @@ -1185,7 +1161,7 @@ export class PresBox extends ViewBoxBaseComponent() { * Method to get the list of selected items in the order in which they have been selected */ @computed get listOfSelected() { - return Array.from(this.selectedArray).map((doc: Doc, index: any) => { + return Array.from(this.selectedArray).map((doc, index) => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentation_targetDoc, Doc, null); if (curDoc && curDoc === this.activeItem) @@ -1193,7 +1169,7 @@ export class PresBox extends ViewBoxBaseComponent() { // eslint-disable-next-line react/no-array-index-key

- {index + 1}. {curDoc.title} + {index + 1}. {StrCast(curDoc.title)})
); @@ -1201,14 +1177,14 @@ export class PresBox extends ViewBoxBaseComponent() { return ( // eslint-disable-next-line react/no-array-index-key
- {index + 1}. {curDoc.title} + {index + 1}. {StrCast(curDoc.title)}
); if (curDoc) return ( // eslint-disable-next-line react/no-array-index-key
- {index + 1}. {curDoc.title} + {index + 1}. {StrCast(curDoc.title)}
); return null; @@ -1301,13 +1277,14 @@ export class PresBox extends ViewBoxBaseComponent() { switch (e.key) { case 'Backspace': if (this.layoutDoc.presentation_status === 'edit') { - undoBatch( + undoable( action(() => { Array.from(this.selectedArray).forEach(doc => this.removeDocument(doc)); this.clearSelectedArray(); this._eleArray.length = 0; this._dragArray.length = 0; - }) + }), + 'delete slides' )(); handled = true; } @@ -1488,7 +1465,7 @@ export class PresBox extends ViewBoxBaseComponent() { ); }; // Converts seconds to ms and updates presentation_transition - public static SetTransitionTime = (number: String, setter: (timeInMS: number) => void, change?: number) => { + public static SetTransitionTime = (number: string, setter: (timeInMS: number) => void, change?: number) => { let timeInMS = Number(number) * 1000; if (change) timeInMS += change; if (timeInMS < 100) timeInMS = 100; @@ -1497,7 +1474,7 @@ export class PresBox extends ViewBoxBaseComponent() { }; @undoBatch - updateTransitionTime = (number: String, change?: number) => { + updateTransitionTime = (number: string, change?: number) => { PresBox.SetTransitionTime( number, (timeInMS: number) => @@ -1510,7 +1487,7 @@ export class PresBox extends ViewBoxBaseComponent() { // Converts seconds to ms and updates presentation_transition @undoBatch - updateZoom = (number: String, change?: number) => { + updateZoom = (number: string, change?: number) => { let scale = Number(number) / 100; if (change) scale += change; if (scale < 0.01) scale = 0.01; @@ -1524,7 +1501,7 @@ export class PresBox extends ViewBoxBaseComponent() { * Converts seconds to ms and updates presentation_duration */ @undoBatch - updateDurationTime = (number: String, change?: number) => { + updateDurationTime = (number: string, change?: number) => { let timeInMS = Number(number) * 1000; if (change) timeInMS += change; if (timeInMS < 100) timeInMS = 100; @@ -1608,9 +1585,9 @@ export class PresBox extends ViewBoxBaseComponent() { }); }; - static _sliderBatch: any; + static _sliderBatch: UndoManager.Batch | undefined; static endBatch = () => { - PresBox._sliderBatch.end(); + PresBox._sliderBatch?.end(); document.removeEventListener('pointerup', PresBox.endBatch, true); }; public static inputter = (min: string, step: string, max: string, value: number, active: boolean, change: (val: string) => void, hmargin?: number) => ( @@ -1704,7 +1681,7 @@ export class PresBox extends ViewBoxBaseComponent() {
- {[DocumentType.AUDIO, DocumentType.VID].includes(targetType as any as DocumentType) ? null : ( + {[DocumentType.AUDIO, DocumentType.VID].includes(targetType as DocumentType) ? null : ( <>
Slide Duration
@@ -1847,7 +1824,7 @@ export class PresBox extends ViewBoxBaseComponent() { if (activeItem && this.targetDoc) { const transitionSpeed = activeItem.presentation_transition ? NumCast(activeItem.presentation_transition) / 1000 : 0.5; const zoom = NumCast(activeItem.config_zoom, 1) * 100; - const effect = StrCast(activeItem.presentation_effect) ? (StrCast(activeItem.presentation_effect) as any as PresEffect) : PresEffect.None; + const effect = StrCast(activeItem.presentation_effect) ? (StrCast(activeItem.presentation_effect) as PresEffect) : PresEffect.None; const direction = StrCast(activeItem.presentation_effectDirection) as PresEffectDirection; return ( @@ -2660,24 +2637,26 @@ export class PresBox extends ViewBoxBaseComponent() {
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
{ this.enterMinimize(); this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); - }) + }), + 'minimze presentation' )}> Mini-player
{ this.layoutDoc.presentation_status = 'manual'; this.initializePresState(this.itemIndex); this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); - }) + }), + 'make presentation manual' )}> Sidebar player
@@ -2773,13 +2752,13 @@ export class PresBox extends ViewBoxBaseComponent() {
{ + onClick={undoable(() => { if (this.childDocs.length) { this.layoutDoc.presentation_status = 'manual'; this.initializePresState(this.itemIndex); this.gotoDocument(this.itemIndex, this.activeItem); } - })}> + }, 'start presentation')}>
200 ? 'inline-flex' : 'none' }}>  Present
@@ -2911,11 +2890,12 @@ export class PresBox extends ViewBoxBaseComponent() { {this._props.PanelWidth() > 250 ? (
{ this.layoutDoc.presentation_status = PresStatus.Edit; clearTimeout(this._presTimer); - }) + }), + 'edit presetnation' )}> EXIT
@@ -2988,7 +2968,7 @@ export class PresBox extends ViewBoxBaseComponent() { }; sort = (treeViewMap: Map) => [...treeViewMap.entries()].sort((a: [Doc, number], b: [Doc, number]) => (a[1] > b[1] ? 1 : a[1] < b[1] ? -1 : 0)).map(kv => kv[0]); - + emptyHierarchy = []; render() { // needed to ensure that the childDocs are loaded for looking up fields this.childDocs.slice(); @@ -3086,7 +3066,7 @@ export class PresBox extends ViewBoxBaseComponent() { ScreenToLocalTransform={this.getTransform} AddToMap={this.AddToMap} RemFromMap={this.RemFromMap} - hierarchyIndex={emptyPath} + hierarchyIndex={this.emptyHierarchy} /> ) : null}
diff --git a/src/client/views/nodes/trails/SlideEffect.tsx b/src/client/views/nodes/trails/SlideEffect.tsx index 00039e3cb..a114c231f 100644 --- a/src/client/views/nodes/trails/SlideEffect.tsx +++ b/src/client/views/nodes/trails/SlideEffect.tsx @@ -103,7 +103,7 @@ export default function SpringAnimation({ doc, dir, springSettings, presEffect, api.start({ loop: infinite, delay: infinite ? 500 : 0 }); } }, [inView]); - const animatedDiv = (style: any) => ( + const animatedDiv = (style: object) => ( `${val}`) }}> {children} diff --git a/src/fields/ObjectField.ts b/src/fields/ObjectField.ts index 5f31208eb..c533cb596 100644 --- a/src/fields/ObjectField.ts +++ b/src/fields/ObjectField.ts @@ -12,9 +12,8 @@ export interface serializedDoctype { export type serverOpType = { $set?: serializedFieldsType; // $unset?: { [key: string]: unknown }; - $remFromSet?: { [key: string]: { fields: serializedFieldType[] } | { deleteCount: number; start: number } | undefined; hint?: { deleteCount: number; start: number } }; - $addToSet?: serializedFieldsType; - length?: number; + $remFromSet?: { [key: string]: { fields: serializedFieldType[] } | { deleteCount: number; start: number } | number | undefined; length: number; hint: { deleteCount: number; start: number } | undefined }; + $addToSet?: { [key: string]: { fields: serializedFieldType[] } | number | undefined; length: number }; }; export abstract class ObjectField { // prettier-ignore diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts index 3763dcd2c..d1316d256 100644 --- a/src/fields/RichTextUtils.ts +++ b/src/fields/RichTextUtils.ts @@ -1,9 +1,10 @@ +/* eslint-disable @typescript-eslint/no-namespace */ /* eslint-disable no-await-in-loop */ /* eslint-disable no-use-before-define */ import { AssertionError } from 'assert'; import * as Color from 'color'; import { docs_v1 as docsV1 } from 'googleapis'; -import { Fragment, Mark, Node } from 'prosemirror-model'; +import { Fragment, Mark, Node, Schema } from 'prosemirror-model'; import { sinkListItem } from 'prosemirror-schema-list'; import { EditorState, TextSelection, Transaction } from 'prosemirror-state'; import { ClientUtils, DashColor } from '../ClientUtils'; @@ -26,7 +27,7 @@ export namespace RichTextUtils { const joiner = ''; export const Initialize = (initial?: string) => { - const content: any[] = []; + const content: object[] = []; const state = { doc: { type: 'doc', @@ -80,8 +81,10 @@ export namespace RichTextUtils { // Preserve the current state, but re-write the content to be the blocks const parsed = JSON.parse(oldState ? oldState.Data : Initialize()); parsed.doc.content = elements.map(text => { - const paragraph: any = { type: 'paragraph' }; - text.length && (paragraph.content = [{ type: 'text', marks: [], text }]); // An empty paragraph gets treated as a line break + const paragraph: object = { + type: 'paragraph', + content: text.length ? [{ type: 'text', marks: [], text }] : undefined, // An empty paragraph gets treated as a line break + }; return paragraph; }); @@ -164,7 +167,7 @@ export namespace RichTextUtils { const inlineObjectMap = await parseInlineObjects(document); const title = document.title!; const { text, paragraphs } = GoogleApiClientUtils.Docs.Utils.extractText(document); - let state = EditorState.create(new FormattedTextBox({} as any).config); + let state = EditorState.create(FormattedTextBox.MakeConfig()); const structured = parseLists(paragraphs); let position = 3; @@ -253,17 +256,20 @@ export namespace RichTextUtils { return groups; }; - const listItem = (lschema: any, runs: docsV1.Schema$TextRun[]): Node => lschema.node('list_item', null, paragraphNode(lschema, runs)); + const listItem = (lschema: Schema, runs: docsV1.Schema$TextRun[]): Node => lschema.node('list_item', null, paragraphNode(lschema, runs)); - const list = (lschema: any, items: Node[]): Node => lschema.node('ordered_list', { mapStyle: 'bullet' }, items); + const list = (lschema: Schema, items: Node[]): Node => lschema.node('ordered_list', { mapStyle: 'bullet' }, items); - const paragraphNode = (lschema: any, runs: docsV1.Schema$TextRun[]): Node => { - const children = runs.map(run => textNode(lschema, run)).filter(child => child !== undefined); + const paragraphNode = (lschema: Schema, runs: docsV1.Schema$TextRun[]): Node => { + const children = runs + .map(run => textNode(lschema, run)) + .filter(child => child !== undefined) + .map(child => child!); const fragment = children.length ? Fragment.from(children) : undefined; return lschema.node('paragraph', null, fragment); }; - const imageNode = (lschema: any, image: ImageTemplate, textNote: Doc) => { + const imageNode = (lschema: Schema, image: ImageTemplate, textNote: Doc) => { const { url: src, width, agnostic } = image; let docId: string; const guid = Utils.GenerateDeterministicGuid(agnostic); @@ -279,7 +285,7 @@ export namespace RichTextUtils { return lschema.node('image', { src, agnostic, width, docId, float: null }); }; - const textNode = (lschema: any, run: docsV1.Schema$TextRun) => { + const textNode = (lschema: Schema, run: docsV1.Schema$TextRun) => { const text = run.content!.removeTrailingNewlines(); return text.length ? lschema.text(text, styleToMarks(lschema, run.textStyle)) : undefined; }; @@ -291,29 +297,33 @@ export namespace RichTextUtils { ['fontSize', 'pFontSize'], ]); - const styleToMarks = (lschema: any, textStyle?: docsV1.Schema$TextStyle) => { + const styleToMarks = (lschema: Schema, textStyle?: docsV1.Schema$TextStyle) => { if (!textStyle) { return undefined; } const marks: Mark[] = []; Object.keys(textStyle).forEach(key => { const targeted = key as keyof docsV1.Schema$TextStyle; - const value = textStyle[targeted] as any; + const value = textStyle[targeted]; if (value) { - const attributes: any = {}; + const attributes: { [key: string]: number | string } = {}; let converted = StyleToMark.get(targeted) || targeted; - value.url && (attributes.href = value.url); - if (value.color) { - const object = value.color.rgbColor; - attributes.color = Color.rgb(['red', 'green', 'blue'].map(color => object[color] * 255 || 0)).hex(); + const urlValue = value as docsV1.Schema$Link; + urlValue.url && (attributes.href = urlValue.url); + const colValue = value as docsV1.Schema$OptionalColor; + const object = colValue.color?.rgbColor; + if (object) { + attributes.color = Color.rgb(['red', 'green', 'blue'].map(color => (object as { [key: string]: number })[color] * 255 || 0)).hex(); } - if (value.magnitude) { - attributes.fontSize = value.magnitude; + const magValue = value as docsV1.Schema$Dimension; + if (magValue.magnitude) { + attributes.fontSize = magValue.magnitude; } + const fontValue = value as docsV1.Schema$WeightedFontFamily; if (converted === 'weightedFontFamily') { - converted = ImportFontFamilyMapping.get(value.fontFamily) || 'timesNewRoman'; + converted = (fontValue.fontFamily && ImportFontFamilyMapping.get(fontValue.fontFamily)) || 'timesNewRoman'; } const mapped = lschema.marks[converted]; @@ -388,7 +398,7 @@ export namespace RichTextUtils { continue; } let converted = MarkToStyle.get(markName) || (markName as keyof docsV1.Schema$TextStyle); - let value: any = true; + let value: unknown = true; if (!converted) { // eslint-disable-next-line no-continue continue; @@ -436,7 +446,7 @@ export namespace RichTextUtils { converted = 'fontSize'; value = { magnitude: parseInt(matches[1].replace('px', '')), unit: 'PT' }; } - textStyle[converted] = value; + textStyle[converted] = value as undefined; } if (Object.keys(textStyle).length) { requests.push(EncodeStyleUpdate(information)); diff --git a/src/fields/util.ts b/src/fields/util.ts index a5c56607c..60eadcdfd 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -398,9 +398,9 @@ export function containedFieldChangedHandler(container: ListImpl | Do const serializeItems = () => ({ __type: 'list', fields: diff?.items?.map((item: FieldType) => SerializationHelper.Serialize(item) as serializedFieldType) ?? [] }); // prettier-ignore const serverOp: serverOpType = diff?.op === '$addToSet' - ? { $addToSet: { ['fields.' + prop]: serializeItems() }, length: diff.length } + ? { $addToSet: { ['fields.' + prop]: serializeItems(), length: diff.length ??0 }} : diff?.op === '$remFromSet' - ? { $remFromSet: { ['fields.' + prop]: serializeItems(), hint: diff.hint}, length: diff.length } + ? { $remFromSet: { ['fields.' + prop]: serializeItems(), hint: diff.hint, length: diff.length ?? 0 } } : { $set: { ['fields.' + prop]: SerializationHelper.Serialize(liveContainedField) as {fields: serializedFieldType[]}} }; if (!(container instanceof Doc) || !container[UpdatingFromServer]) { diff --git a/src/server/database.ts b/src/server/database.ts index a93117349..975b9eb80 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -32,7 +32,7 @@ export namespace Database { try { const { connection } = mongoose; disconnect = async () => - new Promise(resolve => { + new Promise(resolve => { connection.close().then(resolve); }); if (connection.readyState === ConnectionStates.disconnected) { diff --git a/src/server/websocket.ts b/src/server/websocket.ts index f588151a5..ccbcb1c5f 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -49,12 +49,12 @@ export namespace WebSocket { DashStats.logUserLogin(userEmail); } - function GetRefFieldLocal([id, callback]: [string, (result?: serializedDoctype) => void]) { + function GetRefFieldLocal(id: string, callback: (result?: serializedDoctype | undefined) => void) { return Database.Instance.getDocument(id, callback); } function GetRefField([id, callback]: [string, (result?: serializedDoctype) => void]) { process.stdout.write(`+`); - GetRefFieldLocal([id, callback]); + GetRefFieldLocal(id, callback); } function GetRefFields([ids, callback]: [string[], (result?: serializedDoctype[]) => void]) { @@ -62,112 +62,46 @@ export namespace WebSocket { Database.Instance.getDocuments(ids, callback); } - const suffixMap: { [type: string]: string | [string, string | ((json: any) => any)] } = { - number: '_n', - string: '_t', - boolean: '_b', - image: ['_t', 'url'], - video: ['_t', 'url'], - pdf: ['_t', 'url'], - audio: ['_t', 'url'], - web: ['_t', 'url'], - map: ['_t', 'url'], - script: ['_t', value => value.script.originalScript], - RichTextField: ['_t', value => value.Text], - date: ['_d', value => new Date(value.date).toISOString()], - proxy: ['_i', 'fieldId'], - list: [ - '_l', - list => { - const results: any[] = []; - // eslint-disable-next-line no-use-before-define - list.fields.forEach((value: any) => ToSearchTerm(value) && results.push(ToSearchTerm(value)!.value)); - return results.length ? results : null; - }, - ], - }; - - function ToSearchTerm(valIn: any): { suffix: string; value: any } | undefined { - let val = valIn; - if (val === null || val === undefined) { - return undefined; - } - const type = val.__type || typeof val; - - let suffix = suffixMap[type]; - if (!suffix) { - return undefined; - } - if (Array.isArray(suffix)) { - const accessor = suffix[1]; - if (typeof accessor === 'function') { - val = accessor(val); - } else { - val = val[accessor]; - } - [suffix] = suffix; - } - return { suffix, value: val }; - } - - function getSuffix(value: string | [string, any]): string { - return typeof value === 'string' ? value : value[0]; - } const pendingOps = new Map(); - function dispatchNextOp(id: string) { - const next = pendingOps.get(id)!.shift(); + function dispatchNextOp(id: string): unknown { + const next = pendingOps.get(id)?.shift(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const nextOp = (res: boolean) => dispatchNextOp(id); if (next) { const { diff, socket } = next; - if (diff.diff.$addToSet) { - // eslint-disable-next-line no-use-before-define - return GetRefFieldLocal([diff.id, (result?: serializedDoctype) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own + // ideally, we'd call the Database update method for all actions, but for now we handle list insertion/removal on our own + switch (diff.diff.$addToSet ? 'add' : diff.diff.$remFromSet ? 'rem' : 'set') { + case 'add': return GetRefFieldLocal(id, (result) => addToListField(socket, diff, result, nextOp)); // prettier-ignore + case 'rem': return GetRefFieldLocal(id, (result) => remFromListField(socket, diff, result, nextOp)); // prettier-ignore + default: return Database.Instance.update(id, diff.diff, + () => nextOp(socket.broadcast.emit(MessageStore.UpdateField.Message, diff)), + false + ); // prettier-ignore } - if (diff.diff.$remFromSet) { - // eslint-disable-next-line no-use-before-define - return GetRefFieldLocal([diff.id, (result?: serializedDoctype) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own - } - // eslint-disable-next-line no-use-before-define - return SetField(socket, diff); } - return !pendingOps.get(id)!.length && pendingOps.delete(id); + return !pendingOps.get(id)?.length && pendingOps.delete(id); } - function addToListField(socket: Socket, diffIn: Diff, listDoc?: serializedDoctype): void { - const diff = diffIn; - diff.diff.$set = diff.diff.$addToSet; - delete diff.diff.$addToSet; // convert add to set to a query of the current fields, and then a set of the composition of the new fields with the old ones - const updatefield = Array.from(Object.keys(diff.diff.$set ?? {}))[0]; - const newListItems = diff.diff.$set?.[updatefield]?.fields; - if (!newListItems) { - console.log('Error: addToListField - no new list items'); - return; - } - const listItems = listDoc?.fields?.[updatefield.replace('fields.', '')]?.fields.filter(item => item !== undefined) ?? []; - if (diff.diff.$set?.[updatefield]?.fields !== undefined) { + function addToListField(socket: Socket, diff: Diff, listDoc: serializedDoctype | undefined, cb: (res: boolean) => void): void { + const $addToSet = diff.diff.$addToSet as serializedFieldsType; + const updatefield = Array.from(Object.keys($addToSet ?? {}))[0]; + const newListItems = $addToSet?.[updatefield]?.fields; + + if (newListItems) { + const length = diff.diff.$addToSet?.length; + diff.diff.$set = $addToSet; // convert add to set to a query of the current fields, and then a set of the composition of the new fields with the old ones + delete diff.diff.$addToSet; // can't pass $set to Mongo, or it will do that insetead of $addToSet + const listItems = listDoc?.fields?.[updatefield.replace('fields.', '')]?.fields.filter(item => item) ?? []; diff.diff.$set[updatefield]!.fields = [...listItems, ...newListItems]; // , ...newListItems.filter((newItem: any) => newItem === null || !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))]; - const sendBack = diff.diff.length !== diff.diff.$set[updatefield]!.fields?.length; - delete diff.diff.length; - Database.Instance.update( - diff.id, - diff.diff, - () => { - if (sendBack) { - console.log('Warning: list modified during update. Composite list is being returned.'); - const { id } = socket; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (socket as any).id = ''; // bcz: HACK to reference private variable. this allows the update message to go back to the client that made the change. - socket.broadcast.emit(MessageStore.UpdateField.Message, diff); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (socket as any).id = id; - } else { - socket.broadcast.emit(MessageStore.UpdateField.Message, diff); - } - dispatchNextOp(diff.id); - }, - false - ); - } + + // if the client's list length is not the same as what we're writing to the server, + // then we need to send the server's version back to the client so that they are in synch. + // this could happen if another client made a change before the server receives the update from the first client + const target = length !== diff.diff.$set[updatefield].fields.length ? socket : socket.broadcast; + target === socket && console.log('Warning: SEND BACK: list modified during add update. Composite list is being returned.'); + Database.Instance.update(diff.id, diff.diff, () => cb(target.emit(MessageStore.UpdateField.Message, diff)), false); + } else cb(false); } /** @@ -206,15 +140,17 @@ export namespace WebSocket { * items to delete) * @param curListItems the server's current copy of the data */ - function remFromListField(socket: Socket, diffIn: Diff, curListItems?: serializedDoctype): void { - const diff = diffIn; - diff.diff.$set = diff.diff.$remFromSet as serializedFieldsType; - const hint = diff.diff.$remFromSet?.hint; - delete diff.diff.$remFromSet; - const updatefield = Array.from(Object.keys(diff.diff.$set ?? {}))[0]; - const remListItems = diff.diff.$set[updatefield]?.fields; - if (diff.diff.$set[updatefield] !== undefined && remListItems) { - const curList = curListItems?.fields?.[updatefield.replace('fields.', '')]?.fields.filter(f => f !== null) || []; + function remFromListField(socket: Socket, diff: Diff, curListItems: serializedDoctype | undefined, cb: (res: boolean) => void): void { + const $remFromSet = diff.diff.$remFromSet as serializedFieldsType; + const updatefield = Array.from(Object.keys($remFromSet ?? {}))[0]; + const remListItems = $remFromSet?.[updatefield]?.fields; + + if (remListItems) { + const hint = diff.diff.$remFromSet?.hint; + const length = diff.diff.$remFromSet?.length; + diff.diff.$set = $remFromSet; // convert rem from set to a query of the current fields, and then a set of the old fields minus the removed ones + delete diff.diff.$remFromSet; // can't pass $set to Mongo, or it will do that insetead of $remFromSet + const curList = curListItems?.fields?.[updatefield.replace('fields.', '')]?.fields.filter(f => f) ?? []; if (hint) { // indexesToRemove stores the indexes that we mark for deletion, which is later used to filter the list (delete the elements) @@ -227,83 +163,51 @@ export namespace WebSocket { if (closestIndex !== -1) { indexesToRemove.push(closestIndex); } else { - console.log('Item to delete was not found - index = -1'); + console.log('Item to delete was not found'); } } } diff.diff.$set[updatefield]!.fields = curList.filter((curItem, index) => !indexesToRemove.includes(index)); } else { - // go back to the original way to delete if we didn't receive - // a hint from the client + // if we didn't get a hint, remove all matching items from the list diff.diff.$set[updatefield]!.fields = curList?.filter(curItem => !remListItems.some(remItem => (remItem.fieldId ? remItem.fieldId === curItem.fieldId : remItem.heading ? remItem.heading === curItem.heading : remItem === curItem))); } - // if the client and server have different versions of the data after - // deletion, they will have different lengths and the server will - // send its version of the data to the client - const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length; - delete diff.diff.length; - Database.Instance.update( - diff.id, - diff.diff, - () => { - if (sendBack) { - // the two copies are different, so the server sends its copy. - console.log('SEND BACK'); - const { id } = socket; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (socket as any).id = ''; // bcz: HACK to access private variable this allows the update message to go back to the client that made the change. - socket.broadcast.emit(MessageStore.UpdateField.Message, diff); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (socket as any).id = id; - } else { - socket.broadcast.emit(MessageStore.UpdateField.Message, diff); - } - dispatchNextOp(diff.id); - }, - false - ); - } + + // if the client's list length is not the same as what we're writing to the server, + // then we need to send the server's version back to the client so that they are in synch. + // this could happen if another client made a change before the server receives the update from the first client + const target = length !== diff.diff.$set[updatefield].fields.length ? socket : socket.broadcast; + target === socket && console.log('Warning: SEND BACK: list modified during remove update. Composite list is being returned.'); + Database.Instance.update(diff.id, diff.diff, () => cb(target.emit(MessageStore.UpdateField.Message, diff)), false); + } else cb(false); } function UpdateField(socket: Socket, diff: Diff) { const curUser = socketMap.get(socket); - if (!curUser) return false; - const currentUsername = curUser.split(' ')[0]; - userOperations.set(currentUsername, userOperations.get(currentUsername) !== undefined ? userOperations.get(currentUsername)! + 1 : 0); + if (curUser) { + const currentUsername = curUser.split(' ')[0]; + userOperations.set(currentUsername, userOperations.get(currentUsername) !== undefined ? userOperations.get(currentUsername)! + 1 : 0); - if (CurUser !== socketMap.get(socket)) { - CurUser = socketMap.get(socket); - console.log('Switch User: ' + CurUser); - } - if (pendingOps.has(diff.id)) { - pendingOps.get(diff.id)!.push({ diff, socket }); - return true; - } - pendingOps.set(diff.id, [{ diff, socket }]); - if (diff.diff.$addToSet) { - return GetRefFieldLocal([diff.id, (result?: serializedDoctype) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own - } - if (diff.diff.$remFromSet) { - return GetRefFieldLocal([diff.id, (result?: serializedDoctype) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own + if (CurUser !== socketMap.get(socket)) { + CurUser = socketMap.get(socket); + console.log('Switch User: ' + CurUser); + } + if (pendingOps.has(diff.id)) { + pendingOps.get(diff.id)!.push({ diff, socket }); + return true; + } + pendingOps.set(diff.id, [{ diff, socket }]); + return dispatchNextOp(diff.id); } - // eslint-disable-next-line no-use-before-define - return SetField(socket, diff); - } - function SetField(socket: Socket, diff: Diff /* , curListItems?: Transferable */) { - Database.Instance.update(diff.id, diff.diff, () => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false); - dispatchNextOp(diff.id); + return false; } function DeleteField(socket: Socket, id: string) { - Database.Instance.delete({ _id: id }).then(() => { - socket.broadcast.emit(MessageStore.DeleteField.Message, id); - }); + Database.Instance.delete({ _id: id }).then(() => socket.broadcast.emit(MessageStore.DeleteField.Message, id)); } function DeleteFields(socket: Socket, ids: string[]) { - Database.Instance.delete({ _id: { $in: ids } }).then(() => { - socket.broadcast.emit(MessageStore.DeleteFields.Message, ids); - }); + Database.Instance.delete({ _id: { $in: ids } }).then(() => socket.broadcast.emit(MessageStore.DeleteFields.Message, ids)); } function CreateDocField(newValue: serializedDoctype) { @@ -343,21 +247,19 @@ export namespace WebSocket { socket.in(room).emit('message', message); }); - socket.on('ipaddr', () => { + socket.on('ipaddr', () => networkInterfaces().keys?.forEach(dev => { if (dev.family === 'IPv4' && dev.address !== '127.0.0.1') { socket.emit('ipaddr', dev.address); } - }); - }); + }) + ); - socket.on('bye', () => { - console.log('received bye'); - }); + socket.on('bye', () => console.log('received bye')); socket.on('disconnect', () => { const currentUser = socketMap.get(socket); - if (!(currentUser === undefined)) { + if (currentUser !== undefined) { const currentUsername = currentUser.split(' ')[0]; DashStats.logUserLogout(currentUsername); delete timeMap[currentUsername]; -- cgit v1.2.3-70-g09d2 From 0e975569e5686138e52bdc554b3f0391f42aeead Mon Sep 17 00:00:00 2001 From: IEatChili Date: Thu, 15 Aug 2024 14:13:02 -0400 Subject: feat: added face recogntion box --- src/client/apis/gpt/GPT.ts | 2 +- src/client/documents/DocumentTypes.ts | 1 + src/client/documents/Documents.ts | 4 + src/client/util/CurrentUserUtils.ts | 13 +- src/client/views/KeywordBox.tsx | 7 +- src/client/views/Main.tsx | 2 + .../collectionFreeForm/FaceCollectionBox.scss | 74 +++++++ .../collectionFreeForm/FaceCollectionBox.tsx | 217 +++++++++++++++++++++ .../collectionFreeForm/ImageLabelBox.tsx | 5 +- src/client/views/search/FaceRecognitionHandler.tsx | 74 +++++-- src/fields/Doc.ts | 1 + 11 files changed, 375 insertions(+), 25 deletions(-) create mode 100644 src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss create mode 100644 src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 05007960d..8dd3fd6e2 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -128,7 +128,7 @@ const gptImageLabel = async (src: string): Promise => { { role: 'user', content: [ - { type: 'text', text: 'Give three to five labels to describe this image.' }, + { type: 'text', text: 'Give three labels to describe this image.' }, { type: 'image_url', image_url: { diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index a9ea889b3..b66a29ac2 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -17,6 +17,7 @@ export enum DocumentType { FONTICON = 'fonticonbox', SEARCH = 'search', // search query IMAGEGROUPER = 'imagegrouper', + FACECOLLECTION = 'facecollection', LABEL = 'label', // simple text label BUTTON = 'button', // onClick button WEBCAM = 'webcam', // webcam diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 3737aa0b5..ecea74fab 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -795,6 +795,10 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.IMAGEGROUPER), undefined, options); } + export function FaceCollectionDocument(options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.FACECOLLECTION), undefined, options); + } + export function LoadingDocument(file: File | string, options: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.LOADING), undefined, { _height: 150, _width: 200, title: typeof file === 'string' ? file : file.name, ...options }, undefined, ''); } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index cb3d9df62..db0de83b9 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -458,7 +458,8 @@ pie title Minerals in my tap water { title: "Shared", toolTip: "Shared Docs", target: Doc.MySharedDocs, ignoreClick: true, icon: "users", funcs: {badgeValue: badgeValue}}, { title: "Trails", toolTip: "Trails ⌘R", target: Doc.UserDoc(), ignoreClick: true, icon: "pres-trail", funcs: {target: getActiveDashTrails}}, { title: "User Doc", toolTip: "User Doc", target: this.setupUserDocView(doc, "myUserDocView"), ignoreClick: true, icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, - { title: "Image Grouper", toolTip: "Image Grouper", target: this.setupImageGrouper(doc, "myImageGrouper"), ignoreClick: true, icon: "folder-open", hidden: false } + { title: "Image Grouper", toolTip: "Image Grouper", target: this.setupImageGrouper(doc, "myImageGrouper"), ignoreClick: true, icon: "folder-open", hidden: false }, + { title: "Face Collection", toolTip: "Face Collection", target: this.setupFaceCollection(doc, "myFaceCollection"), ignoreClick: true, icon: "face-smile", hidden: false }, ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(this)'}})); } @@ -500,6 +501,12 @@ pie title Minerals in my tap water _lockedPosition: true, _type_collection: CollectionViewType.Schema }); } + static setupFaceCollection(doc: Doc, field: string) { + return DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.FaceCollectionDocument(opts), { + dontRegisterView: true, backgroundColor: "dimgray", ignoreClick: true, title: "Face Collection", isSystem: true, childDragAction: dropActionType.embed, + _lockedPosition: true, _type_collection: CollectionViewType.Schema }); + } + /// Initializes the panel of draggable tools that is opened from the left sidebar. static setupToolsBtnPanel(doc: Doc, field:string) { const allTools = DocListCast(DocCast(doc[field])?.data); @@ -702,8 +709,8 @@ pie title Minerals in my tap water { title: "Fit All", icon: "object-group", toolTip: "Fit Docs to View (double click to make sticky)",btnType: ButtonType.ToggleButton, ignoreClick:true, expertMode: false, toolType:"viewAll", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}', onDoubleClick: '{ return showFreeform(this.toolType, _readOnly_, true);}'}}, // Only when floating document is selected in freeform { title: "Clusters", icon: "braille", toolTip: "Show Doc Clusters", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"clusters", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform { title: "Cards", icon: "brain", toolTip: "Flashcards", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"flashcards", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform - { title: "Arrange", icon:"arrow-down-short-wide",toolTip:"Toggle Auto Arrange", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"arrange", funcs: {hidden: 'IsNoviceMode()'}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform - + { title: "Arrange", icon:"arrow-down-short-wide",toolTip:"Auto Arrange", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"arrange", funcs: {hidden: 'IsNoviceMode()'}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform + ] } static textTools():Button[] { diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx index 68584a7fa..fc9c38a11 100644 --- a/src/client/views/KeywordBox.tsx +++ b/src/client/views/KeywordBox.tsx @@ -7,7 +7,7 @@ import { Doc, DocListCast } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; import { NumCast, StrCast } from '../../fields/Types'; -import { emptyFunction } from '../../Utils'; +import { emptyFunction, Utils } from '../../Utils'; import { DocumentType } from '../documents/DocumentTypes'; import { DragManager } from '../util/DragManager'; import { SnappingManager } from '../util/SnappingManager'; @@ -124,7 +124,7 @@ export class KeywordItem extends ObservableReactComponent { render() { return ( -
+
{this._props.keyword} {this.props.isEditing && }
@@ -297,7 +297,7 @@ export class KeywordBox extends ObservableReactComponent {
{(keywordsList as List).map(keyword => { - return ; + return ; })}
{this._props.isEditing ? ( @@ -331,6 +331,7 @@ export class KeywordBox extends ObservableReactComponent { onClick={() => { this.submitLabel(keyword); }} + key={Utils.GenerateGuid()} /> ); })} diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index ada934aea..85c2b3d47 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -62,6 +62,7 @@ import { PresBox, PresElementBox } from './nodes/trails'; import { SearchBox } from './search/SearchBox'; import { ImageLabelBox } from './collections/collectionFreeForm/ImageLabelBox'; import { FaceRecognitionHandler } from './search/FaceRecognitionHandler'; +import { FaceCollectionBox } from './collections/collectionFreeForm/FaceCollectionBox'; dotenv.config(); @@ -135,6 +136,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; PresElementBox, SearchBox, ImageLabelBox, //Here! + FaceCollectionBox, FunctionPlotBox, InkingStroke, LinkBox, diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss new file mode 100644 index 000000000..480d109c8 --- /dev/null +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss @@ -0,0 +1,74 @@ +.face-document-item { + background: #555555; + margin-top: 10px; + margin-bottom: 10px; + padding: 10px; + border-radius: 10px; + position: relative; + + h1 { + color: white; + font-size: 24px; + text-align: center; + } + + .face-collection-buttons { + position: absolute; + top: 10px; + right: 10px; + } + + .face-document-image-container { + display: flex; + justify-content: center; + flex-wrap: wrap; + + .image-wrapper { + position: relative; + width: 70px; + height: 70px; + margin: 10px; + display: flex; + align-items: center; // Center vertically + justify-content: center; // Center horizontally + + img { + width: 100%; + height: 100%; + object-fit: cover; // This ensures the image covers the container without stretching + border-radius: 5px; + border: 2px solid white; + transition: border-color 0.4s; + + &:hover { + border-color: orange; // Change this to your desired hover border color + } + } + + .remove-item { + position: absolute; + bottom: -5; + right: -5; + background-color: rgba(0, 0, 0, 0.5); // Optional: to add a background behind the icon for better visibility + border-radius: 30%; + width: 10px; // Adjust size as needed + height: 10px; // Adjust size as needed + display: flex; + align-items: center; + justify-content: center; + } + } + + // img { + // max-width: 60px; + // margin: 10px; + // border-radius: 5px; + // border: 2px solid white; + // transition: 0.4s; + + // &:hover { + // border-color: orange; + // } + // } + } +} diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx new file mode 100644 index 000000000..1d3f88df1 --- /dev/null +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -0,0 +1,217 @@ +import { observer } from 'mobx-react'; +import React from 'react'; +import { Docs } from '../../../documents/Documents'; +import { DocumentType } from '../../../documents/DocumentTypes'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { FieldView, FieldViewProps } from '../../nodes/FieldView'; +import 'ldrs/ring'; +import { SnappingManager } from '../../../util/SnappingManager'; +import { action, computed, makeObservable, observable, reaction } from 'mobx'; +import { Doc, DocListCast, NumListCast } from '../../../../fields/Doc'; +import { DocData } from '../../../../fields/DocSymbols'; +import { ImageCast, StrCast } from '../../../../fields/Types'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; +import './FaceCollectionBox.scss'; +import { IconButton, Size } from 'browndash-components'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; +import { List } from '../../../../fields/List'; +import { DocumentView } from '../../nodes/DocumentView'; +import { Utils } from '../../../../Utils'; +import { DragManager } from '../../../util/DragManager'; +import * as faceapi from 'face-api.js'; +import { FaceMatcher } from 'face-api.js'; + +interface FaceDocumentProps { + faceDoc: Doc; +} + +/** + * A componenent to visually represent a Face Document. + */ +@observer +export class FaceDocumentItem extends ObservableReactComponent { + private ref: React.RefObject; + @observable _displayImages: boolean = true; + private _dropDisposer?: DragManager.DragDropDisposer; + private _inputRef = React.createRef(); + + constructor(props: any) { + super(props); + makeObservable(this); + this.ref = React.createRef(); + } + + protected createDropTarget = (ele: HTMLDivElement) => { + this._dropDisposer?.(); + ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this._props.faceDoc)); + }; + + protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { + const { docDragData } = de.complete; + if (docDragData) { + const filteredDocs = docDragData.droppedDocuments.filter(doc => doc.type === DocumentType.IMG); + filteredDocs.forEach(doc => { + // If the current Face Document has no items, and the doc has more than one face descriptor, don't let the user add the document first. + if ((this._props.faceDoc[DocData].faceDescriptors as List>).length === 0 && (doc[DocData].faces as List>).length > 1) { + alert('Cannot add a document with multiple faces as the first item!'); + } else { + // Loop through the documents' face descriptors. + // Choose the face with the smallest distance to add. + const float32Array = (this._props.faceDoc[DocData].faceDescriptors as List>).map(faceDescriptor => new Float32Array(Array.from(faceDescriptor))); + const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(StrCast(this._props.faceDoc[DocData].label), float32Array); + const faceDescriptors: faceapi.LabeledFaceDescriptors[] = [labeledFaceDescriptor]; + + const faceMatcher = new FaceMatcher(faceDescriptors, 1); + let cur_lowest_distance = 1; + let cur_matching_face = new List(); + + (doc[DocData].faces as List>).forEach(face => { + // If the face has the current lowest distance, mark it as such + // Once that lowest distance is found, add the face descriptor to the faceDoc, and add the associated doc + const convered_32_array: Float32Array = new Float32Array(Array.from(face)); + const match = faceMatcher.matchDescriptor(convered_32_array); + + if (match.distance < cur_lowest_distance) { + cur_lowest_distance = match.distance; + cur_matching_face = face; + } + }); + + if (doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`]) { + doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`] = new List>([...(doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`] as List>), cur_matching_face]); + } else { + doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`] = new List>([cur_matching_face]); + } + + this._props.faceDoc[DocData].associatedDocs = new List([...DocListCast(this._props.faceDoc[DocData].associatedDocs), doc]); + this._props.faceDoc[DocData].faceDescriptors = new List>([...(this._props.faceDoc[DocData].faceDescriptors as List>), cur_matching_face]); + + //const match = faceMatcher.findBestMatch(cur_descriptor); + } + }); + return false; + } + return false; + } + + /** + * Toggles whether a Face Document displays its associated docs. + */ + @action + onDisplayClick() { + this._displayImages = !this._displayImages; + } + + /** + * Deletes a Face Document. + */ + @action + deleteFaceDocument = () => { + if (Doc.ActiveDashboard) { + Doc.ActiveDashboard[DocData].faceDocuments = new List(DocListCast(Doc.ActiveDashboard[DocData].faceDocuments).filter(doc => doc !== this._props.faceDoc)); + } + }; + + /** + * Deletes a document from a Face Document's associated docs list. + * @param doc + */ + @action + deleteAssociatedDoc = (doc: Doc) => { + this._props.faceDoc[DocData].faceDescriptors = new List>( + (this._props.faceDoc[DocData].faceDescriptors as List>).filter(fd => !(doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`] as List>).includes(fd)) + ); + doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`] = new List>(); + this._props.faceDoc[DocData].associatedDocs = new List(DocListCast(this._props.faceDoc[DocData].associatedDocs).filter(associatedDoc => associatedDoc !== doc)); + }; + + render() { + return ( +
this.createDropTarget(ele!)}> +
+ +
+
+

{StrCast(this._props.faceDoc[DocData].label)}

+
+ this.onDisplayClick()} + icon={this._displayImages ? : } + color={MarqueeOptionsMenu.Instance.userColor} + style={{ width: '19px' }} + /> + {this._displayImages ? ( +
+ {DocListCast(this._props.faceDoc[DocData].associatedDocs).map(doc => { + const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); + return ( +
+ { + await DocumentView.showDocument(doc, { willZoomCentered: true }); + }} + style={{ maxWidth: '60px', margin: '10px' }} + src={`${name}_o.${type}`} + /> +
+ { + this.deleteAssociatedDoc(doc); + }} + icon={'x'} + style={{ width: '4px' }} + size={Size.XSMALL} + /> +
+
+ ); + })} +
+ ) : ( +
+ )} +
+ ); + } +} + +@observer +export class FaceCollectionBox extends ViewBoxBaseComponent() { + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(FaceCollectionBox, fieldKey); + } + + public static Instance: FaceCollectionBox; + + @computed get currentDocs() { + if (Doc.ActiveDashboard) { + return DocListCast(Doc.ActiveDashboard[DocData].faceDocuments); + } else { + return []; + } + } + + constructor(props: any) { + super(props); + makeObservable(this); + FaceCollectionBox.Instance = this; + } + + render() { + return ( +
+ {this.currentDocs.map(doc => { + return ; + })} +
+ ); + } +} + +Docs.Prototypes.TemplateMap.set(DocumentType.FACECOLLECTION, { + layout: { view: FaceCollectionBox, dataField: 'data' }, + options: { acl: '', _width: 400 }, +}); diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index af01d6cbc..421b5d0a6 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -179,6 +179,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { const labels = imageInfo.labels.split('\n'); labels.forEach(label => { label = label.replace(/^\d+\.\s*|-|\*/, '').trim(); + console.log(label); imageInfo.doc[DocData][`${label}`] = true; (imageInfo.doc[DocData].data_labels as List).push(label); }); @@ -198,7 +199,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { for (let index = 0; index < (doc[DocData].data_labels as List).length; index++) { const label = (doc[DocData].data_labels as List)[index]; const embedding = await gptGetEmbedding(label); - doc[`data_labels_embedding_${index + 1}`] = new List(embedding); + doc[DocData][`data_labels_embedding_${index + 1}`] = new List(embedding); } } @@ -209,7 +210,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { // For each image, loop through the labels, and calculate similarity. Associate it with the // most similar one. this._selectedImages.forEach(doc => { - const embedLists = numberRange((doc[DocData].data_labels as List).length).map(n => Array.from(NumListCast(doc[`data_labels_embedding_${n + 1}`]))); + const embedLists = numberRange((doc[DocData].data_labels as List).length).map(n => Array.from(NumListCast(doc[DocData][`data_labels_embedding_${n + 1}`]))); const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map((l, index) => (embedding && similarity(Array.from(embedding), l)!) || 0)); const {label: mostSimilarLabelCollect} = this._labelGroups.map(label => ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index fcd38c42f..ef4622ea2 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -1,14 +1,13 @@ import * as faceapi from 'face-api.js'; -import { FaceMatcher, TinyFaceDetectorOptions } from 'face-api.js'; -import { Doc, DocListCast, NumListCast } from '../../../fields/Doc'; +import { FaceMatcher } from 'face-api.js'; +import { Doc, DocListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; -import { ObjectField } from '../../../fields/ObjectField'; -import { ImageCast, StrCast } from '../../../fields/Types'; -import { DocUtils } from '../../documents/DocUtils'; -import { Deserializable } from '../../util/SerializationHelper'; -import { DocumentView } from '../nodes/DocumentView'; +import { ImageCast, NumCast, StrCast } from '../../../fields/Types'; +/** + * A class that handles face recognition. + */ export class FaceRecognitionHandler { static _instance: FaceRecognitionHandler; private loadedModels: boolean = false; @@ -18,8 +17,12 @@ export class FaceRecognitionHandler { constructor() { FaceRecognitionHandler._instance = this; this.loadModels(); + this.examinedDocs = new Set(DocListCast(Doc.UserDoc()[DocData].examinedFaceDocs, [])); } + /** + * Loads the face detection models. + */ async loadModels() { const MODEL_URL = `/models`; await faceapi.loadFaceDetectionModel(MODEL_URL); @@ -32,19 +35,31 @@ export class FaceRecognitionHandler { return FaceRecognitionHandler._instance ?? new FaceRecognitionHandler(); } + /** + * When a document is added, look for matching face documents. + * @param doc The document being analyzed. + */ public async findMatches(doc: Doc) { if (this.loadedModels) { + // If the Dashboard doesn't have a list of face documents yet, initialize the list. if (!Doc.ActiveDashboard![DocData].faceDocuments) { Doc.ActiveDashboard![DocData].faceDocuments = new List(); } + // If the doc is currently already been examined, or it is being processed, stop examining the document. if (this.examinedDocs.has(doc) || this.processingDocs.has(doc)) { return; } + // Mark the document as being processed. this.processingDocs.add(doc); try { + if (!Doc.UserDoc()[DocData].faceDocNum) { + Doc.UserDoc()[DocData].faceDocNum = 0; + } + + // Get the image the document contains and analyze for faces. const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); const imageURL = `${name}_o.${type}`; @@ -52,30 +67,51 @@ export class FaceRecognitionHandler { const fullFaceDescriptions = await faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors(); + doc[DocData].faces = new List>(); + + // For each face detected, find a match. for (const fd of fullFaceDescriptions) { - const match = this.findMatch(fd.descriptor); + let match = this.findMatch(fd.descriptor); + let converted_list = new List(); + if (match) { + // If a matching Face Document has been found, add the document to the Face Document's associated docs and append the face + // descriptor to the Face Document's descriptor list. const converted_array = Array.from(fd.descriptor); - const converted_list = new List(converted_array); + converted_list = new List(converted_array); match[DocData].associatedDocs = new List([...DocListCast(match[DocData].associatedDocs), doc]); match[DocData].faceDescriptors = new List>([...(match[DocData].faceDescriptors as List>), converted_list]); } else { + // If a matching Face Document has not been found, create a new Face Document. const newFaceDocument = new Doc(); const converted_array = Array.from(fd.descriptor); - const converted_list = new List(converted_array); + converted_list = new List(converted_array); newFaceDocument[DocData].faceDescriptors = new List>(); (newFaceDocument[DocData].faceDescriptors as List>).push(converted_list); - newFaceDocument[DocData].label = `Person ${DocListCast(Doc.ActiveDashboard![DocData].faceDocuments).length + 1}`; + Doc.UserDoc()[DocData].faceDocNum = NumCast(Doc.UserDoc()[DocData].faceDocNum) + 1; + newFaceDocument[DocData].label = `Face ${Doc.UserDoc()[DocData].faceDocNum}`; newFaceDocument[DocData].associatedDocs = new List([doc]); Doc.ActiveDashboard![DocData].faceDocuments = new List([...DocListCast(Doc.ActiveDashboard![DocData].faceDocuments), newFaceDocument]); + match = newFaceDocument; } + + // Assign a field in the document of the matching Face Document. + if (doc[DocData][`FACE DESCRIPTOR - ${match[DocData].label}`]) { + doc[DocData][`FACE DESCRIPTOR - ${match[DocData].label}`] = new List>([...(doc[DocData][`FACE DESCRIPTOR - ${match[DocData].label}`] as List>), converted_list]); + } else { + doc[DocData][`FACE DESCRIPTOR - ${match[DocData].label}`] = new List>([converted_list]); + } + + doc[DocData].faces = new List>([...(doc[DocData].faces as List>), converted_list]); } + // Updates the examined docs field. this.examinedDocs.add(doc); - console.log(this.examinedDocs); - - DocListCast(Doc.ActiveDashboard![DocData].faceDocuments).forEach(doc => console.log(DocListCast(doc[DocData].associatedDocs))); + if (!Doc.UserDoc()[DocData].examinedFaceDocs) { + Doc.UserDoc()[DocData].examinedFaceDocs = new List(); + } + Doc.UserDoc()[DocData].examinedFaceDocs = new List([...DocListCast(Doc.UserDoc()[DocData].examinedFaceDocs), doc]); } catch (error) { console.error('Error processing document:', error); } finally { @@ -84,6 +120,11 @@ export class FaceRecognitionHandler { } } + /** + * Finds a matching Face Document given a descriptor + * @param cur_descriptor The current descriptor whose match is being searched for. + * @returns The most similar Face Document. + */ private findMatch(cur_descriptor: Float32Array) { if (DocListCast(Doc.ActiveDashboard![DocData].faceDocuments).length < 1) { return null; @@ -95,19 +136,20 @@ export class FaceRecognitionHandler { }); const faceMatcher = new FaceMatcher(faceDescriptors, 0.6); const match = faceMatcher.findBestMatch(cur_descriptor); - if (match.label == 'unknown') { return null; } else { for (const doc of DocListCast(Doc.ActiveDashboard![DocData].faceDocuments)) { if (doc[DocData].label === match.label) { - console.log(match.label); return doc; } } } } + /** + * Loads an image + */ private loadImage = (src: string): Promise => { return new Promise((resolve, reject) => { const img = new Image(); diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 4abb23404..ebd30ceba 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -265,6 +265,7 @@ export class Doc extends RefField { public static get MyDockedBtns() { return DocCast(Doc.UserDoc().myDockedBtns); } // prettier-ignore public static get MySearcher() { return DocCast(Doc.UserDoc().mySearcher); } // prettier-ignore public static get MyImageGrouper() { return DocCast(Doc.UserDoc().myImageGrouper); } //prettier-ignore + public static get MyFaceCollection() { return DocCast(Doc.UserDoc().myFaceCollection); } //prettier-ignore public static get MyHeaderBar() { return DocCast(Doc.UserDoc().myHeaderBar); } // prettier-ignore public static get MyLeftSidebarMenu() { return DocCast(Doc.UserDoc().myLeftSidebarMenu); } // prettier-ignore public static get MyLeftSidebarPanel() { return DocCast(Doc.UserDoc().myLeftSidebarPanel); } // prettier-ignore -- cgit v1.2.3-70-g09d2 From fed4bf0b7363b9d58828a7a51f037a26f287d874 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 15 Aug 2024 15:45:44 -0400 Subject: fixed emptyPath type --- src/ServerUtils.ts | 2 +- src/client/views/nodes/DocumentContentsView.tsx | 2 +- src/client/views/nodes/trails/PresBox.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ServerUtils.ts b/src/ServerUtils.ts index 904541fc7..8b2d0b9f6 100644 --- a/src/ServerUtils.ts +++ b/src/ServerUtils.ts @@ -16,7 +16,7 @@ export namespace ServerUtils { export function AddServerHandlerCallback(socket: Socket, message: Message, handler: (args: [T, (res: unknown) => void]) => void) { socket.on(message.Message, (arg: T, fn: (res: unknown) => void) => { Utils.log('S receiving', message.Name, arg, true); - handler([arg, Utils.loggingCallback('S sending', fn, message.Name)]); + handler([arg, Utils.loggingCallback('Sending', fn, message.Name)]); }); } export type RoomHandler = (socket: Socket, room: string) => void; diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 15baebae1..afc160297 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -4,7 +4,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import * as XRegExp from 'xregexp'; import { OmitKeys } from '../../../ClientUtils'; -import { Without, emptyPath } from '../../../Utils'; +import { Without } from '../../../Utils'; import { Doc, Opt } from '../../../fields/Doc'; import { AclPrivate, DocData } from '../../../fields/DocSymbols'; import { ScriptField } from '../../../fields/ScriptField'; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index c403f9415..cf32a0196 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -20,7 +20,7 @@ import { ObjectField } from '../../../../fields/ObjectField'; import { listSpec } from '../../../../fields/Schema'; import { ComputedField, ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, StrCast, toList } from '../../../../fields/Types'; -import { emptyFunction, emptyPath, stringHash } from '../../../../Utils'; +import { emptyFunction, stringHash } from '../../../../Utils'; import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/PresCustomization'; import { DocServer } from '../../../DocServer'; import { Docs } from '../../../documents/Documents'; -- cgit v1.2.3-70-g09d2 From 196bfbcacd554e0d5e1d437588c5719606d21025 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 15 Aug 2024 18:44:55 -0400 Subject: fixed lightbox typing into a one-line text box that is auto-titling --- package-lock.json | 451 +++++++++++++++++--------------------- src/client/views/LightboxView.tsx | 2 +- 2 files changed, 198 insertions(+), 255 deletions(-) diff --git a/package-lock.json b/package-lock.json index 328110401..c2a4aa964 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2620,9 +2620,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz", - "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", + "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3766,18 +3766,18 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.6.tgz", - "integrity": "sha512-kytg6LheUG42V8H/o/Ptz3olSO5kUXW9zF0ox18VnblX6bO2yif1FPItgc3ey1t5ansb1+gbe7SatntqusQupg==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz", + "integrity": "sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.6.tgz", - "integrity": "sha512-ceNGjoXheH9wbIFa1JHmSc9QVjJUvh18KvHrR4/FkJCSi9HXJ+9ee1kUhCOEFfuxNF8UB6WWVrIUOUgRd70t0A==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.7.tgz", + "integrity": "sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q==", "dependencies": { "@babel/runtime": "^7.23.9" }, @@ -3800,13 +3800,13 @@ } }, "node_modules/@mui/material": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.6.tgz", - "integrity": "sha512-0LUIKBOIjiFfzzFNxXZBRAyr9UQfmTAFzbt6ziOU2FDXhorNN2o3N9/32mNJbCA8zJo2FqFU6d3dtoqUDyIEfA==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", + "integrity": "sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/core-downloads-tracker": "^5.16.6", - "@mui/system": "^5.16.6", + "@mui/core-downloads-tracker": "^5.16.7", + "@mui/system": "^5.16.7", "@mui/types": "^7.2.15", "@mui/utils": "^5.16.6", "@popperjs/core": "^2.11.8", @@ -3901,9 +3901,9 @@ } }, "node_modules/@mui/system": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.6.tgz", - "integrity": "sha512-5xgyJjBIMPw8HIaZpfbGAaFYPwImQn7Nyh+wwKWhvkoIeDosQ1ZMVrbTclefi7G8hNmqhip04duYwYpbBFnBgw==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz", + "integrity": "sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==", "dependencies": { "@babel/runtime": "^7.23.9", "@mui/private-theming": "^5.16.6", @@ -9473,9 +9473,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.14.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", - "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "version": "20.14.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz", + "integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==", "dependencies": { "undici-types": "~5.26.4" } @@ -9685,9 +9685,9 @@ } }, "node_modules/@types/react-transition-group": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", - "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", + "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", "dependencies": { "@types/react": "*" } @@ -9859,9 +9859,9 @@ "dev": true }, "node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, "node_modules/@types/uuid": { "version": "10.0.0", @@ -10148,36 +10148,36 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@vue/compiler-core": { - "version": "3.4.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.37.tgz", - "integrity": "sha512-ZDDT/KiLKuCRXyzWecNzC5vTcubGz4LECAtfGPENpo0nrmqJHwuWtRLxk/Sb9RAKtR9iFflFycbkjkY+W/PZUQ==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.38.tgz", + "integrity": "sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/shared": "3.4.37", - "entities": "^5.0.0", + "@vue/shared": "3.4.38", + "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.37.tgz", - "integrity": "sha512-rIiSmL3YrntvgYV84rekAtU/xfogMUJIclUMeIKEtVBFngOL3IeZHhsH3UaFEgB5iFGpj6IW+8YuM/2Up+vVag==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.38.tgz", + "integrity": "sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==", "dependencies": { - "@vue/compiler-core": "3.4.37", - "@vue/shared": "3.4.37" + "@vue/compiler-core": "3.4.38", + "@vue/shared": "3.4.38" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.37.tgz", - "integrity": "sha512-vCfetdas40Wk9aK/WWf8XcVESffsbNkBQwS5t13Y/PcfqKfIwJX2gF+82th6dOpnpbptNMlMjAny80li7TaCIg==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.38.tgz", + "integrity": "sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/compiler-core": "3.4.37", - "@vue/compiler-dom": "3.4.37", - "@vue/compiler-ssr": "3.4.37", - "@vue/shared": "3.4.37", + "@vue/compiler-core": "3.4.38", + "@vue/compiler-dom": "3.4.38", + "@vue/compiler-ssr": "3.4.38", + "@vue/shared": "3.4.38", "estree-walker": "^2.0.2", "magic-string": "^0.30.10", "postcss": "^8.4.40", @@ -10185,18 +10185,18 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.37.tgz", - "integrity": "sha512-TyAgYBWrHlFrt4qpdACh8e9Ms6C/AZQ6A6xLJaWrCL8GCX5DxMzxyeFAEMfU/VFr4tylHm+a2NpfJpcd7+20XA==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.38.tgz", + "integrity": "sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==", "dependencies": { - "@vue/compiler-dom": "3.4.37", - "@vue/shared": "3.4.37" + "@vue/compiler-dom": "3.4.38", + "@vue/shared": "3.4.38" } }, "node_modules/@vue/shared": { - "version": "3.4.37", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.37.tgz", - "integrity": "sha512-nIh8P2fc3DflG8+5Uw8PT/1i17ccFn0xxN/5oE9RfV5SVnd7G0XEFRwakrnNFE/jlS95fpGXDVG5zDETS26nmg==" + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.38.tgz", + "integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==" }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", @@ -11091,9 +11091,9 @@ } }, "node_modules/axios": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", - "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -17145,17 +17145,6 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/dom-walk": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", @@ -17271,9 +17260,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz", - "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==" + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.8.tgz", + "integrity": "sha512-4Nx0gP2tPNBLTrFxBMHpkQbtn2hidPVr/+/FTtcCiBYTucqc70zRyVZiOLj17Ui3wTO7SQ1/N+hkHYzJjBzt6A==" }, "node_modules/elkjs": { "version": "0.9.3", @@ -17394,9 +17383,9 @@ } }, "node_modules/entities": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-5.0.0.tgz", - "integrity": "sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "engines": { "node": ">=0.12" }, @@ -19509,9 +19498,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express-validator": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.1.0.tgz", - "integrity": "sha512-ePn6NXjHRZiZkwTiU1Rl2hy6aUqmi6Cb4/s8sfUsKH7j2yYl9azSpl8xEHcOj1grzzQ+UBEoLWtE1s6FDxW++g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.2.0.tgz", + "integrity": "sha512-I2ByKD8panjtr8Y05l21Wph9xk7kk64UMyvJCl/fFM/3CTJq8isXYPLeKW/aZBCdb/LYNv63PwhY8khw8VWocA==", "dependencies": { "lodash": "^4.17.21", "validator": "~13.12.0" @@ -20330,14 +20319,6 @@ "node": ">= 12.20" } }, - "node_modules/formdata-node/node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", - "engines": { - "node": ">= 14" - } - }, "node_modules/formidable": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz", @@ -20532,20 +20513,32 @@ } }, "node_modules/gaxios": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.0.tgz", - "integrity": "sha512-DSrkyMTfAnAm4ks9Go20QGOcXEyW/NmZhvTYBU2rb4afBB393WIMQPWPEDMl/k8xqiNN9HYq2zao3oWXsdl2Tg==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", - "uuid": "^10.0.0" + "uuid": "^9.0.1" }, "engines": { "node": ">=14" } }, + "node_modules/gaxios/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/gcp-metadata": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", @@ -21247,9 +21240,9 @@ } }, "node_modules/hast-util-from-parse5/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/hast-util-is-element": { "version": "3.0.0", @@ -21300,9 +21293,9 @@ } }, "node_modules/hast-util-raw/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.0", @@ -21331,9 +21324,9 @@ } }, "node_modules/hast-util-to-jsx-runtime/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/hast-util-to-parse5": { "version": "8.0.0", @@ -21369,9 +21362,9 @@ } }, "node_modules/hast-util-to-text/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/hast-util-whitespace": { "version": "3.0.0", @@ -21636,17 +21629,6 @@ "entities": "^4.4.0" } }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/http-browserify": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/http-browserify/-/http-browserify-1.7.0.tgz", @@ -21882,9 +21864,9 @@ ] }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "engines": { "node": ">= 4" } @@ -23721,9 +23703,9 @@ } }, "node_modules/kruptein": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/kruptein/-/kruptein-3.0.6.tgz", - "integrity": "sha512-EQJjTwAJfQkC4NfdQdo3HXM2a9pmBm8oidzH270cYu1MbgXPNPMJuldN7OPX+qdhPO5rw4X3/iKz0BFBfkXGKA==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/kruptein/-/kruptein-3.0.7.tgz", + "integrity": "sha512-vTftnEjfbqFHLqxDUMQCj6gBo5lKqjV4f0JsM8rk8rM3xmvFZ2eSy4YALdaye7E+cDKnEj7eAjFR3vwh8a4PgQ==", "dependencies": { "asn1.js": "^5.4.1" }, @@ -23964,11 +23946,6 @@ "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", "integrity": "sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w==" }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" - }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -24232,9 +24209,9 @@ "dev": true }, "node_modules/mapbox-gl": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.5.2.tgz", - "integrity": "sha512-KUrmDmLFKPp3MSsWGNTH5uvtYwJknV+eFJ+vxiN6hqKpzbme37z+JfYs5Mehs3CgFaIV/pUdnEV9UPUZJPuS+Q==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.6.0.tgz", + "integrity": "sha512-xjYHHIJDh6haYcKY+/9jh1eywwYfIOWCgT5Fowj4JriZexx/oOtg2S7BQDMZtpFyg9IN4VLCysmUWxY0pFNRWA==", "workspaces": [ "src/style-spec", "test/build/typings" @@ -24257,7 +24234,6 @@ "gl-matrix": "^3.4.3", "grid-index": "^1.1.0", "kdbush": "^4.0.2", - "lodash.clonedeep": "^4.5.0", "murmurhash-js": "^1.0.0", "pbf": "^3.2.1", "potpack": "^2.0.0", @@ -24265,7 +24241,6 @@ "rw": "^1.3.3", "serialize-to-js": "^3.1.2", "supercluster": "^8.0.1", - "tiny-lru": "^11.2.11", "tinyqueue": "^3.0.0", "tweakpane": "^4.0.4", "vt-pbf": "^3.1.3" @@ -24302,17 +24277,6 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, - "node_modules/markdown-it/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/markdown-table": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", @@ -24544,9 +24508,9 @@ } }, "node_modules/mdast-util-gfm-footnote/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-gfm-footnote/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -25039,9 +25003,9 @@ } }, "node_modules/mdast-util-gfm-strikethrough/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-gfm-strikethrough/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -25536,9 +25500,9 @@ } }, "node_modules/mdast-util-gfm-table/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-gfm-table/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -26032,9 +25996,9 @@ } }, "node_modules/mdast-util-gfm-task-list-item/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-gfm-task-list-item/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -26513,9 +26477,9 @@ } }, "node_modules/mdast-util-gfm/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-gfm/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -27012,9 +26976,9 @@ } }, "node_modules/mdast-util-math/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-math/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -27510,9 +27474,9 @@ } }, "node_modules/mdast-util-mdx-expression/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-mdx-expression/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -28015,9 +27979,9 @@ } }, "node_modules/mdast-util-mdx-jsx/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-mdx-jsx/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -28513,9 +28477,9 @@ } }, "node_modules/mdast-util-mdxjs-esm/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-mdxjs-esm/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -29146,9 +29110,9 @@ } }, "node_modules/mdast-util-to-markdown/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": { "version": "4.0.0", @@ -30951,9 +30915,9 @@ } }, "node_modules/mocha": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", - "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", "dev": true, "dependencies": { "ansi-colors": "^4.1.3", @@ -31143,9 +31107,9 @@ } }, "node_modules/mongoose": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.2.tgz", - "integrity": "sha512-GZB4rHMdYfGatV+23IpCrqFbyCOjCNOHXgWbirr92KRwTEncBrtW3kgU9vmpKjsGf7nMmnAy06SwWUv1vhDkSg==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.3.tgz", + "integrity": "sha512-OubSDbsAclDFGHjV82MsKyIGQWFc42Ot1l+0dhRS6U9xODM7rm/ES/WpOQd8Ds9j0Mx8QzxZtrSCnBh6o9wUqw==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", @@ -34265,9 +34229,9 @@ } }, "node_modules/openai": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.55.1.tgz", - "integrity": "sha512-FziYJcWl+SAGbt5AcRIzVzNcnKohpEMQdtzVOmHFbBp/if7x2+ACqgxF2XUbyi2PcKONPcVpmtG5h9qoDAEXwQ==", + "version": "4.55.7", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.55.7.tgz", + "integrity": "sha512-I2dpHTINt0Zk+Wlns6KzkKu77MmNW3VfIIQf5qYziEUI6t7WciG1zTobfKqdPzBmZi3TTM+3DtjPumxQdcvzwA==", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", @@ -34290,9 +34254,9 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.43.tgz", - "integrity": "sha512-Mw/YlgXnyJdEwLoFv2dpuJaDFriX+Pc+0qOBJ57jC1H6cDxIj2xc5yUrdtArDVG0m+KV6622a4p2tenEqB3C/g==", + "version": "18.19.44", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.44.tgz", + "integrity": "sha512-ZsbGerYg72WMXUIE9fYxtvfzLEuq6q8mKERdWFnqTmOvudMxnz+CBNRoOwJ2kNpFOncrKjT1hZwxjlFgQ9qvQA==", "dependencies": { "undici-types": "~5.26.4" } @@ -34542,17 +34506,6 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/parse5/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/parseley": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", @@ -35110,9 +35063,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", - "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -35331,17 +35284,17 @@ } }, "node_modules/prosemirror-transform": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.9.0.tgz", - "integrity": "sha512-5UXkr1LIRx3jmpXXNKDhv8OyAOeLTGuXNwdVfg8x27uASna/wQkr9p6fD3eupGOi4PLJfbezxTyi/7fSJypXHg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.0.tgz", + "integrity": "sha512-9UOgFSgN6Gj2ekQH5CTDJ8Rp/fnKR2IkYfGdzzp5zQMFsS4zDllLVx/+jGcX86YlACpG7UR5fwAXiWzxqWtBTg==", "dependencies": { "prosemirror-model": "^1.21.0" } }, "node_modules/prosemirror-view": { - "version": "1.33.9", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.9.tgz", - "integrity": "sha512-xV1A0Vz9cIcEnwmMhKKFAOkfIp8XmJRnaZoPqNXrPS7EK5n11Ov8V76KhR0RsfQd/SIzmWY+bg+M44A2Lx/Nnw==", + "version": "1.33.10", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.10.tgz", + "integrity": "sha512-wsKg9JeQkWlkXG8DDcloI/tbB9r3CysziubigoC8wTuE6zobN/9cl8bGRk1J1XjkUp7rxGBziOSxrhoILL84hg==", "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -35970,9 +35923,9 @@ } }, "node_modules/react-icons": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", - "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", "peerDependencies": { "react": "*" } @@ -36667,9 +36620,9 @@ } }, "node_modules/remark-parse/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/remark-parse/node_modules/mdast-util-from-markdown": { "version": "2.0.1", @@ -39460,9 +39413,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/terser": { - "version": "5.31.5", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.5.tgz", - "integrity": "sha512-YPmas0L0rE1UyLL/llTWA0SiDOqIcAQYLeUj7cJYzXHlRTAnMSg9pPe4VJ5PlKvTrPQsdVFuiRiwyeNlYgwh2Q==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -39627,14 +39580,6 @@ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" }, - "node_modules/tiny-lru": { - "version": "11.2.11", - "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.2.11.tgz", - "integrity": "sha512-27BIW0dIWTYYoWNnqSmoNMKe5WIbkXsc0xaCQHd3/3xT2XMuMJrzHdrO9QBFR14emBz1Bu0dOAs2sCBBrvgPQA==", - "engines": { - "node": ">=12" - } - }, "node_modules/tinycolor2": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", @@ -40737,9 +40682,9 @@ } }, "node_modules/unified/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/uninstall": { "version": "0.0.0", @@ -40774,9 +40719,9 @@ } }, "node_modules/unist-util-find-after/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/unist-util-is": { "version": "6.0.0", @@ -40791,9 +40736,9 @@ } }, "node_modules/unist-util-is/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/unist-util-position": { "version": "5.0.0", @@ -40808,9 +40753,9 @@ } }, "node_modules/unist-util-position/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/unist-util-remove-position": { "version": "5.0.0", @@ -40826,9 +40771,9 @@ } }, "node_modules/unist-util-remove-position/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/unist-util-stringify-position": { "version": "3.0.3", @@ -40870,14 +40815,14 @@ } }, "node_modules/unist-util-visit-parents/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/unist-util-visit/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/universal-user-agent": { "version": "7.0.2", @@ -41234,9 +41179,9 @@ } }, "node_modules/vfile-location/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/vfile-message": { "version": "4.0.2", @@ -41252,9 +41197,9 @@ } }, "node_modules/vfile-message/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/vfile-message/node_modules/unist-util-stringify-position": { "version": "4.0.0", @@ -41269,9 +41214,9 @@ } }, "node_modules/vfile/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/vfile/node_modules/unist-util-stringify-position": { "version": "4.0.0", @@ -41350,9 +41295,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -41388,13 +41333,11 @@ } }, "node_modules/web-streams-polyfill": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", - "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", - "optional": true, - "peer": true, + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", "engines": { - "node": ">= 8" + "node": ">= 14" } }, "node_modules/web-worker": { diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 334983ad0..b8b73e7dd 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -276,7 +276,7 @@ export class LightboxView extends ObservableReactComponent { }}> { this._docView = r !== null ? r : undefined; })} -- cgit v1.2.3-70-g09d2 From 325aa35c4bd5f57240ead2ec5f22ea9c4f19d522 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 15 Aug 2024 23:16:09 -0400 Subject: fixed dropping on multi col/row collections with margins --- .../CollectionMulticolumnView.scss | 69 +++++++++------- .../CollectionMulticolumnView.tsx | 94 +++++++++++----------- .../CollectionMultirowView.scss | 49 ++++++----- .../CollectionMultirowView.tsx | 31 +++---- src/client/views/nodes/trails/PresBox.tsx | 22 ++--- 5 files changed, 143 insertions(+), 122 deletions(-) diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss index f983fd815..06d78c39e 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss @@ -1,43 +1,50 @@ -.collectionMulticolumnView_contents { - display: flex; - //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template) - width: 100%; +.collectionMulticolumnView_drop { height: 100%; + top: 0; + left: 0; + position: absolute; - .document-wrapper { + .collectionMulticolumnView_contents { display: flex; - flex-direction: column; + //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template) width: 100%; - align-items: center; - position: relative; - > .iconButton-container { - top: 0; - left: 0; - position: absolute; - } - - .contentFittingDocumentView { - margin: auto; - } + height: 100%; - .label-wrapper { + .document-wrapper { display: flex; - flex-direction: row; - justify-content: center; - height: 20px; + flex-direction: column; + width: 100%; + align-items: center; + position: relative; + > .iconButton-container { + top: 0; + left: 0; + position: absolute; + } + + .contentFittingDocumentView { + margin: auto; + } + + .label-wrapper { + display: flex; + flex-direction: row; + justify-content: center; + height: 20px; + } } - } - .multiColumnResizer { - cursor: ew-resize; - transition: 0.5s opacity ease; - display: flex; - flex-direction: column; + .multiColumnResizer { + cursor: ew-resize; + transition: 0.5s opacity ease; + display: flex; + flex-direction: column; - .multiColumnResizer-hdl { - width: 100%; - height: 100%; - transition: 0.5s background-color ease; + .multiColumnResizer-hdl { + width: 100%; + height: 100%; + transition: 0.5s background-color ease; + } } } } diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 5125bdb6c..c6884d866 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -17,6 +17,7 @@ import './CollectionMulticolumnView.scss'; import ResizeBar from './MulticolumnResizer'; import WidthLabel from './MulticolumnWidthLabel'; import { dropActionType } from '../../../util/DropActionTypes'; +import { SnappingManager } from '../../../util/SnappingManager'; interface WidthSpecifier { magnitude: number; @@ -211,15 +212,14 @@ export class CollectionMulticolumnView extends CollectionSubView() { return Transform.Identity(); }; - @undoBatch onInternalDrop = (e: Event, de: DragManager.DropEvent) => { let dropInd = -1; - if (de.complete.docDragData && this._mainCont) { + if (de.complete.docDragData && this._contRef.current) { let curInd = -1; de.complete.docDragData?.droppedDocuments.forEach(d => { curInd = this.childDocs.indexOf(d); }); - Array.from(this._mainCont.children).forEach((child, index) => { + Array.from(this._contRef.current.children).forEach((child, index) => { const brect = child.getBoundingClientRect(); if (brect.x < de.x && brect.x + brect.width > de.x) { if (curInd !== -1 && curInd === Math.floor(index / 2)) { @@ -317,11 +317,11 @@ export class CollectionMulticolumnView extends CollectionSubView() { this.childLayouts.forEach((layout, i) => { collector.push( // eslint-disable-next-line react/no-array-index-key - +
{this.getDisplayDoc(layout)} {this.layoutDoc._chromeHidden ? null : ( -
@@ -343,49 +343,53 @@ export class CollectionMulticolumnView extends CollectionSubView() { return collector; } + _contRef = React.createRef(); render() { return ( -
- {this.contents} - {!this._startIndex ? null : ( - -
{ - this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown); - })}> -
+
+ )} + {this._startIndex > this.childLayoutPairs.length - 1 || !this.maxShown ? null : ( + +
{ + this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown); + })}> + } color={SettingsManager.userColor} /> +
+
+ )} +
); } diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss index f44eacb2a..0d49fabaa 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss @@ -1,34 +1,41 @@ -.collectionMultirowView_contents { - display: flex; - //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template) - width: 100%; +.collectionMultirowView_drop { height: 100%; - flex-direction: column; + top: 0; + left: 0; + position: absolute; - .document-wrapper { + .collectionMultirowView_contents { display: flex; - flex-direction: row; + //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template) + width: 100%; height: 100%; - align-items: center; + flex-direction: column; - .label-wrapper { + .document-wrapper { display: flex; flex-direction: row; - justify-content: center; - height: 20px; + height: 100%; + align-items: center; + + .label-wrapper { + display: flex; + flex-direction: row; + justify-content: center; + height: 20px; + } } - } - .multiRowResizer { - cursor: ns-resize; - transition: 0.5s opacity ease; - display: flex; - flex-direction: row; + .multiRowResizer { + cursor: ns-resize; + transition: 0.5s opacity ease; + display: flex; + flex-direction: row; - .multiRowResizer-hdl { - width: 100%; - height: 100%; - transition: 0.5s background-color ease; + .multiRowResizer-hdl { + width: 100%; + height: 100%; + transition: 0.5s background-color ease; + } } } } diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 2833ff2f8..04b85e182 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -196,12 +196,12 @@ export class CollectionMultirowView extends CollectionSubView() { @undoBatch onInternalDrop = (e: Event, de: DragManager.DropEvent) => { let dropInd = -1; - if (de.complete.docDragData && this._mainCont) { + if (de.complete.docDragData && this._contRef.current) { let curInd = -1; de.complete.docDragData?.droppedDocuments.forEach(d => { curInd = this.childDocs.indexOf(d); }); - Array.from(this._mainCont.children).forEach((child, index) => { + Array.from(this._contRef.current.children).forEach((child, index) => { const brect = child.getBoundingClientRect(); if (brect.y < de.y && brect.y + brect.height > de.y) { if (curInd !== -1 && curInd === Math.floor(index / 2)) { @@ -318,20 +318,23 @@ export class CollectionMultirowView extends CollectionSubView() { return collector; } + _contRef = React.createRef(); render() { return ( -
- {this.contents} +
+
+ {this.contents} +
); } diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index cf32a0196..7448fa898 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -2,7 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import Slider from '@mui/material/Slider'; import { Button, Dropdown, DropdownType, IconButton, Toggle, ToggleType, Type } from 'browndash-components'; -import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx'; +import { IReactionDisposer, ObservableSet, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { AiOutlineSend } from 'react-icons/ai'; @@ -10,7 +10,8 @@ import { BiMicrophone } from 'react-icons/bi'; import { FaArrowDown, FaArrowLeft, FaArrowRight, FaArrowUp } from 'react-icons/fa'; import ReactLoading from 'react-loading'; import ReactTextareaAutosize from 'react-textarea-autosize'; -import { lightOrDark, returnFalse, returnOne, setupMoveUpEvents, StopEvent } from '../../../../ClientUtils'; +import { StopEvent, lightOrDark, returnFalse, returnOne, setupMoveUpEvents } from '../../../../ClientUtils'; +import { emptyFunction, stringHash } from '../../../../Utils'; import { Doc, DocListCast, Field, FieldResult, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { Animation, DocData, TransitionTimer } from '../../../../fields/DocSymbols'; import { Copy } from '../../../../fields/FieldSymbols'; @@ -20,24 +21,23 @@ import { ObjectField } from '../../../../fields/ObjectField'; import { listSpec } from '../../../../fields/Schema'; import { ComputedField, ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DocCast, NumCast, StrCast, toList } from '../../../../fields/Types'; -import { emptyFunction, stringHash } from '../../../../Utils'; -import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/PresCustomization'; import { DocServer } from '../../../DocServer'; -import { Docs } from '../../../documents/Documents'; +import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/PresCustomization'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; +import { Docs } from '../../../documents/Documents'; import { DictationManager } from '../../../util/DictationManager'; import { dropActionType } from '../../../util/DropActionTypes'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { SerializationHelper } from '../../../util/SerializationHelper'; import { SnappingManager } from '../../../util/SnappingManager'; -import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager'; -import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; -import { CollectionFreeFormPannableContents } from '../../collections/collectionFreeForm/CollectionFreeFormPannableContents'; +import { UndoManager, undoBatch, undoable } from '../../../util/UndoManager'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { pinDataTypes as dataTypes } from '../../PinFuncs'; import { CollectionView } from '../../collections/CollectionView'; import { TreeView } from '../../collections/TreeView'; -import { ViewBoxBaseComponent } from '../../DocComponent'; +import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; +import { CollectionFreeFormPannableContents } from '../../collections/collectionFreeForm/CollectionFreeFormPannableContents'; import { Colors } from '../../global/globalEnums'; -import { pinDataTypes as dataTypes } from '../../PinFuncs'; import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { FocusViewOptions } from '../FocusViewOptions'; @@ -47,7 +47,7 @@ import CubicBezierEditor, { EaseFuncToPoints, TIMING_DEFAULT_MAPPINGS } from './ import './PresBox.scss'; import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums'; import SlideEffect from './SlideEffect'; -import { AnimationSettings, easeItems, effectItems, effectTimings, movementItems, presEffectDefaultTimings, springMappings, springPreviewColors, SpringSettings, SpringType } from './SpringUtils'; +import { AnimationSettings, SpringSettings, SpringType, easeItems, effectItems, effectTimings, movementItems, presEffectDefaultTimings, springMappings, springPreviewColors } from './SpringUtils'; @observer export class PresBox extends ViewBoxBaseComponent() { -- cgit v1.2.3-70-g09d2 From d0c072b36ae6b9a65f993592bc7a27719126fda9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 15 Aug 2024 23:18:38 -0400 Subject: from last --- .../collections/collectionMulticolumn/CollectionMulticolumnView.tsx | 2 +- .../views/collections/collectionMulticolumn/CollectionMultirowView.tsx | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index c6884d866..c4c025ded 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -10,7 +10,7 @@ import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types import { DragManager } from '../../../util/DragManager'; import { SettingsManager } from '../../../util/SettingsManager'; import { Transform } from '../../../util/Transform'; -import { undoBatch, undoable } from '../../../util/UndoManager'; +import { undoable } from '../../../util/UndoManager'; import { DocumentView } from '../../nodes/DocumentView'; import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import './CollectionMulticolumnView.scss'; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 04b85e182..bda8e91ac 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -6,7 +6,6 @@ import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types import { DragManager } from '../../../util/DragManager'; import { dropActionType } from '../../../util/DropActionTypes'; import { Transform } from '../../../util/Transform'; -import { undoBatch } from '../../../util/UndoManager'; import { DocumentView } from '../../nodes/DocumentView'; import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import './CollectionMultirowView.scss'; @@ -193,7 +192,6 @@ export class CollectionMultirowView extends CollectionSubView() { return Transform.Identity(); // type coersion, this case should never be hit }; - @undoBatch onInternalDrop = (e: Event, de: DragManager.DropEvent) => { let dropInd = -1; if (de.complete.docDragData && this._contRef.current) { -- cgit v1.2.3-70-g09d2 From b6f6acb80f57011594d39b9ce576a5e77862cb7f Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 15 Aug 2024 23:50:01 -0400 Subject: fixed horiz alignment of items in multicolumnview --- src/client/views/collections/CollectionStackingView.tsx | 9 +++++---- .../collectionMulticolumn/CollectionMulticolumnView.tsx | 5 ++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 0f12c111e..3f8aee792 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -320,7 +320,7 @@ export class CollectionStackingView extends CollectionSubView this.getDocHeight(doc); const panelHeight = () => (this.isStackingView ? height() : Math.min(height(), this._props.PanelHeight())); - const panelWidth = () => (this.isStackingView ? width() : this.columnWidth); + const panelWidth = () => this.columnWidth; const stackedDocTransform = () => this.getDocTransform(doc); this._docXfs.push({ stackedDocTransform, width, height }); return count > this._renderCount ? null : ( @@ -373,9 +373,10 @@ export class CollectionStackingView extends CollectionSubView { - const { columnUnitLength } = this; - if (columnUnitLength === undefined) { + if (this.columnUnitLength === undefined) { return Transform.Identity(); // we're still waiting on promises to resolve } let offset = 0; // eslint-disable-next-line no-restricted-syntax for (const { layout: candidate } of this.childLayoutPairs) { if (candidate === layout) { - return this.ScreenToLocalBoxXf().translate(0, -offset / (this._props.NativeDimScaling?.() || 1)); + return this.ScreenToLocalBoxXf().translate(-offset / (this._props.NativeDimScaling?.() || 1), 0); } offset += this.lookupPixels(candidate) + resizerWidth; } -- cgit v1.2.3-70-g09d2 From e57584a1be9d428fb40fc789494a7ac0ac14fb84 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 19 Aug 2024 16:42:56 -0400 Subject: extensive fixes to DiagramBox --- src/client/documents/Documents.ts | 1 + src/client/util/CurrentUserUtils.ts | 16 +- .../collectionGrid/CollectionGridView.tsx | 6 +- src/client/views/nodes/DiagramBox.scss | 112 +++---- src/client/views/nodes/DiagramBox.tsx | 360 ++++++++------------- .../views/nodes/formattedText/FormattedTextBox.tsx | 3 +- 6 files changed, 206 insertions(+), 292 deletions(-) diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index d7fdf016c..b108b73db 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -256,6 +256,7 @@ export class DocumentOptions { _layout_nativeDimEditable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers', false); _layout_reflowVertical?: BOOLt = new BoolInfo('permit vertical resizing with content "reflow"'); _layout_reflowHorizontal?: BOOLt = new BoolInfo('permit horizontal resizing with content reflow'); + _layout_noSidebar?: BOOLt = new BoolInfo('whether to display the sidebar toggle button'); layout_boxShadow?: string; // box-shadow css string OR "standard" to use dash standard box shadow layout_maxShown?: NUMt = new NumInfo('maximum number of children to display at one time (see multicolumnview)'); _layout_autoHeight?: BOOLt = new BoolInfo('whether document automatically resizes vertically to display contents'); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index c99ce1832..311b86fa4 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -321,20 +321,16 @@ export class CurrentUserUtils { const rtfield = new RichTextField(JSON.stringify( {doc: {type:"doc",content:[ {type:"code_block",content:[ - {type:"text",text:"^@mermaids"}, - {type:"text",text:"\n\n"}, - {type:"text",text:"pie "}, - {type:"text",text:"title"}, - {type:"text",text:" "}, - {type:"text",text:"Minerals in my tap water"}, - {type:"text",text:"\n \"Calcium\" : "}, + {type:"text",text:`^@mermaids\n`}, + {type:"text",text:`\n pie title Minerals in my tap water`}, + {type:"text",text:`\n "Calcium" : `}, {type:"dashField",attrs:{fieldKey:"calcium",docId:"",hideKey:true,hideValue:false,editable:true}}, - {type:"text",text:"\n \"Potassium\" : "}, + {type:"text",text:`\n "Potassium" : `}, {type:"dashField",attrs:{fieldKey:"pot",docId:"",hideKey:true,hideValue:false,editable:true}}, - {type:"text",text:"\n \"Magnesium\" : 10.01"} + {type:"text",text:`\n "Magnesium" : 10.01`} ]} ]}, - selection:{type:"text",anchor:109,head:109} + selection:{type:"text",anchor:1,head:1} }), `^@mermaids pie title Minerals in my tap water diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 2d9191dd7..61bd0241c 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -13,7 +13,7 @@ import { undoBatch } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; import { ContextMenuProps } from '../../ContextMenuItem'; import { DocumentView } from '../../nodes/DocumentView'; -import { CollectionSubView } from '../CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import './CollectionGridView.scss'; import Grid, { Layout } from './Grid'; @@ -26,7 +26,7 @@ export class CollectionGridView extends CollectionSubView() { @observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll private dropLocation: object = {}; // sets the drop location for external drops - constructor(props: any) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); } @@ -200,7 +200,7 @@ export class CollectionGridView extends CollectionSubView() { whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged} onClickScript={this.onChildClickHandler} renderDepth={this._props.renderDepth + 1} - dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy' + dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as 'x' | 'y' | 'xy'} /> ); } diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss index d2749f1ad..323638bff 100644 --- a/src/client/views/nodes/DiagramBox.scss +++ b/src/client/views/nodes/DiagramBox.scss @@ -1,3 +1,5 @@ +$searchbarHeight: 50px; + .DIYNodeBox { width: 100%; height: 100%; @@ -6,83 +8,75 @@ align-items: center; justify-content: center; - .DIYNodeBox-wrapper { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - .DIYNodeBox { - /* existing code */ - - .DIYNodeBox-iframe { - height: 100%; - width: 100%; - border: none; + .DIYNodeBox { + /* existing code */ - } + .DIYNodeBox-iframe { + height: 100%; + width: 100%; + border: none; } + } - .search-bar { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - padding: 10px; + .DIYNodeBox-searchbar { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: $searchbarHeight; + padding: 10px; - input[type="text"] { - flex: 1; - margin-right: 10px; - } + input[type='text'] { + flex: 1; + margin-right: 10px; + } - button { - padding: 5px 10px; - } + button { + padding: 5px 10px; } + } - .content { + .DIYNodeBox-content { + flex: 1; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: calc(100% - $searchbarHeight); + .diagramBox { flex: 1; display: flex; justify-content: center; align-items: center; - width:100%; - height:100%; - .diagramBox{ + width: 100%; + height: 100%; + svg { flex: 1; display: flex; justify-content: center; align-items: center; - width:100%; - height:100%; - svg{ - flex: 1; - display: flex; - justify-content: center; - align-items: center; - width:100%; - height:100%; - } + width: 100%; + height: 100%; } } + } - .loading-circle { - position: relative; - width: 50px; - height: 50px; - border-radius: 50%; - border: 3px solid #ccc; - border-top-color: #333; - animation: spin 1s infinite linear; - } + .loading-circle { + position: relative; + width: 50px; + height: 50px; + border-radius: 50%; + border: 3px solid #ccc; + border-top-color: #333; + animation: spin 1s infinite linear; + } - @keyframes spin { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); } } -} \ No newline at end of file +} diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 32969fa53..36deb2d8d 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -1,284 +1,198 @@ import mermaid from 'mermaid'; -import { action, makeObservable, observable, reaction } from 'mobx'; +import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; -import { List } from '../../../fields/List'; +import { DocData } from '../../../fields/DocSymbols'; import { RichTextField } from '../../../fields/RichTextField'; -import { DocCast, NumCast } from '../../../fields/Types'; +import { Cast, DocCast, NumCast } from '../../../fields/Types'; +import { Gestures } from '../../../pen-gestures/GestureTypes'; import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT'; import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { LinkManager } from '../../util/LinkManager'; +import { undoable } from '../../util/UndoManager'; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { InkingStroke } from '../InkingStroke'; import './DiagramBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; +import { FormattedTextBox } from './formattedText/FormattedTextBox'; @observer export class DiagramBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DiagramBox, fieldKey); } - private _ref: React.RefObject = React.createRef(); - private _dragRef = React.createRef(); + static isPointInBox = (box: Doc, pt: number[]): boolean => { + if (typeof pt[0] === 'number' && typeof box.x === 'number' && typeof box.y === 'number' && typeof pt[1] === 'number') { + return pt[0] < box.x + NumCast(box.width) && pt[0] > box.x && pt[1] > box.y && pt[1] < box.y + NumCast(box.height); + } + return false; + }; + constructor(props: FieldViewProps) { super(props); makeObservable(this); } - @observable inputValue = ''; - @observable loading = false; - @observable errorMessage = ''; - @observable mermaidCode = ''; + @observable _showCode = false; + @observable _inputValue = ''; + @observable _generating = false; + @observable _errorMessage = ''; - @action handleInputChange = (e: React.ChangeEvent) => { - this.inputValue = e.target.value; - }; - async componentDidMount() { + @computed get mermaidcode() { + return Cast(this.Document[DocData].text, RichTextField, null)?.Text ?? ''; + } + + componentDidMount() { this._props.setContentViewBox?.(this); mermaid.initialize({ securityLevel: 'loose', startOnLoad: true, flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, }); - this.mermaidCode = 'asdasdasd'; - const docArray: Doc[] = DocListCast(this.Document.data); - let mermaidCodeDoc = docArray.filter(doc => doc.type === 'rich text'); - mermaidCodeDoc = mermaidCodeDoc.filter(doc => (doc.text as RichTextField).Text === 'mermaidCodeTitle'); - if (mermaidCodeDoc[0]) { - if (typeof mermaidCodeDoc[0].title === 'string') { - console.log(mermaidCodeDoc[0].title); - if (mermaidCodeDoc[0].title !== '') { - this.renderMermaidAsync(mermaidCodeDoc[0].title); - } - } - } - // this will create a text doc far away where the user cant to save the mermaid code, where it will then be accessed when flipped to the diagram box side - // the code is stored in the title since it is much easier to change than in the text - else { - DocumentManager.Instance.AddViewRenderedCb(this.Document, docViewForYourCollection => { - if (docViewForYourCollection && docViewForYourCollection.ComponentView) { - if (docViewForYourCollection.ComponentView.addDocument && docViewForYourCollection.ComponentView.removeDocument) { - const newDoc = Docs.Create.TextDocument('mermaidCodeTitle', { title: '', x: 9999 + NumCast(this.layoutDoc._width), y: 9999 }); - docViewForYourCollection.ComponentView?.addDocument(newDoc); - } - } - }); - } - console.log(this.Document.title); - // this is so that ever time a new doc, text node or ink node, is created, this.createMermaidCode will run which will create a save + // when a new doc/text/ink/shape is created in the freeform view, this generates the corresponding mermaid diagram code reaction( () => DocListCast(this.Document.data), - () => this.convertDrawingToMermaidCode(), + docArray => docArray.length && this.convertDrawingToMermaidCode(docArray), { fireImmediately: true } ); } - renderMermaid = async (str: string) => { + renderMermaid = (str: string) => { try { - const { svg, bindFunctions } = await this.mermaidDiagram(str); - return { svg, bindFunctions }; + return mermaid.render('graph' + Date.now(), str); } catch (error) { - console.error('Error rendering mermaid diagram:', error); return { svg: '', bindFunctions: undefined }; } }; - mermaidDiagram = async (str: string) => mermaid.render('graph' + Date.now(), str); - async renderMermaidAsync(mermaidCode: string) { + renderMermaidAsync = async (mermaidCode: string, dashDiv: HTMLDivElement) => { try { const { svg, bindFunctions } = await this.renderMermaid(mermaidCode); - const dashDiv = document.getElementById('dashDiv' + this.Document.title); - if (dashDiv) { - dashDiv.innerHTML = svg; - if (bindFunctions) { - bindFunctions(dashDiv); - } - } + dashDiv.innerHTML = svg; + bindFunctions?.(dashDiv); } catch (error) { console.error('Error rendering Mermaid:', error); } - } - @action handleRenderClick = () => { - this.generateMermaidCode(); }; - @action async generateMermaidCode() { - console.log('Generating Mermaid Code'); - this.loading = true; - let prompt = ''; - // let docArray: Doc[] = DocListCast(this.Document.data); - // let mermaidCodeDoc = docArray.filter(doc => doc.type == 'rich text') - // mermaidCodeDoc=mermaidCodeDoc.filter(doc=>(doc.text as RichTextField).Text=='mermaidCodeTitle') - // if(mermaidCodeDoc[0]){ - // console.log(mermaidCodeDoc[0].title) - // if(typeof mermaidCodeDoc[0].title=='string'){ - // console.log(mermaidCodeDoc[0].title) - // if(mermaidCodeDoc[0].title!=""){ - // prompt="Edit this code "+this.inputValue+": "+mermaidCodeDoc[0].title - // console.log("you have to see me") - // } - // } - // } - // else{ - prompt = 'Write this in mermaid code and only give me the mermaid code: ' + this.inputValue; - console.log('there is no text save'); - // } - const res = await gptAPICall(prompt, GPTCallType.MERMAID); - this.loading = false; - if (res === 'Error connecting with API.') { - // If GPT call failed - console.error('GPT call failed'); - this.errorMessage = 'GPT call failed; please try again.'; - } else if (res !== null) { - // If GPT call succeeded, set htmlCode;;; TODO: check if valid html - if (this.isValidCode(res)) { - this.mermaidCode = res; - console.log('GPT call succeeded:' + res); - this.errorMessage = ''; - } else { - console.error('GPT call succeeded but invalid html; please try again.'); - this.errorMessage = 'GPT call succeeded but invalid html; please try again.'; - } - } - this.renderMermaidAsync.call(this, this.removeWords(this.mermaidCode)); - this.loading = false; - } - isValidCode = (html: string) => true; - removeWords(inputStrIn: string) { - const inputStr = inputStrIn.replace('```mermaid', ''); - return inputStr.replace('```', ''); - } + + setMermaidCode = undoable((res: string) => { + this.Document[DocData].text = new RichTextField( + JSON.stringify({ + doc: { + type: 'doc', + content: [ + { + type: 'code_block', + content: [ + { type: 'text', text: `^@mermaids\n` }, + { type: 'text', text: this.removeWords(res) }, + ], + }, + ], + }, + selection: { type: 'text', anchor: 1, head: 1 }, + }), + res + ); + }, 'set mermaid code'); + + generateMermaidCode = action(() => { + this._generating = true; + const prompt = 'Write this in mermaid code and only give me the mermaid code: ' + this._inputValue; + gptAPICall(prompt, GPTCallType.MERMAID).then( + action(res => { + this._generating = false; + if (res === 'Error connecting with API.') { + this._errorMessage = 'GPT call failed; please try again.'; + } + // If GPT call succeeded, set mermaid code on Doc which will trigger a rendering if _showCode is false + else if (res && this.isValidCode(res)) { + this.setMermaidCode(res); + this._errorMessage = ''; + } else { + this._errorMessage = 'GPT call succeeded but invalid html; please try again.'; + } + }) + ); + }); + isValidCode = (html: string) => (html ? true : false); + removeWords = (inputStrIn: string) => inputStrIn.replace('```mermaid', '').replace(`^@mermaids`, '').replace('```', ''); + // method to convert the drawings on collection node side the mermaid code - async convertDrawingToMermaidCode() { - let mermaidCode = ''; - let diagramExists = false; - if (this.Document.data instanceof List) { - const docArray: Doc[] = DocListCast(this.Document.data); - const rectangleArray = docArray.filter(doc => doc.title === 'rectangle' || doc.title === 'circle'); - const lineArray = docArray.filter(doc => doc.title === 'line' || doc.title === 'stroke'); - const textArray = docArray.filter(doc => doc.type === 'rich text'); - const timeoutPromise = () => - new Promise(resolve => { - setTimeout(resolve, 0); - }); - await timeoutPromise(); - const inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); - console.log(inkStrokeArray.length); - console.log(lineArray.length); - if (inkStrokeArray[0] && inkStrokeArray.length === lineArray.length) { - mermaidCode = 'graph TD;'; - const inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView); - for (let i = 0; i < rectangleArray.length; i++) { - const rectangle = rectangleArray[i]; - for (let j = 0; j < lineArray.length; j++) { - const inkScaleX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX; - const inkScaleY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY; - const inkStrokeXArray = (inkingStrokeArray[j] as InkingStroke) - ?.inkScaledData() - .inkData.map(coord => coord.X) - .map(doc => doc * inkScaleX); - const inkStrokeYArray = (inkingStrokeArray[j] as InkingStroke) - ?.inkScaledData() - .inkData.map(coord => coord.Y) - .map(doc => doc * inkScaleY); - console.log(inkingStrokeArray.length); - console.log(lineArray.length); - // need to minX and minY to since the inkStroke.x and.y is not relative to the doc. so I have to do some calcluations - const minX: number = Math.min(...inkStrokeXArray); - const minY: number = Math.min(...inkStrokeYArray); - const startX = inkStrokeXArray[0] - minX + (lineArray[j]?.x as number); - const startY = inkStrokeYArray[0] - minY + (lineArray[j]?.y as number); - const endX = inkStrokeXArray[inkStrokeXArray.length - 1] - minX + (lineArray[j].x as number); - const endY = inkStrokeYArray[inkStrokeYArray.length - 1] - minY + (lineArray[j].y as number); - if (this.isPointInBox(rectangle, [startX, startY])) { - for (let k = 0; k < rectangleArray.length; k++) { - const rectangle2 = rectangleArray[k]; - if (this.isPointInBox(rectangle2, [endX, endY]) && typeof rectangle.x === 'number' && typeof rectangle2.x === 'number') { - diagramExists = true; - const linkedDocs: Doc[] = LinkManager.Instance.getAllRelatedLinks(lineArray[j]).map(d => DocCast(LinkManager.getOppositeAnchor(d, lineArray[j]))); - console.log(linkedDocs.length); - if (linkedDocs.length !== 0) { - const linkedText = (linkedDocs[0].text as RichTextField).Text; - mermaidCode += Math.abs(rectangle.x) + this.getTextInBox(rectangle, textArray) + '-->|' + linkedText + '|' + Math.abs(rectangle2.x) + this.getTextInBox(rectangle2, textArray) + ';'; - } else { - mermaidCode += Math.abs(rectangle.x) + this.getTextInBox(rectangle, textArray) + '-->' + Math.abs(rectangle2.x) + this.getTextInBox(rectangle2, textArray) + ';'; - } - } + convertDrawingToMermaidCode = async (docArray: Doc[]) => { + const rectangleArray = docArray.filter(doc => doc.title === Gestures.Rectangle || doc.title === Gestures.Circle); + const lineArray = docArray.filter(doc => doc.title === Gestures.Line || doc.title === Gestures.Stroke); + const textArray = docArray.filter(doc => doc.type === DocumentType.RTF); + await new Promise(resolve => setTimeout(resolve)); + const inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); + if (inkStrokeArray[0] && inkStrokeArray.length === lineArray.length) { + let mermaidCode = `graph TD \n`; + const inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView as InkingStroke).filter(stroke => stroke); + for (const rectangle of rectangleArray) { + for (const inkStroke of inkingStrokeArray) { + const inkData = inkStroke.inkScaledData(); + const { inkScaleX, inkScaleY } = inkData; + const inkStrokeXArray = inkData.inkData.map(coord => coord.X * inkScaleX); + const inkStrokeYArray = inkData.inkData.map(coord => coord.Y * inkScaleY); + // need to minX and minY to since the inkStroke.x and.y is not relative to the doc. so I have to do some calcluations + const offX = Math.min(...inkStrokeXArray) - NumCast(inkStroke.Document.x); + const offY = Math.min(...inkStrokeYArray) - NumCast(inkStroke.Document.y); + + const startX = inkStrokeXArray[0] - offX; + const startY = inkStrokeYArray[0] - offY; + const endX = inkStrokeXArray.lastElement() - offX; + const endY = inkStrokeYArray.lastElement() - offY; + if (DiagramBox.isPointInBox(rectangle, [startX, startY])) { + for (const rectangle2 of rectangleArray) { + if (DiagramBox.isPointInBox(rectangle2, [endX, endY])) { + const linkedDocs = LinkManager.Instance.getAllRelatedLinks(inkStroke.Document).map(d => DocCast(LinkManager.getOppositeAnchor(d, inkStroke.Document))); + const linkedDocText = Cast(linkedDocs[0]?.text, RichTextField, null)?.Text; + const linkText = linkedDocText ? `|${linkedDocText}|` : ''; + mermaidCode += ' ' + Math.abs(NumCast(rectangle.x)) + this.getTextInBox(rectangle, textArray) + '-->' + linkText + Math.abs(NumCast(rectangle2.x)) + this.getTextInBox(rectangle2, textArray) + `\n`; } } } } - // this will save the text - DocumentManager.Instance.AddViewRenderedCb(this.Document, docViewForYourCollection => { - if (docViewForYourCollection && docViewForYourCollection.ComponentView) { - if (docViewForYourCollection.ComponentView.addDocument && docViewForYourCollection.ComponentView.removeDocument) { - let docs: Doc[] = DocListCast(this.Document.data); - docs = docs.filter(doc => doc.type === 'rich text'); - const mermaidCodeDoc = docs.filter(doc => (doc.text as RichTextField).Text === 'mermaidCodeTitle'); - if (mermaidCodeDoc[0]) { - if (diagramExists) { - mermaidCodeDoc[0].title = mermaidCode; - } else { - mermaidCodeDoc[0].title = ''; - } - } - } - } - }); + this.setMermaidCode(mermaidCode); } } - } - testInkingStroke = () => { - if (this.Document.data instanceof List) { - const docArray: Doc[] = DocListCast(this.Document.data); - const lineArray = docArray.filter(doc => doc.title === 'line' || doc.title === 'stroke'); - setTimeout(() => { - const inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); - console.log(inkStrokeArray); - }); - } }; - getTextInBox = (box: Doc, richTextArray: Doc[]): string => { - for (let i = 0; i < richTextArray.length; i++) { - const textDoc = richTextArray[i]; - if (typeof textDoc.x === 'number' && typeof textDoc.y === 'number' && typeof box.x === 'number' && typeof box.height === 'number' && typeof box.width === 'number' && typeof box.y === 'number') { - if (textDoc.x > box.x && textDoc.x < box.x + box.width && textDoc.y > box.y && textDoc.y < box.y + box.height) { - if (box.title === 'rectangle') { - return '(' + ((textDoc.text as RichTextField)?.Text ?? '') + ')'; - } - if (box.title === 'circle') { - return '((' + ((textDoc.text as RichTextField)?.Text ?? '') + '))'; - } - } + + getTextInBox = (box: Doc, richTextArray: Doc[]) => { + for (const textDoc of richTextArray) { + if (DiagramBox.isPointInBox(box, [NumCast(textDoc.x), NumCast(textDoc.y)])) { + switch (box.title) { + case Gestures.Rectangle: return '(' + ((textDoc.text as RichTextField)?.Text ?? '') + ')'; + case Gestures.Circle: return '((' + ((textDoc.text as RichTextField)?.Text ?? '') + '))'; + default: + } // prettier-ignore } } return '( )'; }; - isPointInBox = (box: Doc, line: number[]): boolean => { - if (typeof line[0] === 'number' && typeof box.x === 'number' && typeof box.width === 'number' && typeof box.height === 'number' && typeof box.y === 'number' && typeof line[1] === 'number') { - return line[0] < box.x + box.width && line[0] > box.x && line[1] > box.y && line[1] < box.y + box.height; - } - return false; - }; render() { return ( -
-
-
- - -
-
- {this.mermaidCode ? ( -
- ) : ( -
{this.loading ?
:
{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}
}
- )} -
+
+
+ e.key === 'Enter' && this.generateMermaidCode())} onChange={action(e => (this._inputValue = e.target.value))} /> + + (this._showCode = !this._showCode))} /> +
+
+ {this._showCode ? ( + + ) : this._generating ? ( +
+ ) : ( +
r && this.renderMermaidAsync.call(this, this.removeWords(this.mermaidcode), r)}> + {this._errorMessage || 'Type a prompt to generate a diagram'} +
+ )}
); @@ -286,6 +200,14 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() { } Docs.Prototypes.TemplateMap.set(DocumentType.DIAGRAM, { - layout: { view: DiagramBox, dataField: 'dadta' }, - options: { _height: 300, _layout_fitWidth: true, _layout_nativeDimEditable: true, _layout_reflowVertical: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' }, + layout: { view: DiagramBox, dataField: 'data' }, + options: { + _height: 300, // + _layout_fitWidth: true, + _layout_nativeDimEditable: true, + _layout_reflowVertical: true, + _layout_reflowHorizontal: true, + waitForDoubleClickToClick: 'always', + systemIcon: 'BsGlobe', + }, }); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index e21902fdd..a88bd8920 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1464,7 +1464,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - this._editorView?.dispatch(tx.deleteSelection().addStoredMark(mark)); + this._editorView?.dispatch(tx.addStoredMark(mark)); }); this.tryUpdateDoc(true); // calling select() above will make isContentActive() true only after a render .. which means the selectAll() above won't write to the Document and the incomingValue will overwrite the selection with the non-updated data } else { @@ -2090,6 +2090,7 @@ Docs.Prototypes.TemplateMap.set(DocumentType.RTF, { _layout_nativeDimEditable: true, _layout_reflowVertical: true, _layout_reflowHorizontal: true, + _layout_noSidebar: true, defaultDoubleClick: 'ignore', systemIcon: 'BsFileEarmarkTextFill', }, -- cgit v1.2.3-70-g09d2 From cdb21e036ff65d63991a53798133407be1d5755f Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Aug 2024 21:30:32 -0400 Subject: fixed error handling of images too big to load. cleaned up facecollectionbox. changed metadata field naming to match conventions. --- src/client/Network.ts | 11 +-- src/client/documents/DocUtils.ts | 2 +- .../collectionFreeForm/FaceCollectionBox.tsx | 88 ++++++++------------ .../collections/collectionFreeForm/MarqueeView.tsx | 97 +++------------------- src/client/views/nodes/FaceRectangles.tsx | 3 +- src/client/views/search/FaceRecognitionHandler.tsx | 64 +++++++------- 6 files changed, 87 insertions(+), 178 deletions(-) diff --git a/src/client/Network.ts b/src/client/Network.ts index 8876d8190..17f8a6534 100644 --- a/src/client/Network.ts +++ b/src/client/Network.ts @@ -1,3 +1,4 @@ +import formidable from 'formidable'; import * as requestPromise from 'request-promise'; import { ClientUtils } from '../ClientUtils'; import { Utils } from '../Utils'; @@ -49,15 +50,9 @@ export namespace Networking { if (!fileguidpairs.length) { return []; } - const maxFileSize = 5000000; + const maxFileSize = 6000000; if (fileguidpairs.some(f => f.file.size > maxFileSize)) { - return new Promise[]>(res => { - res([{ - source: { size: 0, filepath: '', mimetype: '', originalFilename: '', newFilename: '',hashAlgorithm: false, - toJSON: () => ({ size: 0, filepath: '', mimetype: '', originalFilename: '', newFilename: '',name: '', length: 0, mtime: new Date(), type: '' }) }, - result: { name: '', message: `max file size (${maxFileSize / 1000000}MB) exceeded` } - }]) // prettier-ignore - }); + return new Promise[]>(res => res([{ source: { newFilename: '', mimetype: '' } as formidable.File, result: new Error(`max file size (${maxFileSize / 1000000}MB) exceeded`) }])); } formData.set('fileguids', fileguidpairs.map(pair => pair.guid).join(';')); formData.set('filesize', fileguidpairs.reduce((sum, pair) => sum + pair.file.size, 0).toString()); diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index a503d732b..35d835f1f 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -739,7 +739,7 @@ export namespace DocUtils { const { source: { newFilename, mimetype }, result, - } = upfiles.lastElement() ?? { source: { newFilename: '', mimetype: '' }, result: { message: 'upload failed' } }; + } = upfiles.lastElement() ?? { source: { newFilename: '', mimetype: '' }, result: new Error('upload failed') }; if (result instanceof Error) { if (overwriteDoc) { overwriteDoc.loadingError = result.message; diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 50b91e8fe..d5a2809dc 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -11,17 +11,20 @@ import { Doc, DocListCast } from '../../../../fields/Doc'; import { DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; -import { ImageCast, StrCast } from '../../../../fields/Types'; +import { listSpec } from '../../../../fields/Schema'; +import { Cast, ImageCast, StrCast } from '../../../../fields/Types'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; import { SnappingManager } from '../../../util/SnappingManager'; +import { undoable } from '../../../util/UndoManager'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocumentView } from '../../nodes/DocumentView'; import { FieldView, FieldViewProps } from '../../nodes/FieldView'; import './FaceCollectionBox.scss'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; +import { FaceRecognitionHandler } from '../../search/FaceRecognitionHandler'; interface FaceDocumentProps { faceDoc: Doc; @@ -32,17 +35,15 @@ interface FaceDocumentProps { */ @observer export class FaceDocumentItem extends ObservableReactComponent { - private ref: React.RefObject; - @observable _displayImages: boolean = true; private _dropDisposer?: DragManager.DragDropDisposer; - private _inputRef = React.createRef(); constructor(props: FaceDocumentProps) { super(props); makeObservable(this); - this.ref = React.createRef(); } + @observable _displayImages: boolean = true; + protected createDropTarget = (ele: HTMLDivElement) => { this._dropDisposer?.(); ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this._props.faceDoc)); @@ -54,20 +55,20 @@ export class FaceDocumentItem extends ObservableReactComponent doc.type === DocumentType.IMG); filteredDocs.forEach(doc => { // If the current Face Document has no items, and the doc has more than one face descriptor, don't let the user add the document first. - if ((this._props.faceDoc[DocData].faceDescriptors as List>).length === 0 && (doc[DocData].faces as List>).length > 1) { + if ((this._props.faceDoc[DocData].face_descriptors as List>).length === 0 && (doc[DocData][FaceRecognitionHandler.FacesField(doc)] as List>).length > 1) { alert('Cannot add a document with multiple faces as the first item!'); } else { // Loop through the documents' face descriptors. // Choose the face with the smallest distance to add. - const float32Array = (this._props.faceDoc[DocData].faceDescriptors as List>).map(faceDescriptor => new Float32Array(Array.from(faceDescriptor))); - const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(StrCast(this._props.faceDoc[DocData].label), float32Array); + const float32Array = (this._props.faceDoc[DocData].face_descriptors as List>).map(faceDescriptor => new Float32Array(Array.from(faceDescriptor))); + const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(StrCast(this._props.faceDoc[DocData].face_label), float32Array); const faceDescriptors: faceapi.LabeledFaceDescriptors[] = [labeledFaceDescriptor]; const faceMatcher = new FaceMatcher(faceDescriptors, 1); let cur_lowest_distance = 1; let cur_matching_face = new List(); - (doc[DocData].faces as List>).forEach(face => { + (doc[DocData][FaceRecognitionHandler.FacesField(doc)] as List>).forEach(face => { // If the face has the current lowest distance, mark it as such // Once that lowest distance is found, add the face descriptor to the faceDoc, and add the associated doc const convered_32_array: Float32Array = new Float32Array(Array.from(face)); @@ -79,16 +80,15 @@ export class FaceDocumentItem extends ObservableReactComponent>([...(doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`] as List>), cur_matching_face]); + const faceFieldKey = FaceRecognitionHandler.FaceField(doc, this._props.faceDoc); + if (doc[DocData][faceFieldKey]) { + Cast(doc[DocData][faceFieldKey], listSpec('number'), null).push(cur_matching_face as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that } else { - doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`] = new List>([cur_matching_face]); + doc[DocData][faceFieldKey] = new List>([cur_matching_face]); } - this._props.faceDoc[DocData].associatedDocs = new List([...DocListCast(this._props.faceDoc[DocData].associatedDocs), doc]); - this._props.faceDoc[DocData].faceDescriptors = new List>([...(this._props.faceDoc[DocData].faceDescriptors as List>), cur_matching_face]); - - //const match = faceMatcher.findBestMatch(cur_descriptor); + Doc.AddDocToList(this._props.faceDoc[DocData], 'face_docList', doc); + Cast(this._props.faceDoc[DocData].face_descriptors, listSpec('number'), null).push(cur_matching_face as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that } }); return false; @@ -107,12 +107,11 @@ export class FaceDocumentItem extends ObservableReactComponent { + deleteFaceDocument = undoable(() => { if (Doc.ActiveDashboard) { - Doc.ActiveDashboard[DocData].faceDocuments = new List(DocListCast(Doc.ActiveDashboard[DocData].faceDocuments).filter(doc => doc !== this._props.faceDoc)); + Doc.RemoveDocFromList(Doc.ActiveDashboard[DocData], 'faceDocuments', this._props.faceDoc); } - }; + }, 'remove face'); /** * Deletes a document from a Face Document's associated docs list. @@ -120,60 +119,44 @@ export class FaceDocumentItem extends ObservableReactComponent { - this._props.faceDoc[DocData].faceDescriptors = new List>( - (this._props.faceDoc[DocData].faceDescriptors as List>).filter(fd => !(doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`] as List>).includes(fd)) + this._props.faceDoc[DocData].face_descriptors = new List>( + (this._props.faceDoc[DocData].face_descriptors as List>).filter(fd => !(doc[DocData][FaceRecognitionHandler.FaceField(doc, this._props.faceDoc)] as List>).includes(fd)) ); - doc[DocData][`FACE DESCRIPTOR - ${this._props.faceDoc[DocData].label}`] = new List>(); - this._props.faceDoc[DocData].associatedDocs = new List(DocListCast(this._props.faceDoc[DocData].associatedDocs).filter(associatedDoc => associatedDoc !== doc)); + doc[DocData][FaceRecognitionHandler.FaceField(doc, this._props.faceDoc)] = new List>(); + Doc.RemoveDocFromList(this._props.faceDoc[DocData], 'face_docList', doc); }; render() { return (
this.createDropTarget(ele!)}>
- +
-

{StrCast(this._props.faceDoc[DocData].label)}

+

{StrCast(this._props.faceDoc[DocData].face_label)}

this.onDisplayClick()} - icon={this._displayImages ? : } + icon={} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} /> {this._displayImages ? (
- {DocListCast(this._props.faceDoc[DocData].associatedDocs).map(doc => { + {DocListCast(this._props.faceDoc[DocData].face_docList).map(doc => { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return (
- { - await DocumentView.showDocument(doc, { willZoomCentered: true }); - }} - style={{ maxWidth: '60px', margin: '10px' }} - src={`${name}_o.${type}`} - /> + DocumentView.showDocument(doc, { willZoomCentered: true })} style={{ maxWidth: '60px', margin: '10px' }} src={`${name}_o.${type}`} />
- { - this.deleteAssociatedDoc(doc); - }} - icon={'x'} - style={{ width: '4px' }} - size={Size.XSMALL} - /> + this.deleteAssociatedDoc(doc)} icon={'x'} style={{ width: '4px' }} size={Size.XSMALL} />
); })}
- ) : ( -
- )} + ) : null}
); } @@ -190,9 +173,8 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { @computed get currentDocs() { if (Doc.ActiveDashboard) { return DocListCast(Doc.ActiveDashboard[DocData].faceDocuments); - } else { - return []; } + return []; } constructor(props: FieldViewProps) { @@ -204,9 +186,9 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { render() { return (
- {this.currentDocs.map(doc => { - return ; - })} + {this.currentDocs.map(doc => ( + + ))}
); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index d7a41df64..6fee076ee 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -1,28 +1,24 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -import similarity from 'compute-cosine-similarity'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { ClientUtils, lightOrDark, returnFalse } from '../../../../ClientUtils'; -import { intersectRect, numberRange } from '../../../../Utils'; -import { Doc, DocListCast, NumListCast, Opt } from '../../../../fields/Doc'; +import { intersectRect } from '../../../../Utils'; +import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; -import { InkData, InkField, InkTool } from '../../../../fields/InkField'; +import { InkTool } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; -import { RichTextField } from '../../../../fields/RichTextField'; -import { Cast, FieldValue, ImageCast, NumCast, StrCast } from '../../../../fields/Types'; +import { Cast, NumCast, StrCast } from '../../../../fields/Types'; import { ImageField } from '../../../../fields/URLField'; import { GetEffectiveAcl } from '../../../../fields/util'; -import { gptGetEmbedding, gptImageLabel } from '../../../apis/gpt/GPT'; -import { CognitiveServices } from '../../../cognitive_services/CognitiveServices'; import { DocUtils } from '../../../documents/DocUtils'; -import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; +import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs, DocumentOptions } from '../../../documents/Documents'; import { SnappingManager, freeformScrollMode } from '../../../util/SnappingManager'; import { Transform } from '../../../util/Transform'; import { UndoManager, undoBatch } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; +import { MainView } from '../../MainView'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { MarqueeViewBounds } from '../../PinFuncs'; import { PreviewCursor } from '../../PreviewCursor'; @@ -30,15 +26,10 @@ import { DocumentView } from '../../nodes/DocumentView'; import { OpenWhere } from '../../nodes/OpenWhere'; import { pasteImageBitmap } from '../../nodes/WebBoxRenderer'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; -import { CollectionCardView } from '../CollectionCardDeckView'; import { SubCollectionViewProps } from '../CollectionSubView'; -import { CollectionFreeFormView } from './CollectionFreeFormView'; -import { ImageLabelHandler } from './ImageLabelHandler'; +import { ImageLabelBoxData } from './ImageLabelBox'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './MarqueeView.scss'; -import { MainView } from '../../MainView'; -import { ImageLabelBox, ImageLabelBoxData } from './ImageLabelBox'; -import { SearchBox } from '../../search/SearchBox'; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -68,7 +59,7 @@ export class MarqueeView extends ObservableReactComponent { - const selected = this.marqueeSelect(false); - if (e instanceof KeyboardEvent ? e.key === 'i' : true) { - const inks = selected.filter(s => s.type === DocumentType.INK); - const setDocs = selected.filter(s => s.type === DocumentType.RTF && s.color); - const sets = setDocs.map(sd => Cast(sd.data, RichTextField)?.Text as string); - const colors = setDocs.map(sd => FieldValue(sd.color) as string); - const wordToColor = new Map(); - sets.forEach((st: string, i: number) => st.split(',').forEach(word => wordToColor.set(word, colors[i]))); - const strokes: InkData[] = []; - inks.filter(i => Cast(i.data, InkField)).forEach(i => { - const d = Cast(i.data, InkField, null); - const left = Math.min(...(d?.inkData.map(pd => pd.X) ?? [0])); - const top = Math.min(...(d?.inkData.map(pd => pd.Y) ?? [0])); - strokes.push(d.inkData.map(pd => ({ X: pd.X + NumCast(i.x) - left, Y: pd.Y + NumCast(i.y) - top }))); - }); - CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then(results => { - // const wordResults = results.filter((r: any) => r.category === "inkWord"); - // for (const word of wordResults) { - // const indices: number[] = word.strokeIds; - // indices.forEach(i => { - // if (wordToColor.has(word.recognizedText.toLowerCase())) { - // inks[i].color = wordToColor.get(word.recognizedText.toLowerCase()); - // } - // else { - // for (const alt of word.alternates) { - // if (wordToColor.has(alt.recognizedString.toLowerCase())) { - // inks[i].color = wordToColor.get(alt.recognizedString.toLowerCase()); - // break; - // } - // } - // } - // }) - // } - // const wordResults = results.filter((r: any) => r.category === "inkWord"); - // for (const word of wordResults) { - // const indices: number[] = word.strokeIds; - // indices.forEach(i => { - // const otherInks: Doc[] = []; - // indices.forEach(i2 => i2 !== i && otherInks.push(inks[i2])); - // inks[i].relatedInks = new List(otherInks); - // const uniqueColors: string[] = []; - // Array.from(wordToColor.values()).forEach(c => uniqueColors.indexOf(c) === -1 && uniqueColors.push(c)); - // inks[i].alternativeColors = new List(uniqueColors); - // if (wordToColor.has(word.recognizedText.toLowerCase())) { - // inks[i].color = wordToColor.get(word.recognizedText.toLowerCase()); - // } - // else if (word.alternates) { - // for (const alt of word.alternates) { - // if (wordToColor.has(alt.recognizedString.toLowerCase())) { - // inks[i].color = wordToColor.get(alt.recognizedString.toLowerCase()); - // break; - // } - // } - // } - // }); - // } - const lines = results.filter((r: any) => r.category === 'line'); - const text = lines.map((l: any) => l.recognizedText).join('\r\n'); - this._props.addDocument?.(Docs.Create.TextDocument(text, { _width: this.Bounds.width, _height: this.Bounds.height, x: this.Bounds.left + this.Bounds.width, y: this.Bounds.top, title: text })); - }); - } - }); - @undoBatch summary = action(() => { const selected = this.marqueeSelect(false).map(d => { @@ -704,8 +630,8 @@ export class MarqueeView extends ObservableReactComponent {' '} @@ -714,7 +640,7 @@ export class MarqueeView extends ObservableReactComponent s + pt[0] + ',' + pt[1] + ' ', '')} fill="none" - stroke={lightOrDark(this._props.Document?.backgroundColor ?? 'white')} + stroke={lightOrDark((this._props.Document?.backgroundColor as string) ?? 'white')} strokeWidth="1" strokeDasharray="3" /> @@ -753,7 +679,6 @@ export class MarqueeView extends ObservableReactComponent { diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx index ade4225d9..19aa90a8b 100644 --- a/src/client/views/nodes/FaceRectangles.tsx +++ b/src/client/views/nodes/FaceRectangles.tsx @@ -4,6 +4,7 @@ import { Doc, DocListCast } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; import { Cast, NumCast } from '../../../fields/Types'; import FaceRectangle from './FaceRectangle'; +import { FaceRecognitionHandler } from '../search/FaceRecognitionHandler'; interface FaceRectanglesProps { document: Doc; @@ -19,7 +20,7 @@ export interface RectangleTemplate { @observer export class FaceRectangles extends React.Component { render() { - const faces = DocListCast(this.props.document.faces); + const faces = DocListCast(this.props.document[FaceRecognitionHandler.FacesField(this.props.document)]); const templates: RectangleTemplate[] = faces.map(faceDoc => { const rectangle = Cast(faceDoc.faceRectangle, Doc) as Doc; const style = { diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 29ca6e797..dc271fe73 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -1,42 +1,46 @@ import * as faceapi from 'face-api.js'; import { FaceMatcher } from 'face-api.js'; +import { computed } from 'mobx'; import { Doc, DocListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; +import { listSpec } from '../../../fields/Schema'; import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; -import { DocumentManager } from '../../util/DocumentManager'; -import { computed } from 'mobx'; import { DocumentType } from '../../documents/DocumentTypes'; -import { listSpec } from '../../../fields/Schema'; +import { DocumentManager } from '../../util/DocumentManager'; /** * A class that handles face recognition. */ export class FaceRecognitionHandler { static _instance: FaceRecognitionHandler; - private loadedModels: boolean = false; - @computed get examinedFaceDocs() { - return DocListCast(Doc.UserDoc().examinedFaceDocs); - } - processingDocs: Set = new Set(); - pendingLoadDocs: Doc[] = []; + private _loadedModels: boolean = false; + private _processingDocs: Set = new Set(); + private _pendingLoadDocs: Doc[] = []; + + public static FaceField = (target: Doc, doc: Doc) => `${Doc.LayoutFieldKey(target)}_${doc.face_label}`; + public static FacesField = (target: Doc) => `${Doc.LayoutFieldKey(target)}_Faces`; constructor() { FaceRecognitionHandler._instance = this; - this.loadModels().then(() => this.pendingLoadDocs.forEach(this.findMatches)); + this.loadModels().then(() => this._pendingLoadDocs.forEach(this.findMatches)); DocumentManager.Instance.AddAnyViewRenderedCB(dv => FaceRecognitionHandler.Instance.findMatches(dv.Document)); } + @computed get examinedFaceDocs() { + return DocListCast(Doc.UserDoc().examinedFaceDocs); + } + /** * Loads the face detection models. */ - async loadModels() { + loadModels = async () => { const MODEL_URL = `/models`; await faceapi.loadFaceDetectionModel(MODEL_URL); await faceapi.loadFaceLandmarkModel(MODEL_URL); await faceapi.loadFaceRecognitionModel(MODEL_URL); - this.loadedModels = true; - } + this._loadedModels = true; + }; public static get Instance() { return FaceRecognitionHandler._instance ?? new FaceRecognitionHandler(); @@ -47,8 +51,8 @@ export class FaceRecognitionHandler { * @param doc The document being analyzed. */ public findMatches = async (doc: Doc) => { - if (!this.loadedModels || !Doc.ActiveDashboard) { - this.pendingLoadDocs.push(doc); + if (!this._loadedModels || !Doc.ActiveDashboard) { + this._pendingLoadDocs.push(doc); return; } @@ -59,12 +63,12 @@ export class FaceRecognitionHandler { const imgUrl = ImageCast(doc[Doc.LayoutFieldKey(doc)]); // If the doc isn't an image or currently already been examined or is being processed, stop examining the document. - if (!imgUrl || this.examinedFaceDocs.includes(doc) || this.processingDocs.has(doc)) { + if (!imgUrl || this.examinedFaceDocs.includes(doc) || this._processingDocs.has(doc)) { return; } // Mark the document as being processed. - this.processingDocs.add(doc); + this._processingDocs.add(doc); // Get the image the document contains and analyze for faces. const [name, type] = imgUrl.url.href.split('.'); @@ -74,7 +78,7 @@ export class FaceRecognitionHandler { const fullFaceDescriptions = await faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors(); - doc[DocData].faces = new List>(); + doc[DocData][FaceRecognitionHandler.FacesField(doc)] = new List>(); // For each face detected, find a match. for (const fd of fullFaceDescriptions) { @@ -84,34 +88,36 @@ export class FaceRecognitionHandler { if (match) { // If a matching Face Document has been found, add the document to the Face Document's associated docs and append the face // descriptor to the Face Document's descriptor list. - Doc.AddDocToList(match, 'associatedDocs', doc); - Cast(match.faceDescriptors, listSpec('number'), null).push(converted_list as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that + Doc.AddDocToList(match, 'face_docList', doc); + Cast(match.face_descriptors, listSpec('number'), null).push(converted_list as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that } else { // If a matching Face Document has not been found, create a new Face Document. Doc.UserDoc().faceDocNum = NumCast(Doc.UserDoc().faceDocNum) + 1; const newFaceDocument = new Doc(); - newFaceDocument.label = `Face ${Doc.UserDoc().faceDocNum}`; - newFaceDocument.associatedDocs = new List([doc]); - newFaceDocument.faceDescriptors = new List>([converted_list]); + newFaceDocument.title = `Face ${Doc.UserDoc().faceDocNum}`; + newFaceDocument.face = ''; // just to make prettyprinting look better + newFaceDocument.face_label = `Face${Doc.UserDoc().faceDocNum}`; + newFaceDocument.face_docList = new List([doc]); + newFaceDocument.face_descriptors = new List>([converted_list]); Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'faceDocuments', newFaceDocument); match = newFaceDocument; } // Assign a field in the document of the matching Face Document. - const faceDescripField = `FACE DESCRIPTOR - ${match[DocData].label}`; + const faceDescripField = FaceRecognitionHandler.FaceField(doc, match); if (doc[DocData][faceDescripField]) { Cast(doc[DocData][faceDescripField], listSpec('number'), null).push(converted_list as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that } else { doc[DocData][faceDescripField] = new List>([converted_list]); } - Cast(doc[DocData].faces, listSpec('number'), null).push(converted_list as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that + Cast(doc[DocData][FaceRecognitionHandler.FacesField(doc)], listSpec('number'), null).push(converted_list as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that Doc.AddDocToList(Doc.UserDoc(), 'examinedFaceDocs', doc); } - this.processingDocs.delete(doc); + this._processingDocs.delete(doc); }; /** @@ -125,14 +131,14 @@ export class FaceRecognitionHandler { } const faceDescriptors: faceapi.LabeledFaceDescriptors[] = DocListCast(Doc.ActiveDashboard[DocData].faceDocuments).map(faceDocument => { - const float32Array = (faceDocument[DocData].faceDescriptors as List>).map(faceDescriptor => new Float32Array(Array.from(faceDescriptor))); - return new faceapi.LabeledFaceDescriptors(StrCast(faceDocument[DocData].label), float32Array); + const float32Array = (faceDocument[DocData].face_descriptors as List>).map(faceDescriptor => new Float32Array(Array.from(faceDescriptor))); + return new faceapi.LabeledFaceDescriptors(StrCast(faceDocument[DocData].face_label), float32Array); }); const faceMatcher = new FaceMatcher(faceDescriptors, 0.6); const match = faceMatcher.findBestMatch(cur_descriptor); if (match.label !== 'unknown') { for (const doc of DocListCast(Doc.ActiveDashboard[DocData].faceDocuments)) { - if (doc[DocData].label === match.label) { + if (doc[DocData].face_label === match.label) { return doc; } } -- cgit v1.2.3-70-g09d2 From 69e9940f4fa24fd1ab1d9715f60b27d9e1f1221a Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Aug 2024 21:34:58 -0400 Subject: from last --- src/client/views/collections/CollectionView.tsx | 3 +-- src/client/views/nodes/ImageBox.tsx | 8 +------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 66c4896c0..ab93abab6 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -17,6 +17,7 @@ import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { FieldView } from '../nodes/FieldView'; import { OpenWhere } from '../nodes/OpenWhere'; import { CollectionCalendarView } from './CollectionCalendarView'; +import { CollectionCardView } from './CollectionCardDeckView'; import { CollectionCarousel3DView } from './CollectionCarousel3DView'; import { CollectionCarouselView } from './CollectionCarouselView'; import { CollectionDockingView } from './CollectionDockingView'; @@ -33,8 +34,6 @@ import { CollectionLinearView } from './collectionLinear'; import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { CollectionSchemaView } from './collectionSchema/CollectionSchemaView'; -import { CollectionCardView } from './CollectionCardDeckView'; -import { DocData } from '../../../fields/DocSymbols'; @observer export class CollectionView extends ViewBoxAnnotatableComponent() { diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 7d8a4ee49..d0a7fc6ac 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,6 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import zIndex from '@mui/material/styles/zIndex'; import { Colors } from 'browndash-components'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction } from 'mobx'; import { observer } from 'mobx-react'; @@ -11,7 +10,6 @@ import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; -import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; @@ -22,6 +20,7 @@ import { DocumentType } from '../../documents/DocumentTypes'; import { DocUtils } from '../../documents/DocUtils'; import { Networking } from '../../Network'; import { DragManager } from '../../util/DragManager'; +import { SnappingManager } from '../../util/SnappingManager'; import { undoBatch } from '../../util/UndoManager'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { ContextMenu } from '../ContextMenu'; @@ -37,7 +36,6 @@ import { FieldView, FieldViewProps } from './FieldView'; import { FocusViewOptions } from './FocusViewOptions'; import './ImageBox.scss'; import { OpenWhere } from './OpenWhere'; -import { SnappingManager } from '../../util/SnappingManager'; export class ImageEditorData { // eslint-disable-next-line no-use-before-define @@ -176,10 +174,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(targetDoc), this.fieldKey); } } - const layoutDoc = de.complete.docDragData?.draggedDocuments[0]; - const targetField = Doc.LayoutFieldKey(layoutDoc); - const targetDoc = layoutDoc[DocData]; - console.log(targetDoc[targetField]); added === false && e.preventDefault(); added !== undefined && e.stopPropagation(); return added; -- cgit v1.2.3-70-g09d2 From d5ae46421b34d688817e059257578906ff2f12a9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Aug 2024 21:46:56 -0400 Subject: fixing lint errors --- .../collectionFreeForm/MarqueeOptionsMenu.tsx | 4 ++-- .../views/collections/collectionFreeForm/MarqueeView.tsx | 16 ++++++++++------ src/server/server_Initialization.ts | 9 +++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index b94a22d04..44c916ab9 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -18,10 +18,10 @@ export class MarqueeOptionsMenu extends AntimodeMenu { public showMarquee: () => void = unimplementedFunction; public hideMarquee: () => void = unimplementedFunction; public pinWithView: (e: KeyboardEvent | React.PointerEvent | undefined) => void = unimplementedFunction; - public classifyImages: (e: React.MouseEvent | undefined) => void = unimplementedFunction; + public classifyImages: () => void = unimplementedFunction; public groupImages: () => void = unimplementedFunction; public isShown = () => this._opacity > 0; - constructor(props: any) { + constructor(props: AntimodeMenuProps) { super(props); makeObservable(this); MarqueeOptionsMenu.Instance = this; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 6fee076ee..6cc75aa4b 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -156,6 +156,7 @@ export class MarqueeView extends ObservableReactComponent + // eslint-disable-next-line @typescript-eslint/no-explicit-any pasteImageBitmap((data: any, error: any) => { error && console.log(error); data && @@ -432,7 +433,7 @@ export class MarqueeView extends ObservableReactComponent { + classifyImages = action(async () => { const groupButton = DocListCast(Doc.MyLeftSidebarMenu.data).find(d => d.target === Doc.MyImageGrouper); if (groupButton) { this._selectedDocs = this.marqueeSelect(false, DocumentType.IMG); @@ -515,13 +516,14 @@ export class MarqueeView extends ObservableReactComponent { - if (this._commandExecuted || (e as any).propagationIsStopped) { + const ee = e as unknown as KeyboardEvent & { propagationIsStopped?: boolean }; + if (this._commandExecuted || ee.propagationIsStopped) { return; } if (e.key === 'Backspace' || e.key === 'Delete' || e.key === 'd' || e.key === 'h') { this._commandExecuted = true; e.stopPropagation(); - (e as any).propagationIsStopped = true; + ee.propagationIsStopped = true; this.delete(e, e.key === 'h'); e.stopPropagation(); } @@ -529,7 +531,7 @@ export class MarqueeView extends ObservableReactComponent) => { - if ((e as any).handlePan || this._props.isAnnotationOverlay) return; - (e as any).handlePan = true; + const ee = e as CustomEvent & { handlePan?: boolean }; + if (ee.handlePan || this._props.isAnnotationOverlay) return; + ee.handlePan = true; const bounds = this.MarqueeRef?.getBoundingClientRect(); if (!this._props.Document._freeform_noAutoPan && !this._props.renderDepth && bounds) { @@ -682,6 +685,7 @@ export class MarqueeView extends ObservableReactComponent { + // eslint-disable-next-line @typescript-eslint/no-explicit-any r?.addEventListener('dashDragMovePause', this.onDragMovePause as any); this.MarqueeRef = r; }} diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index 2190e27c7..8d3afc3ad 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -113,6 +113,7 @@ function registerEmbeddedBrowseRelativePathHandler(server: express.Express) { }); } +// eslint-disable-next-line @typescript-eslint/no-explicit-any function proxyServe(req: any, requrl: string, response: any) { // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires const htmlBodyMemoryStream = new (require('memorystream'))(); @@ -137,8 +138,10 @@ function proxyServe(req: any, requrl: string, response: any) { response.send(header?.includes('gzip') ? zlib.gzipSync(htmlText) : htmlText); } else { req.pipe(request(requrl)) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('requrl ', e)) .pipe(response) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('response pipe error', e)); console.log('EMPTY body:' + req.url); } @@ -147,14 +150,17 @@ function proxyServe(req: any, requrl: string, response: any) { } } else { req.pipe(htmlBodyMemoryStream) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('html body memorystream error', e)) .pipe(response) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('html body memory stream response error', e)); } }; const retrieveHTTPBody = () => { // req.headers.cookie = ''; req.pipe(request(requrl)) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => { console.log(`CORS url error: ${requrl}`, e); response.send(` @@ -163,6 +169,7 @@ function proxyServe(req: any, requrl: string, response: any) {

${e}

`); }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('response', (res: any) => { res.headers; const headers = Object.keys(res.headers); @@ -187,6 +194,7 @@ function proxyServe(req: any, requrl: string, response: any) { }) .on('end', sendModifiedBody) .pipe(htmlBodyMemoryStream) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('http body pipe error', e)); }; retrieveHTTPBody(); @@ -244,6 +252,7 @@ export default async function InitializeServer(routeSetter: RouteSetter) { app.use(whm(compiler)); app.get(/^\/+$/, (req, res) => res.redirect(req.user ? '/home' : '/login')); // target urls that consist of one or more '/'s with nothing in between app.use(express.static(publicDirectory, { setHeaders: res => res.setHeader('Access-Control-Allow-Origin', '*') })); // all urls that start with dash's public directory: /files/ (e.g., /files/images, /files/audio, etc) + // eslint-disable-next-line @typescript-eslint/no-explicit-any app.use(cors({ origin: (_origin: any, callback: any) => callback(null, true) })); registerAuthenticationRoutes(app); // this adds routes to authenticate a user (login, etc) registerCorsProxy(app); // this adds a /corsProxy/ route to allow clients to get to urls that would otherwise be blocked by cors policies -- cgit v1.2.3-70-g09d2 From 19a947cbd253ff7fb9da88c27af7645219446d0a Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Aug 2024 22:02:54 -0400 Subject: from last --- .eslintrc.json | 2 +- src/client/documents/DocUtils.ts | 2 +- src/client/views/nodes/FaceRectangle.tsx | 34 ---------------------- src/client/views/nodes/FaceRectangles.tsx | 47 ------------------------------- src/server/server_Initialization.ts | 2 +- 5 files changed, 3 insertions(+), 84 deletions(-) delete mode 100644 src/client/views/nodes/FaceRectangle.tsx delete mode 100644 src/client/views/nodes/FaceRectangles.tsx diff --git a/.eslintrc.json b/.eslintrc.json index 6202561d5..d4f43f04c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -40,6 +40,7 @@ "react/jsx-filename-extension": [2, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }], "import/prefer-default-export": "off", "no-unused-expressions": "off", + "@typescript-eslint/no-unused-expressions": "off", "prefer-template": "off", "no-inner-declarations": "off", "no-plusplus": "off", @@ -54,7 +55,6 @@ "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": "error", "@typescript-eslint/no-namespace": 0, - "@typescript-eslint/no-unused-expressions": "off", "react/destructuring-assignment": 0, "no-restricted-globals": ["error", "event"], "no-param-reassign": ["error", { "props": false }], diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index 35d835f1f..0168e0a3b 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -35,7 +35,7 @@ import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; import { DocumentType } from './DocumentTypes'; import { Docs, DocumentOptions } from './Documents'; -// eslint-disable-next-line @typescript-eslint/no-var-requires +// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports const { DFLT_IMAGE_NATIVE_DIM } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', '')); diff --git a/src/client/views/nodes/FaceRectangle.tsx b/src/client/views/nodes/FaceRectangle.tsx deleted file mode 100644 index 2b66b83fe..000000000 --- a/src/client/views/nodes/FaceRectangle.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { observable, runInAction } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { RectangleTemplate } from './FaceRectangles'; - -@observer -export default class FaceRectangle extends React.Component<{ rectangle: RectangleTemplate }> { - @observable private opacity = 0; - - componentDidMount() { - setTimeout( - () => - runInAction(() => { - this.opacity = 1; - }), - 500 - ); - } - - render() { - const { rectangle } = this.props; - return ( -
- ); - } -} diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx deleted file mode 100644 index 19aa90a8b..000000000 --- a/src/client/views/nodes/FaceRectangles.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { Doc, DocListCast } from '../../../fields/Doc'; -import { Id } from '../../../fields/FieldSymbols'; -import { Cast, NumCast } from '../../../fields/Types'; -import FaceRectangle from './FaceRectangle'; -import { FaceRecognitionHandler } from '../search/FaceRecognitionHandler'; - -interface FaceRectanglesProps { - document: Doc; - color: string; - backgroundColor: string; -} - -export interface RectangleTemplate { - id: string; - style: Partial; -} - -@observer -export class FaceRectangles extends React.Component { - render() { - const faces = DocListCast(this.props.document[FaceRecognitionHandler.FacesField(this.props.document)]); - const templates: RectangleTemplate[] = faces.map(faceDoc => { - const rectangle = Cast(faceDoc.faceRectangle, Doc) as Doc; - const style = { - top: NumCast(rectangle.top), - left: NumCast(rectangle.left), - width: NumCast(rectangle.width), - height: NumCast(rectangle.height), - backgroundColor: `${this.props.backgroundColor}33`, - border: `solid 2px ${this.props.color}`, - } as React.CSSProperties; - return { - id: rectangle[Id], - style: style, - }; - }); - return ( -
- {templates.map(rectangle => ( - - ))} -
- ); - } -} diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index 8d3afc3ad..97c63a93e 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -115,7 +115,7 @@ function registerEmbeddedBrowseRelativePathHandler(server: express.Express) { // eslint-disable-next-line @typescript-eslint/no-explicit-any function proxyServe(req: any, requrl: string, response: any) { - // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires + // eslint-disable-next-line global-require, @typescript-eslint/no-require-imports const htmlBodyMemoryStream = new (require('memorystream'))(); let wasinBrFormat = false; const sendModifiedBody = () => { -- cgit v1.2.3-70-g09d2 From 27c4292e709e6bbba449e940d61d54b157092296 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Aug 2024 22:23:12 -0400 Subject: updated packages --- package-lock.json | 1579 ++++++++++++++++++++++++++--------------------------- package.json | 13 +- 2 files changed, 794 insertions(+), 798 deletions(-) diff --git a/package-lock.json b/package-lock.json index c2a4aa964..41922228a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,9 +50,9 @@ "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/textfit": "^2.4.4", - "@types/web": "^0.0.151", + "@types/web": "^0.0.155", "@types/webpack-hot-middleware": "^2.25.9", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/parser": "^8.2.0", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", "archiver": "^7.0.1", @@ -116,7 +116,7 @@ "function-plot": "^1.23.3", "golden-layout": "^2.6.0", "google-auth-library": "^9.4.1", - "googleapis": "^140.0.1", + "googleapis": "^142.0.0", "googlephotos": "^0.3.5", "got": "^14.0.0", "howler": "^2.2.4", @@ -211,7 +211,7 @@ "reveal.js": "^5.0.2", "rimraf": "^6.0.0", "sass": "^1.69.5", - "sass-loader": "^14.2.0", + "sass-loader": "^16.0.1", "serializr": "^3.0.2", "shelljs": "^0.8.5", "socket.io": "^4.7.2", @@ -269,7 +269,7 @@ "@types/libxmljs": "^0.18.12", "@types/lodash": "^4.14.202", "@types/mocha": "^10.0.6", - "@types/node": "^20.10.3", + "@types/node": "^22.4.2", "@types/nodemailer": "^6.4.14", "@types/passport": "^1.0.16", "@types/passport-google-oauth20": "^2.0.14", @@ -278,7 +278,6 @@ "@types/react": "^18.2.41", "@types/react-autosuggest": "^10.1.10", "@types/react-color": "^3.0.10", - "@types/react-datepicker": "^6.2.0", "@types/react-dom": "^18.2.17", "@types/react-grid-layout": "^1.3.5", "@types/react-measure": "^2.0.12", @@ -315,7 +314,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", - "typescript-eslint": "^7.8.0", + "typescript-eslint": "^8.2.0", "webpack-dev-server": "^5.0.4" }, "engines": { @@ -323,49 +322,49 @@ } }, "node_modules/@adobe/react-spectrum": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.36.1.tgz", - "integrity": "sha512-ZDxbCjFBYU3S8iEbsrKoJS5fIf91lpM44nWyY1rKwqD7Lu6Lo0cNX8g44x5pXi+PcMr2KxZOPTj4khfCqMOCvg==", + "version": "3.36.3", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.36.3.tgz", + "integrity": "sha512-G1v560c1S4q14+Ub6LhPCLLUHxESjdcg05SeEGs3m4si6MQAv9TzL9zblmb8DnAtFSZYfNIIEc0X5kibSPtTBA==", "dependencies": { "@internationalized/string": "^3.2.3", - "@react-aria/i18n": "^3.12.1", + "@react-aria/i18n": "^3.12.2", "@react-aria/ssr": "^3.9.5", - "@react-aria/utils": "^3.25.1", - "@react-aria/visually-hidden": "^3.8.14", + "@react-aria/utils": "^3.25.2", + "@react-aria/visually-hidden": "^3.8.15", "@react-spectrum/actionbar": "^3.5.1", "@react-spectrum/actiongroup": "^3.10.7", - "@react-spectrum/avatar": "^3.0.14", + "@react-spectrum/avatar": "^3.0.15", "@react-spectrum/badge": "^3.1.15", "@react-spectrum/breadcrumbs": "^3.9.9", "@react-spectrum/button": "^3.16.6", "@react-spectrum/buttongroup": "^3.6.15", "@react-spectrum/calendar": "^3.4.11", "@react-spectrum/checkbox": "^3.9.8", - "@react-spectrum/combobox": "^3.13.1", + "@react-spectrum/combobox": "^3.13.2", "@react-spectrum/contextualhelp": "^3.6.13", "@react-spectrum/datepicker": "^3.10.1", "@react-spectrum/dialog": "^3.8.13", - "@react-spectrum/divider": "^3.5.15", + "@react-spectrum/divider": "^3.5.16", "@react-spectrum/dnd": "^3.4.1", "@react-spectrum/dropzone": "^3.0.3", "@react-spectrum/filetrigger": "^3.0.3", "@react-spectrum/form": "^3.7.8", "@react-spectrum/icon": "^3.7.15", "@react-spectrum/illustratedmessage": "^3.5.3", - "@react-spectrum/image": "^3.5.3", + "@react-spectrum/image": "^3.5.4", "@react-spectrum/inlinealert": "^3.2.7", "@react-spectrum/labeledvalue": "^3.1.16", - "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/layout": "^3.6.8", "@react-spectrum/link": "^3.6.9", "@react-spectrum/list": "^3.8.1", "@react-spectrum/listbox": "^3.13.1", - "@react-spectrum/menu": "^3.20.1", + "@react-spectrum/menu": "^3.20.3", "@react-spectrum/meter": "^3.5.3", "@react-spectrum/numberfield": "^3.9.5", "@react-spectrum/overlays": "^5.6.3", "@react-spectrum/picker": "^3.15.1", "@react-spectrum/progress": "^3.7.9", - "@react-spectrum/provider": "^3.9.9", + "@react-spectrum/provider": "^3.9.10", "@react-spectrum/radio": "^3.7.8", "@react-spectrum/searchfield": "^3.8.8", "@react-spectrum/slider": "^3.6.11", @@ -375,13 +374,13 @@ "@react-spectrum/tabs": "^3.8.12", "@react-spectrum/tag": "^3.2.8", "@react-spectrum/text": "^3.5.7", - "@react-spectrum/textfield": "^3.12.3", + "@react-spectrum/textfield": "^3.12.4", "@react-spectrum/theme-dark": "^3.5.12", "@react-spectrum/theme-default": "^3.5.12", "@react-spectrum/theme-light": "^3.4.12", "@react-spectrum/tooltip": "^3.6.9", "@react-spectrum/view": "^3.6.12", - "@react-spectrum/well": "^3.4.15", + "@react-spectrum/well": "^3.4.16", "@react-stately/collections": "^3.10.9", "@react-stately/data": "^3.11.6", "@react-types/shared": "^3.24.1", @@ -4132,15 +4131,15 @@ } }, "node_modules/@react-aria/actiongroup": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@react-aria/actiongroup/-/actiongroup-3.7.7.tgz", - "integrity": "sha512-qkbCnMYt32ZWN8X7ycup/kbdaQLENJ+uzy3gRI5VY06RwN+btdvT8seZl1xR0n7qfdDCZxmd5WaKbXA0gl3bBA==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/list": "^3.10.7", + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/@react-aria/actiongroup/-/actiongroup-3.7.8.tgz", + "integrity": "sha512-0Hz6Ec6HugO3WOTzs1wODPb1Bf//a9ad6w6uriTE8QRKveFueypsjDbex5dBOhCtdzgrpflhpy812s9FoCUZ/Q==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", + "@react-stately/list": "^3.10.8", "@react-types/actiongroup": "^3.4.11", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4151,13 +4150,13 @@ } }, "node_modules/@react-aria/breadcrumbs": { - "version": "3.5.15", - "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.15.tgz", - "integrity": "sha512-KJ7678hwKbacz6dyY4aOJlgtV91PtuSnlWGR+AsK88WwHhpjjTjLLTSRepjbQ35GuQuoYokM4mmfaS/I0nblhw==", + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.16.tgz", + "integrity": "sha512-OXLKKu4SmjnSaSHkk4kow5/aH/SzlHWPJt+Uq3xec9TwDOr/Ob8aeFVGFoY0HxfGozuQlUz+4e+d29vfA0jNWg==", "dependencies": { - "@react-aria/i18n": "^3.12.1", - "@react-aria/link": "^3.7.3", - "@react-aria/utils": "^3.25.1", + "@react-aria/i18n": "^3.12.2", + "@react-aria/link": "^3.7.4", + "@react-aria/utils": "^3.25.2", "@react-types/breadcrumbs": "^3.7.7", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4167,14 +4166,14 @@ } }, "node_modules/@react-aria/button": { - "version": "3.9.7", - "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.9.7.tgz", - "integrity": "sha512-xwE6uatbbn3KbNSc0dyDnOo539HJM2cqCPfjiQGt8O9cFbpQSmx76Fj4WotU3BwT7ZVbcAC8D206CgF1C2cDcQ==", + "version": "3.9.8", + "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.9.8.tgz", + "integrity": "sha512-MdbMQ3t5KSCkvKtwYd/Z6sgw0v+r1VQFRYOZ4L53xOkn+u140z8vBpNeWKZh/45gxGv7SJn9s2KstLPdCWmIxw==", "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/toggle": "^3.7.6", + "@react-aria/focus": "^3.18.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", + "@react-stately/toggle": "^3.7.7", "@react-types/button": "^3.9.6", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4184,18 +4183,18 @@ } }, "node_modules/@react-aria/calendar": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.10.tgz", - "integrity": "sha512-5PokdIHAH+CAd6vMHFW9mg77I5tC0FQglYsCEI9ikhCnL5xlt3FmJjLtOs3UJQaWgrd4cdVd0oINpPafJ9ydhA==", + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.11.tgz", + "integrity": "sha512-VLhBovLVu3uJXBkHbgEippmo/K58QLcc/tSJQ0aJUNyHsrvPgHEcj484cb+Uj/yOirXEIzaoW6WEvhcdKrb49Q==", "dependencies": { "@internationalized/date": "^3.5.5", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/utils": "^3.25.1", - "@react-stately/calendar": "^3.5.3", + "@react-aria/utils": "^3.25.2", + "@react-stately/calendar": "^3.5.4", "@react-types/button": "^3.9.6", - "@react-types/calendar": "^3.4.8", + "@react-types/calendar": "^3.4.9", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4205,18 +4204,18 @@ } }, "node_modules/@react-aria/checkbox": { - "version": "3.14.5", - "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.14.5.tgz", - "integrity": "sha512-On8m66CNi1LvbDeDo355au0K66ayIjo0nDe4oe85aNsR/owyzz8hXNPAFuh98owQVMsKt4596FZICAVSMzzhJg==", - "dependencies": { - "@react-aria/form": "^3.0.7", - "@react-aria/interactions": "^3.22.1", - "@react-aria/label": "^3.7.10", - "@react-aria/toggle": "^3.10.6", - "@react-aria/utils": "^3.25.1", - "@react-stately/checkbox": "^3.6.7", + "version": "3.14.6", + "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.14.6.tgz", + "integrity": "sha512-LICY1PR3WsW/VbuLMjZbxo75+poeo3XCXGcUnk6hxMlWfp/Iy/XHVsHlGu9stRPKRF8BSuOGteaHWVn6IXfwtA==", + "dependencies": { + "@react-aria/form": "^3.0.8", + "@react-aria/interactions": "^3.22.2", + "@react-aria/label": "^3.7.11", + "@react-aria/toggle": "^3.10.7", + "@react-aria/utils": "^3.25.2", + "@react-stately/checkbox": "^3.6.8", "@react-stately/form": "^3.0.5", - "@react-stately/toggle": "^3.7.6", + "@react-stately/toggle": "^3.7.7", "@react-types/checkbox": "^3.8.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4226,12 +4225,12 @@ } }, "node_modules/@react-aria/collections": { - "version": "3.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@react-aria/collections/-/collections-3.0.0-alpha.3.tgz", - "integrity": "sha512-SKsoQrCuz4zIVMwKGz0WcFoRbIP0H8+eRU2XzjmWX9KlRdrfeqIBOxuiU8XO3or0aHdbBI/bC/YtCjVzix5Lrg==", + "version": "3.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/@react-aria/collections/-/collections-3.0.0-alpha.4.tgz", + "integrity": "sha512-chMNAlsubnpErBWN7sLhmAMOnE7o17hSfq3s0VDHlvRN9K/mPOPlYokmyWkkPqi7fYiR50EPVHDtwTWLJoqfnw==", "dependencies": { "@react-aria/ssr": "^3.9.5", - "@react-aria/utils": "^3.25.1", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", "use-sync-external-store": "^1.2.0" @@ -4242,19 +4241,19 @@ } }, "node_modules/@react-aria/color": { - "version": "3.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.0-rc.1.tgz", - "integrity": "sha512-oP9PE0Xpo9uQ/TtH1x8iWhsjtk4OTIoTFdQZyoDsj8d84sqRv6Og9ajBZ/VTaneNK1n4NrPSx+qWfXu+SrWlDg==", - "dependencies": { - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/numberfield": "^3.11.5", - "@react-aria/slider": "^3.7.10", - "@react-aria/spinbutton": "^3.6.7", - "@react-aria/textfield": "^3.14.7", - "@react-aria/utils": "^3.25.1", - "@react-aria/visually-hidden": "^3.8.14", - "@react-stately/color": "^3.7.1", + "version": "3.0.0-rc.2", + "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.0-rc.2.tgz", + "integrity": "sha512-h4P7LocDEHPOEWgHYb8VPJLRGkyMhcsXemmvGao6G23zGTpTX8Nr6pEuJhcXQlGWt8hXvj/ASnC750my+zb1yA==", + "dependencies": { + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/numberfield": "^3.11.6", + "@react-aria/slider": "^3.7.11", + "@react-aria/spinbutton": "^3.6.8", + "@react-aria/textfield": "^3.14.8", + "@react-aria/utils": "^3.25.2", + "@react-aria/visually-hidden": "^3.8.15", + "@react-stately/color": "^3.7.2", "@react-stately/form": "^3.0.5", "@react-types/color": "3.0.0-rc.1", "@react-types/shared": "^3.24.1", @@ -4266,20 +4265,20 @@ } }, "node_modules/@react-aria/combobox": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.10.1.tgz", - "integrity": "sha512-B0zjX66HEqjPFnunYR0quAqwVJ6U0ez1eqBp25/611Dtzh3JHUovQmTE0xGGTjRe6N6qJg0VHVr2eRO/D0A+Lw==", + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.10.3.tgz", + "integrity": "sha512-EdDwr2Rp1xy7yWjOYHt2qF1IpAtUrkaNKZJzlIw1XSwcqizQY6E8orNPdZr6ZwD6/tgujxF1N71JTKyffrR0Xw==", "dependencies": { - "@react-aria/i18n": "^3.12.1", - "@react-aria/listbox": "^3.13.1", + "@react-aria/i18n": "^3.12.2", + "@react-aria/listbox": "^3.13.3", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/menu": "^3.15.1", - "@react-aria/overlays": "^3.23.1", - "@react-aria/selection": "^3.19.1", - "@react-aria/textfield": "^3.14.7", - "@react-aria/utils": "^3.25.1", + "@react-aria/menu": "^3.15.3", + "@react-aria/overlays": "^3.23.2", + "@react-aria/selection": "^3.19.3", + "@react-aria/textfield": "^3.14.8", + "@react-aria/utils": "^3.25.2", "@react-stately/collections": "^3.10.9", - "@react-stately/combobox": "^3.9.1", + "@react-stately/combobox": "^3.9.2", "@react-stately/form": "^3.0.5", "@react-types/button": "^3.9.6", "@react-types/combobox": "^3.12.1", @@ -4292,25 +4291,25 @@ } }, "node_modules/@react-aria/datepicker": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.11.1.tgz", - "integrity": "sha512-yEEuDt/ynt7bTfd/9RD1EiLPysWhbgSYSpn5PHVz7I2XORvNPpyamyAgz3+oFiLFLC/zy0qrG7e6V1rvI1NBzw==", + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.11.2.tgz", + "integrity": "sha512-6sbLln3VXSBcBRDgSACBzIzF/5KV5NlNOhZvXPFE6KqFw6GbevjZQTv5BNDXiwA3CQoawIRF7zgRvTANw8HkNA==", "dependencies": { "@internationalized/date": "^3.5.5", "@internationalized/number": "^3.5.3", "@internationalized/string": "^3.2.3", - "@react-aria/focus": "^3.18.1", - "@react-aria/form": "^3.0.7", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/label": "^3.7.10", - "@react-aria/spinbutton": "^3.6.7", - "@react-aria/utils": "^3.25.1", - "@react-stately/datepicker": "^3.10.1", + "@react-aria/focus": "^3.18.2", + "@react-aria/form": "^3.0.8", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/label": "^3.7.11", + "@react-aria/spinbutton": "^3.6.8", + "@react-aria/utils": "^3.25.2", + "@react-stately/datepicker": "^3.10.2", "@react-stately/form": "^3.0.5", "@react-types/button": "^3.9.6", - "@react-types/calendar": "^3.4.8", - "@react-types/datepicker": "^3.8.1", + "@react-types/calendar": "^3.4.9", + "@react-types/datepicker": "^3.8.2", "@react-types/dialog": "^3.5.12", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4321,13 +4320,13 @@ } }, "node_modules/@react-aria/dialog": { - "version": "3.5.16", - "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.16.tgz", - "integrity": "sha512-2clBSQQaoqCjAUkHnMA/noZ1ZnFbEVU67fL9M1QfokezAyLAlyCyD9XSed6+Td/Ncj80N3/Lax65XAlvWCyOlg==", + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.17.tgz", + "integrity": "sha512-lvfEgaqg922J1hurscqCS600OZQVitGtdpo81kAefJaUzMnCxzrYviyT96aaW0simHOlimbYF5js8lxBLZJRaw==", "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/overlays": "^3.23.1", - "@react-aria/utils": "^3.25.1", + "@react-aria/focus": "^3.18.2", + "@react-aria/overlays": "^3.23.2", + "@react-aria/utils": "^3.25.2", "@react-types/dialog": "^3.5.12", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4338,17 +4337,17 @@ } }, "node_modules/@react-aria/dnd": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.7.1.tgz", - "integrity": "sha512-p3/pc8p2fGd4s+Qj4SfRPJjZFStuuXqRNyDQxd9AAFYUWcCQxwDOqtiTZmfvs7Hvl0PUuysHW6Q5v7ABRjVr7w==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.7.2.tgz", + "integrity": "sha512-NuE3EGqoBbe9aXAO9mDfbu4kMO7S4MCgkjkCqYi16TWfRUf38ajQbIlqodCx91b3LVN3SYvNbE3D4Tj5ebkljw==", "dependencies": { "@internationalized/string": "^3.2.3", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/overlays": "^3.23.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/dnd": "^3.4.1", + "@react-aria/overlays": "^3.23.2", + "@react-aria/utils": "^3.25.2", + "@react-stately/dnd": "^3.4.2", "@react-types/button": "^3.9.6", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4359,12 +4358,12 @@ } }, "node_modules/@react-aria/focus": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.1.tgz", - "integrity": "sha512-N0Cy61WCIv+57mbqC7hiZAsB+3rF5n4JKabxUmg/2RTJL6lq7hJ5N4gx75ymKxkN8GnVDwt4pKZah48Wopa5jw==", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.2.tgz", + "integrity": "sha512-Jc/IY+StjA3uqN73o6txKQ527RFU7gnG5crEl5Xy3V+gbYp2O5L3ezAo/E0Ipi2cyMbG6T5Iit1IDs7hcGu8aw==", "dependencies": { - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" @@ -4374,12 +4373,12 @@ } }, "node_modules/@react-aria/form": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.7.tgz", - "integrity": "sha512-VIsKP/KytJPOLRQl0NxWWS1bQELPBuW3vRjmmhBrtgPFmp0uCLhjPBkP6A4uIVj1E/JtAocyHN3DNq4+IJGQCg==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.8.tgz", + "integrity": "sha512-8S2QiyUdAgK43M3flohI0R+2rTyzH088EmgeRArA8euvJTL16cj/oSOKMEgWVihjotJ9n6awPb43ZhKboyNsMg==", "dependencies": { - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", "@react-stately/form": "^3.0.5", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4389,19 +4388,19 @@ } }, "node_modules/@react-aria/grid": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.10.1.tgz", - "integrity": "sha512-7dSgiYVQapBtPV4SIit+9fJ1qoEjtp+PXffJkWAPtGbg/jJ4b0jcVzykH7ARD4w/6jAJN/oVSfrKZqFPoLAd9w==", + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.10.3.tgz", + "integrity": "sha512-l0r9mz05Gwjq3t6JOTNQOf+oAoWN0bXELPJtIr8m0XyXMPFCQe1xsTaX8igVQdrDmXyBc75RAWS0BJo2JF2fIA==", "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", + "@react-aria/focus": "^3.18.2", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/selection": "^3.19.1", - "@react-aria/utils": "^3.25.1", + "@react-aria/selection": "^3.19.3", + "@react-aria/utils": "^3.25.2", "@react-stately/collections": "^3.10.9", - "@react-stately/grid": "^3.9.1", - "@react-stately/selection": "^3.16.1", + "@react-stately/grid": "^3.9.2", + "@react-stately/selection": "^3.16.2", "@react-types/checkbox": "^3.8.3", "@react-types/grid": "^3.2.8", "@react-types/shared": "^3.24.1", @@ -4413,19 +4412,19 @@ } }, "node_modules/@react-aria/gridlist": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.9.1.tgz", - "integrity": "sha512-cue2KCI4WyVmL3j9tZx7xG7gUJ7UyRbawzRTcocJukOmpeoyRaw/robrIYK2Pd//GhRbIMAoo4iOyZk5j7vEww==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/grid": "^3.10.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/selection": "^3.19.1", - "@react-aria/utils": "^3.25.1", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.9.3.tgz", + "integrity": "sha512-bb9GnKKeuL6NljoVUcHxr9F0cy/2WDOXRYeMikTnviRw6cuX95oojrhFfCUvz2d6ID22Btrvh7LkE+oIPVuc+g==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/grid": "^3.10.3", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/selection": "^3.19.3", + "@react-aria/utils": "^3.25.2", "@react-stately/collections": "^3.10.9", - "@react-stately/list": "^3.10.7", - "@react-stately/tree": "^3.8.3", + "@react-stately/list": "^3.10.8", + "@react-stately/tree": "^3.8.4", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4435,16 +4434,16 @@ } }, "node_modules/@react-aria/i18n": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.1.tgz", - "integrity": "sha512-0q3gyogF9Ekah+9LOo6tcfshxsk2Ope+KdbtFHJVhznedMxn6RpHGcVur5ImbQ1dYafA5CmjBUGJW70b56+BGA==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.2.tgz", + "integrity": "sha512-PvEyC6JWylTpe8dQEWqQwV6GiA+pbTxHQd//BxtMSapRW3JT9obObAnb/nFhj3HthkUvqHyj0oO1bfeN+mtD8A==", "dependencies": { "@internationalized/date": "^3.5.5", "@internationalized/message": "^3.1.4", "@internationalized/number": "^3.5.3", "@internationalized/string": "^3.2.3", "@react-aria/ssr": "^3.9.5", - "@react-aria/utils": "^3.25.1", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4453,12 +4452,12 @@ } }, "node_modules/@react-aria/interactions": { - "version": "3.22.1", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.1.tgz", - "integrity": "sha512-5TLzQaDAQQ5C70yG8GInbO4wIylKY67RfTIIwQPGR/4n5OIjbUD8BOj3NuSsuZ/frUPaBXo1VEBBmSO23fxkjw==", + "version": "3.22.2", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.2.tgz", + "integrity": "sha512-xE/77fRVSlqHp2sfkrMeNLrqf2amF/RyuAS6T5oDJemRSgYM3UoxTbWjucPhfnoW7r32pFPHHgz4lbdX8xqD/g==", "dependencies": { "@react-aria/ssr": "^3.9.5", - "@react-aria/utils": "^3.25.1", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4467,11 +4466,11 @@ } }, "node_modules/@react-aria/label": { - "version": "3.7.10", - "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.10.tgz", - "integrity": "sha512-e5XVHA+OUK0aIwr4nHcnIj0z1kUryGaJWYYD2OGkkIltyUCKmwpRqdx8LQYbO4HGsJhvC3hJgidFdGcQwHHPYw==", + "version": "3.7.11", + "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.11.tgz", + "integrity": "sha512-REgejE5Qr8cXG/b8H2GhzQmjQlII/0xQW/4eDzydskaTLvA7lF5HoJUE6biYTquH5va38d8XlH465RPk+bvHzA==", "dependencies": { - "@react-aria/utils": "^3.25.1", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4480,13 +4479,13 @@ } }, "node_modules/@react-aria/link": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.3.tgz", - "integrity": "sha512-dOwzxzo7LF4djBfRC8GcIhuTpDkNUIMT6ykQRV1a3749kgrr10YLascsO/l66k60i2k0T2oClkzfefYEK6WZeA==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.4.tgz", + "integrity": "sha512-E8SLDuS9ssm/d42+3sDFNthfMcNXMUrT2Tq1DIZt22EsMcuEzmJ9B0P7bDP5RgvIw05xVGqZ20nOpU4mKTxQtA==", "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", + "@react-aria/focus": "^3.18.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", "@react-types/link": "^3.5.7", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4496,16 +4495,16 @@ } }, "node_modules/@react-aria/listbox": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.13.1.tgz", - "integrity": "sha512-b5Nu+5d5shJbxpy4s6OXvMlMzm+PVbs3L6CtoHlsKe8cAlSWD340vPHCOGYLwZApIBewepOBvRWgeAF8IDI04w==", - "dependencies": { - "@react-aria/interactions": "^3.22.1", - "@react-aria/label": "^3.7.10", - "@react-aria/selection": "^3.19.1", - "@react-aria/utils": "^3.25.1", + "version": "3.13.3", + "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.13.3.tgz", + "integrity": "sha512-htluPyDfFtn66OEYaJdIaFCYH9wGCNk30vOgZrQkPul9F9Cjce52tTyPVR0ERsf14oCUsjjS5qgeq3dGidRqEw==", + "dependencies": { + "@react-aria/interactions": "^3.22.2", + "@react-aria/label": "^3.7.11", + "@react-aria/selection": "^3.19.3", + "@react-aria/utils": "^3.25.2", "@react-stately/collections": "^3.10.9", - "@react-stately/list": "^3.10.7", + "@react-stately/list": "^3.10.8", "@react-types/listbox": "^3.5.1", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4524,19 +4523,19 @@ } }, "node_modules/@react-aria/menu": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.15.1.tgz", - "integrity": "sha512-ZBTMZiJ17j6t7epcsjd0joAzsMKO31KLJHPtWAEfk1JkBxrMoirISPN8O1CeK/uBX++VaWSrDZfFe1EjrOwKuA==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/overlays": "^3.23.1", - "@react-aria/selection": "^3.19.1", - "@react-aria/utils": "^3.25.1", + "version": "3.15.3", + "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.15.3.tgz", + "integrity": "sha512-vvUmVjJwIg3h2r+7isQXTwlmoDlPAFBckHkg94p3afrT1kNOTHveTsaVl17mStx/ymIioaAi3PrIXk/PZXp1jw==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/overlays": "^3.23.2", + "@react-aria/selection": "^3.19.3", + "@react-aria/utils": "^3.25.2", "@react-stately/collections": "^3.10.9", - "@react-stately/menu": "^3.8.1", - "@react-stately/tree": "^3.8.3", + "@react-stately/menu": "^3.8.2", + "@react-stately/tree": "^3.8.4", "@react-types/button": "^3.9.6", "@react-types/menu": "^3.9.11", "@react-types/shared": "^3.24.1", @@ -4548,11 +4547,11 @@ } }, "node_modules/@react-aria/meter": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.15.tgz", - "integrity": "sha512-OUAzgmfiyEvBF+h9NlG7s8jvrGNTqj/zAWyUWEh5FMEjKFrDfni6awwFoRs164QqmUvRBNC0/eKv3Ghd2GIkRA==", + "version": "3.4.16", + "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.16.tgz", + "integrity": "sha512-hJqKnEE6mmK2Psx5kcI7NZ44OfTg0Bp7DatQSQ4zZE4yhnykRRwxqSKjze37tPR63cCqgRXtQ5LISfBfG54c0Q==", "dependencies": { - "@react-aria/progress": "^3.4.15", + "@react-aria/progress": "^3.4.16", "@react-types/meter": "^3.4.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4562,17 +4561,17 @@ } }, "node_modules/@react-aria/numberfield": { - "version": "3.11.5", - "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.5.tgz", - "integrity": "sha512-cfJzU7SWsksKiLjfubSj5lR18ebQ7IbYaMQZbxdpZSPOANHIiktaxjPK4Nz7cqZ+HZ/6tQEirpY0iqpLx35CSw==", - "dependencies": { - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/spinbutton": "^3.6.7", - "@react-aria/textfield": "^3.14.7", - "@react-aria/utils": "^3.25.1", + "version": "3.11.6", + "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.6.tgz", + "integrity": "sha512-nvEWiQcWRwj6O2JXmkXEeWoBX/GVZT9zumFJcew3XknGTWJUr3h2AOymIQFt9g4mpag8IgOFEpSIlwhtZHdp1A==", + "dependencies": { + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/spinbutton": "^3.6.8", + "@react-aria/textfield": "^3.14.8", + "@react-aria/utils": "^3.25.2", "@react-stately/form": "^3.0.5", - "@react-stately/numberfield": "^3.9.5", + "@react-stately/numberfield": "^3.9.6", "@react-types/button": "^3.9.6", "@react-types/numberfield": "^3.8.5", "@react-types/shared": "^3.24.1", @@ -4584,17 +4583,17 @@ } }, "node_modules/@react-aria/overlays": { - "version": "3.23.1", - "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.23.1.tgz", - "integrity": "sha512-qNV3pGThvRXjhdHCfqN9Eg4uD+nFm2DoK6d5e9LFd1+xCkKbT88afDBIcLmeG7fgfmukb1sNmzCJQJt8Svk54g==", + "version": "3.23.2", + "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.23.2.tgz", + "integrity": "sha512-vjlplr953YAuJfHiP4O+CyrTlr6OaFgXAGrzWq4MVMjnpV/PT5VRJWYFHR0sUGlHTPqeKS4NZbi/xCSgl/3pGQ==", "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", + "@react-aria/focus": "^3.18.2", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", "@react-aria/ssr": "^3.9.5", - "@react-aria/utils": "^3.25.1", - "@react-aria/visually-hidden": "^3.8.14", - "@react-stately/overlays": "^3.6.9", + "@react-aria/utils": "^3.25.2", + "@react-aria/visually-hidden": "^3.8.15", + "@react-stately/overlays": "^3.6.10", "@react-types/button": "^3.9.6", "@react-types/overlays": "^3.8.9", "@react-types/shared": "^3.24.1", @@ -4606,13 +4605,13 @@ } }, "node_modules/@react-aria/progress": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.15.tgz", - "integrity": "sha512-wlx8pgEet3mlq5Skjy7yV1DfQiEg79tZtojpb5YGN2dIAH8sxClrKOSJRVce0fy9IXVCKrQxjQNXPNUIojK5Rg==", + "version": "3.4.16", + "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.16.tgz", + "integrity": "sha512-RbDIFQg4+/LG+KYZeLAijt2zH7K2Gp0CY9RKWdho3nU5l3/w57Fa7NrfDGWtpImrt7bR2nRmXMA6ESfr7THfrg==", "dependencies": { - "@react-aria/i18n": "^3.12.1", - "@react-aria/label": "^3.7.10", - "@react-aria/utils": "^3.25.1", + "@react-aria/i18n": "^3.12.2", + "@react-aria/label": "^3.7.11", + "@react-aria/utils": "^3.25.2", "@react-types/progress": "^3.5.6", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4622,17 +4621,17 @@ } }, "node_modules/@react-aria/radio": { - "version": "3.10.6", - "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.6.tgz", - "integrity": "sha512-Cr7kiTUWw+HOEdFHztqrFlSXvwuzOCTMbwNkziTyc9fualIX6UDilykND2ctfBgkM4qH7SgQt+SxAIwTdevsKg==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/form": "^3.0.7", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/label": "^3.7.10", - "@react-aria/utils": "^3.25.1", - "@react-stately/radio": "^3.10.6", + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.7.tgz", + "integrity": "sha512-o2tqIe7xd1y4HeCBQfz/sXIwLJuI6LQbVoCQ1hgk/5dGhQ0LiuXohRYitGRl9zvxW8jYdgLULmOEDt24IflE8A==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/form": "^3.0.8", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/label": "^3.7.11", + "@react-aria/utils": "^3.25.2", + "@react-stately/radio": "^3.10.7", "@react-types/radio": "^3.8.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4642,16 +4641,16 @@ } }, "node_modules/@react-aria/searchfield": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.7.7.tgz", - "integrity": "sha512-2f087PCR8X5LYyLnvjCIOV27xjjTCkDFPnQaC7XSPCfzDYGM8utCR56JfZMqHnjcMnVNoiEg7EjSBBrh7I2bnQ==", + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.7.8.tgz", + "integrity": "sha512-SsF5xwH8Us548QgzivvbM7nhFbw7pu23xnRRIuhlP3MwOR3jRUFh17NKxf3Z0jvrDv/u0xfm3JKHIgaUN0KJ2A==", "dependencies": { - "@react-aria/i18n": "^3.12.1", - "@react-aria/textfield": "^3.14.7", - "@react-aria/utils": "^3.25.1", - "@react-stately/searchfield": "^3.5.5", + "@react-aria/i18n": "^3.12.2", + "@react-aria/textfield": "^3.14.8", + "@react-aria/utils": "^3.25.2", + "@react-stately/searchfield": "^3.5.6", "@react-types/button": "^3.9.6", - "@react-types/searchfield": "^3.5.7", + "@react-types/searchfield": "^3.5.8", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4660,20 +4659,20 @@ } }, "node_modules/@react-aria/select": { - "version": "3.14.7", - "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.14.7.tgz", - "integrity": "sha512-qZy5oX6P8SGrdv4bHb8iVMIVv+vLuo7UwOJtsQ1FUORIsZmBEz0RyfgYdzlueMcZNoQ9JgLYtrK2e0h6AmJOlg==", - "dependencies": { - "@react-aria/form": "^3.0.7", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/label": "^3.7.10", - "@react-aria/listbox": "^3.13.1", - "@react-aria/menu": "^3.15.1", - "@react-aria/selection": "^3.19.1", - "@react-aria/utils": "^3.25.1", - "@react-aria/visually-hidden": "^3.8.14", - "@react-stately/select": "^3.6.6", + "version": "3.14.9", + "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.14.9.tgz", + "integrity": "sha512-tiNgMyA2G9nKnFn3pB/lMSgidNToxSFU7r6l4OcG+Vyr63J7B/3dF2lTXq8IYhlfOR3K3uQkjroSx52CmC3NDw==", + "dependencies": { + "@react-aria/form": "^3.0.8", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/label": "^3.7.11", + "@react-aria/listbox": "^3.13.3", + "@react-aria/menu": "^3.15.3", + "@react-aria/selection": "^3.19.3", + "@react-aria/utils": "^3.25.2", + "@react-aria/visually-hidden": "^3.8.15", + "@react-stately/select": "^3.6.7", "@react-types/button": "^3.9.6", "@react-types/select": "^3.9.6", "@react-types/shared": "^3.24.1", @@ -4685,15 +4684,15 @@ } }, "node_modules/@react-aria/selection": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.19.1.tgz", - "integrity": "sha512-mbExvq2Omi60sTWFGjwcNz1ja2P8VDsxWAqSypHRTyqXhtgqbv8V/v8Gp+7BmVPH1YHcbhztl6rvUZTDOSszzw==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/selection": "^3.16.1", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.19.3.tgz", + "integrity": "sha512-GYoObXCXlmGK08hp7Qfl6Bk0U+bKP5YDWSsX+MzNjJsqzQSLm4S06tRB9ACM7gIo9dDCvL4IRxdSYTJAlJc6bw==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", + "@react-stately/selection": "^3.16.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4703,11 +4702,11 @@ } }, "node_modules/@react-aria/separator": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.4.1.tgz", - "integrity": "sha512-bZ+GQ936Y+WXAtsQjJdEMgYeqmqjhU90+wOlRGjmGdwf+/ht2yzBpeRuHEYUbE6F0iis/YoVc+b8ppAtPna/kA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.4.2.tgz", + "integrity": "sha512-Xql9Kg3VlGesEUC7QheE+L5b3KgBv0yxiUU+/4JP8V2vfU/XSz4xmprHEeq7KVQVOetn38iiXU8gA5g26SEsUA==", "dependencies": { - "@react-aria/utils": "^3.25.1", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4716,16 +4715,16 @@ } }, "node_modules/@react-aria/slider": { - "version": "3.7.10", - "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.10.tgz", - "integrity": "sha512-QmBn87sDkncS/uhcrH0MxUN7bcEo8cHYcWk+gk7mibdIpyxyVDPKh7v7ZsosmAJLzjS0yb2ec1/Q5Oldfg1k/A==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/label": "^3.7.10", - "@react-aria/utils": "^3.25.1", - "@react-stately/slider": "^3.5.6", + "version": "3.7.11", + "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.11.tgz", + "integrity": "sha512-2WAwjANXPsA2LHJ5nxxV4c7ihFAzz2spaBz8+FJ7MDYE7WroYnE8uAXElea1aGo+Lk0DTiAdepLpBkggqPNanw==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/label": "^3.7.11", + "@react-aria/utils": "^3.25.2", + "@react-stately/slider": "^3.5.7", "@react-types/shared": "^3.24.1", "@react-types/slider": "^3.7.5", "@swc/helpers": "^0.5.0" @@ -4735,13 +4734,13 @@ } }, "node_modules/@react-aria/spinbutton": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.7.tgz", - "integrity": "sha512-OCimp4yXoFIgh6WAMOls5DDDRDRO75ZFic3YA6wLWTRNHxo1Lj8S90i1A6pakY6bi4hdBCKmj4DnFSNKAw1iWg==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.8.tgz", + "integrity": "sha512-OJMAYRIZ0WrWE+5tZsywrSg4t+aOwl6vl/e1+J64YcGMM+p+AKd61KGG5T0OgNSORXjoVIZOmj6wZ6Od4xfPMw==", "dependencies": { - "@react-aria/i18n": "^3.12.1", + "@react-aria/i18n": "^3.12.2", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/utils": "^3.25.1", + "@react-aria/utils": "^3.25.2", "@react-types/button": "^3.9.6", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4766,12 +4765,12 @@ } }, "node_modules/@react-aria/switch": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.6.tgz", - "integrity": "sha512-+dZOX1utODlx5dC90DtwnXd9nvln9HxMffBj/gmMT1/cD/RmXfjvymfjTsTMwvHhqCew9yfpvod0ZWwj3BkLGw==", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.7.tgz", + "integrity": "sha512-yBNvKylhc3ZRQ0+7mD0mIenRRe+1yb8YaqMMZr8r3Bf87LaiFtQyhRFziq6ZitcwTJz5LEWjBihxbSVvUrf49w==", "dependencies": { - "@react-aria/toggle": "^3.10.6", - "@react-stately/toggle": "^3.7.6", + "@react-aria/toggle": "^3.10.7", + "@react-stately/toggle": "^3.7.7", "@react-types/shared": "^3.24.1", "@react-types/switch": "^3.5.5", "@swc/helpers": "^0.5.0" @@ -4781,20 +4780,20 @@ } }, "node_modules/@react-aria/table": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.15.1.tgz", - "integrity": "sha512-jVDLxp6Y/9M6y45c1I6u6msJ9dBg2I7Cu/FlSaK6HthTpN23UXuGw1oWuAjbfqi31nVXHWBwjCZkGKTdMjLf5A==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/grid": "^3.10.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", + "version": "3.15.3", + "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.15.3.tgz", + "integrity": "sha512-nQCLjlEvyJHyuijHw8ESqnA9fxNJfQHx0WPcl08VDEb8VxcE/MVzSAIedSWaqjG5k9Oflz6o/F/zHtzw4AFAow==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/grid": "^3.10.3", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", "@react-aria/live-announcer": "^3.3.4", - "@react-aria/utils": "^3.25.1", - "@react-aria/visually-hidden": "^3.8.14", + "@react-aria/utils": "^3.25.2", + "@react-aria/visually-hidden": "^3.8.15", "@react-stately/collections": "^3.10.9", "@react-stately/flags": "^3.0.3", - "@react-stately/table": "^3.12.1", + "@react-stately/table": "^3.12.2", "@react-types/checkbox": "^3.8.3", "@react-types/grid": "^3.2.8", "@react-types/shared": "^3.24.1", @@ -4807,15 +4806,15 @@ } }, "node_modules/@react-aria/tabs": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.3.tgz", - "integrity": "sha512-J1KOCdx4eSyMMeNCvO8BIz8E8xez12B+cYbM4BbJzWlcfMboGYUnM0lvI8QSpFPa/H9LkAhp7BJnl9IZeIBzoA==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/selection": "^3.19.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/tabs": "^3.6.8", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.5.tgz", + "integrity": "sha512-aQZGAoOIg1B16qlvXIy6+rHbNBNVcWkGjOjeyvqTTPMjXt/FmElkICnqckI7MRJ1lTqzyppCOBitYOHSXRo8Uw==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/i18n": "^3.12.2", + "@react-aria/selection": "^3.19.3", + "@react-aria/utils": "^3.25.2", + "@react-stately/tabs": "^3.6.9", "@react-types/shared": "^3.24.1", "@react-types/tabs": "^3.3.9", "@swc/helpers": "^0.5.0" @@ -4826,17 +4825,17 @@ } }, "node_modules/@react-aria/tag": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.3.tgz", - "integrity": "sha512-BqXKazX9YHvt6+qzGTu770V0FqGVefzz03hmnV2IVb+zYchXBv3WYbWVy46s/D5zTePOAXdpitQHxqy5rh+hgw==", - "dependencies": { - "@react-aria/gridlist": "^3.9.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/label": "^3.7.10", - "@react-aria/selection": "^3.19.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/list": "^3.10.7", + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.5.tgz", + "integrity": "sha512-iyJuATQ8t2cdLC7hiZm143eeZze/MtgxaMq0OewlI9TUje54bkw2Q+CjERdgisIo3Eemf55JJgylGrTcalEJAg==", + "dependencies": { + "@react-aria/gridlist": "^3.9.3", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/label": "^3.7.11", + "@react-aria/selection": "^3.19.3", + "@react-aria/utils": "^3.25.2", + "@react-stately/list": "^3.10.8", "@react-types/button": "^3.9.6", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4847,18 +4846,18 @@ } }, "node_modules/@react-aria/textfield": { - "version": "3.14.7", - "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.7.tgz", - "integrity": "sha512-1cWCG6vkjlwJuRTXKbKl9P0Q/0Li5pnMafZqDDWfDOlkS5dFGxYG6QFfoaYp7N6XMoNkXiculnCssfrQ+8hWgA==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/form": "^3.0.7", - "@react-aria/label": "^3.7.10", - "@react-aria/utils": "^3.25.1", + "version": "3.14.8", + "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.8.tgz", + "integrity": "sha512-FHEvsHdE1cMR2B7rlf+HIneITrC40r201oLYbHAp3q26jH/HUujzFBB9I20qhXjyBohMWfQLqJhSwhs1VW1RJQ==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/form": "^3.0.8", + "@react-aria/label": "^3.7.11", + "@react-aria/utils": "^3.25.2", "@react-stately/form": "^3.0.5", - "@react-stately/utils": "^3.10.2", + "@react-stately/utils": "^3.10.3", "@react-types/shared": "^3.24.1", - "@react-types/textfield": "^3.9.5", + "@react-types/textfield": "^3.9.6", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -4866,14 +4865,14 @@ } }, "node_modules/@react-aria/toggle": { - "version": "3.10.6", - "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.6.tgz", - "integrity": "sha512-AGlbtB1b8grrtjbiW5Au0LKYzxR83RHbHhaUkFwajyYRGyuEzr3Y03OiveoPB+DayA8Gz3H1ZVmW++8JZQOWHw==", + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.7.tgz", + "integrity": "sha512-/RJQU8QlPZXRElZ3Tt10F5K5STgUBUGPpfuFUGuwF3Kw3GpPxYsA1YAVjxXz2MMGwS0+y6+U/J1xIs1AF0Jwzg==", "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/toggle": "^3.7.6", + "@react-aria/focus": "^3.18.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", + "@react-stately/toggle": "^3.7.7", "@react-types/checkbox": "^3.8.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4883,13 +4882,13 @@ } }, "node_modules/@react-aria/toolbar": { - "version": "3.0.0-beta.7", - "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.7.tgz", - "integrity": "sha512-PKaXD2qiWcVOn/bX07ipamTc6OlqypqcQRGG7WUL0ZXWfV6AfL7GFPS1B2Jh7Etetq68Ynyuo6R4jT4Jypsjdg==", + "version": "3.0.0-beta.8", + "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.8.tgz", + "integrity": "sha512-nMlA1KK54/Kohb3HlHAzobg69PVIEr8Q1j5P3tLd9apY8FgGvnz7yLpcj6kO1GA872gseEzgiO0Rzk+yRHQRCA==", "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/utils": "^3.25.1", + "@react-aria/focus": "^3.18.2", + "@react-aria/i18n": "^3.12.2", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4898,14 +4897,14 @@ } }, "node_modules/@react-aria/tooltip": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.6.tgz", - "integrity": "sha512-JvRAMTcMju/KBOtISjVKKtIDzG3J1r6xK+mZTvu6ArM7DdeMBM5A8Lwk0bJ8dhr+YybiM9rR3hoZv3/E7IIYVw==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.7.tgz", + "integrity": "sha512-UOTTDbbUz7OaE48VjNSWl+XQbYCUs5Gss4I3Tv1pfRLXzVtGYXv3ur/vRayvZR0xd12ANY26fZPNkSmCFpmiXw==", "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/tooltip": "^3.4.11", + "@react-aria/focus": "^3.18.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", + "@react-stately/tooltip": "^3.4.12", "@react-types/shared": "^3.24.1", "@react-types/tooltip": "^3.4.11", "@swc/helpers": "^0.5.0" @@ -4915,15 +4914,15 @@ } }, "node_modules/@react-aria/tree": { - "version": "3.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.0.0-alpha.3.tgz", - "integrity": "sha512-o/9B+PVSUYxDM1KxQ/Pl1CytPtIagyidmasd10266hWfwzvPA0ZyakBwIEFj+ROnr9buAdP+A4sOTRo+a6g+YQ==", - "dependencies": { - "@react-aria/gridlist": "^3.9.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/selection": "^3.19.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/tree": "^3.8.3", + "version": "3.0.0-alpha.5", + "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.0.0-alpha.5.tgz", + "integrity": "sha512-6JtkvQ/KQNFyqxc5M6JMVY63heHt2gZAwXxEt+Ojx/sbWDtDb5RrZVgkb44n7R/tMrFPJEiYZLMFPbGCsUQeJQ==", + "dependencies": { + "@react-aria/gridlist": "^3.9.3", + "@react-aria/i18n": "^3.12.2", + "@react-aria/selection": "^3.19.3", + "@react-aria/utils": "^3.25.2", + "@react-stately/tree": "^3.8.4", "@react-types/button": "^3.9.6", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -4934,12 +4933,12 @@ } }, "node_modules/@react-aria/utils": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.25.1.tgz", - "integrity": "sha512-5Uj864e7T5+yj78ZfLnfHqmypLiqW2mN+nsdslog2z5ssunTqjolVeM15ootXskjISlZ7MojLpq97kIC4nlnAw==", + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.25.2.tgz", + "integrity": "sha512-GdIvG8GBJJZygB4L2QJP1Gabyn2mjFsha73I2wSe+o4DYeGWoJiMZRM06PyTIxLH4S7Sn7eVDtsSBfkc2VY/NA==", "dependencies": { "@react-aria/ssr": "^3.9.5", - "@react-stately/utils": "^3.10.2", + "@react-stately/utils": "^3.10.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" @@ -4949,14 +4948,14 @@ } }, "node_modules/@react-aria/virtualizer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-4.0.1.tgz", - "integrity": "sha512-JZ6X0l38ZwBU/JgeLwkDA8mknRxqO1nYSVaPZHgOg8fd9BzMRWBjse7VW+Uf09P0uAEFElwlB+RY8UDx+W/Fmg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-4.0.2.tgz", + "integrity": "sha512-HNhpZl53UM2Z8g0DNvjAW7aZRwOReYgKRxdTF/IlYHNMLpdqWZinKwLbxZCsbgX3SCjdIGns90YhkMSKVpfrpw==", "dependencies": { - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", - "@react-stately/virtualizer": "^4.0.1", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", + "@react-stately/virtualizer": "^4.0.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -4966,12 +4965,12 @@ } }, "node_modules/@react-aria/visually-hidden": { - "version": "3.8.14", - "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.14.tgz", - "integrity": "sha512-DV3yagbAgO4ywQTq6D/AxcIaTC8c77r/SxlIMhQBMQ6vScJWTCh6zFG55wmLe3NKqvRrowv1OstlmYfZQ4v/XA==", + "version": "3.8.15", + "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.15.tgz", + "integrity": "sha512-l+sJ7xTdD5Sd6+rDNDaeJCSPnHOsI+BaJyApvb/YcVgHa7rB47lp6TXCWUCDItcPY4JqRGyeByRJVrtzBFTWCw==", "dependencies": { - "@react-aria/interactions": "^3.22.1", - "@react-aria/utils": "^3.25.1", + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -5062,12 +5061,12 @@ } }, "node_modules/@react-spectrum/avatar": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/@react-spectrum/avatar/-/avatar-3.0.14.tgz", - "integrity": "sha512-QQRRQEO4mHdW9UtXomEJw9gAfOliqhMaYMJYWlwytCAipErrllae7U9VK0AaECokfNBib3Klhp8b/4VtLKr+dw==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@react-spectrum/avatar/-/avatar-3.0.15.tgz", + "integrity": "sha512-o41Aa1eGQg2rkof4xz+tNCQU6eZ+r4DyKDXnHCKE0DkjIoii5wYYMa6tLxblZVGMmuR0EvqOEhEs/6xJFBypGA==", "dependencies": { - "@react-aria/utils": "^3.25.1", - "@react-spectrum/utils": "^3.11.9", + "@react-aria/utils": "^3.25.2", + "@react-spectrum/utils": "^3.11.10", "@react-types/avatar": "^3.0.9", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -5212,12 +5211,12 @@ } }, "node_modules/@react-spectrum/combobox": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/combobox/-/combobox-3.13.1.tgz", - "integrity": "sha512-p6Wt8TCvaE/ljDpRZQEuGjxvFkXiIwElz3Fq/qoV6qhdeXbm8GxEwkfzpcBk2SgvjVAAWgQYcmUJVav+R5J0/g==", + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/@react-spectrum/combobox/-/combobox-3.13.2.tgz", + "integrity": "sha512-IewORdb5GpIrgSw56fNqrTHwW8gCxSUIpAgJG+zlGb1eBmf2cybD7GpZ56am36bxst6jP4jxw06rMbGYxer9Fg==", "dependencies": { "@react-aria/button": "^3.9.7", - "@react-aria/combobox": "^3.10.1", + "@react-aria/combobox": "^3.10.3", "@react-aria/dialog": "^3.5.16", "@react-aria/focus": "^3.18.1", "@react-aria/form": "^3.0.7", @@ -5333,12 +5332,12 @@ } }, "node_modules/@react-spectrum/divider": { - "version": "3.5.15", - "resolved": "https://registry.npmjs.org/@react-spectrum/divider/-/divider-3.5.15.tgz", - "integrity": "sha512-bL0pwPup9VL7W4faxvHonChx8eEbBUhX67/V47wR21q4PmnuP3bOVZ6U3qqCbhA+R246zsyxlBouX3mL6QuKvg==", + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@react-spectrum/divider/-/divider-3.5.16.tgz", + "integrity": "sha512-Y7ywKHcId/pRL93S2M5xGNP0VaFRI9n2nPEvtOsfsSfJKzRzqfEPjcO4+WZqHwAPUf6j0qmo1LMj1XiJqk0kwA==", "dependencies": { - "@react-aria/separator": "^3.4.1", - "@react-spectrum/utils": "^3.11.9", + "@react-aria/separator": "^3.4.2", + "@react-spectrum/utils": "^3.11.10", "@react-types/divider": "^3.3.11", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -5443,12 +5442,12 @@ } }, "node_modules/@react-spectrum/image": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@react-spectrum/image/-/image-3.5.3.tgz", - "integrity": "sha512-8ZUkWXH9tnR+ZnxEeMEflo/nMRNFn60VpXOt9hfJlXbhwUKD4eO3TFA14QQXr407XSZwt9d7CGkT4urw4lxtmA==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@react-spectrum/image/-/image-3.5.4.tgz", + "integrity": "sha512-xfcPejRWdr5di9NAPNpEUG22x6DVZrKeNRfa/qglLDvGUHbCQ3uY12hvmAVSVOLQuZs40SBuJ/dEwHgy80Zljw==", "dependencies": { - "@react-aria/utils": "^3.25.1", - "@react-spectrum/utils": "^3.11.9", + "@react-aria/utils": "^3.25.2", + "@react-spectrum/utils": "^3.11.10", "@react-types/image": "^3.4.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -5516,12 +5515,12 @@ } }, "node_modules/@react-spectrum/layout": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/@react-spectrum/layout/-/layout-3.6.7.tgz", - "integrity": "sha512-EheC/J99qt2GpVq05UqPk9iH9PImH9SHXmikNqf/pckKH2Xh/EUY9t5ab+oOYq0N9JbdLp9a38AvuL9KyTJAFQ==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/@react-spectrum/layout/-/layout-3.6.8.tgz", + "integrity": "sha512-E2P8ttCc/0yGaf+1N7SZUjiR0nWDbhJxFddnxKtWCUzA7dvn1wuDSHjPHOHBKPn8/Td6EJds0/d819S3dk25Vg==", "dependencies": { - "@react-aria/utils": "^3.25.1", - "@react-spectrum/utils": "^3.11.9", + "@react-aria/utils": "^3.25.2", + "@react-spectrum/utils": "^3.11.10", "@react-types/layout": "^3.3.17", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -5617,26 +5616,26 @@ } }, "node_modules/@react-spectrum/menu": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/@react-spectrum/menu/-/menu-3.20.1.tgz", - "integrity": "sha512-lIkL14tJaZh3Ago2x8EMcLlyGBMRquDz0OsqgMHeHwQOtUOnIY31JdrWNBdSYWgASZDytrKJSU4e5gXRMCYNEw==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/menu": "^3.15.1", - "@react-aria/overlays": "^3.23.1", - "@react-aria/separator": "^3.4.1", - "@react-aria/utils": "^3.25.1", + "version": "3.20.3", + "resolved": "https://registry.npmjs.org/@react-spectrum/menu/-/menu-3.20.3.tgz", + "integrity": "sha512-NZDSN3x//KGQEHo1BKgcIDUPG4BUt0Iw0jhVl9e3W5s/KctbHVriNxGTpijKyW9s1AFffQNTrN06NC8CwDZKbA==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/menu": "^3.15.3", + "@react-aria/overlays": "^3.23.2", + "@react-aria/separator": "^3.4.2", + "@react-aria/utils": "^3.25.2", "@react-spectrum/button": "^3.16.6", - "@react-spectrum/layout": "^3.6.7", + "@react-spectrum/layout": "^3.6.8", "@react-spectrum/overlays": "^5.6.3", "@react-spectrum/text": "^3.5.7", - "@react-spectrum/utils": "^3.11.9", + "@react-spectrum/utils": "^3.11.10", "@react-stately/collections": "^3.10.9", - "@react-stately/menu": "^3.8.1", - "@react-stately/overlays": "^3.6.9", - "@react-stately/tree": "^3.8.3", + "@react-stately/menu": "^3.8.2", + "@react-stately/overlays": "^3.6.10", + "@react-stately/tree": "^3.8.4", "@react-types/menu": "^3.9.11", "@react-types/overlays": "^3.8.9", "@react-types/shared": "^3.24.1", @@ -5765,14 +5764,14 @@ } }, "node_modules/@react-spectrum/provider": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.9.9.tgz", - "integrity": "sha512-sVgIG0MZ/4KCrJgWjOGyEdP5nhl8fXxp6L1s7SWyzWT/e6ypD0Og9hkQo/yY2XHP2hI4ZiZ4Psc1H4olsrp5lw==", - "dependencies": { - "@react-aria/i18n": "^3.12.1", - "@react-aria/overlays": "^3.23.1", - "@react-aria/utils": "^3.25.1", - "@react-spectrum/utils": "^3.11.9", + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.9.10.tgz", + "integrity": "sha512-KWds89+YN7JfaJ5nQ0RmjAo+OKsbRwFg7UBu06fzQyzVlP9ff11QRce9G/gTuo7A0TJ0rV4ihi4+qqWpR1MSJA==", + "dependencies": { + "@react-aria/i18n": "^3.12.2", + "@react-aria/overlays": "^3.23.2", + "@react-aria/utils": "^3.25.2", + "@react-spectrum/utils": "^3.11.10", "@react-types/provider": "^3.8.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", @@ -5992,20 +5991,20 @@ } }, "node_modules/@react-spectrum/textfield": { - "version": "3.12.3", - "resolved": "https://registry.npmjs.org/@react-spectrum/textfield/-/textfield-3.12.3.tgz", - "integrity": "sha512-1NUTA/Wo8cPLmKcQymgzVBd37Q1mLf358stV4MxLqKjnPT+rGHBTflhV1cmRpLbWdXYnyPSEXyZx12YXctauKg==", - "dependencies": { - "@react-aria/focus": "^3.18.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/textfield": "^3.14.7", - "@react-aria/utils": "^3.25.1", + "version": "3.12.4", + "resolved": "https://registry.npmjs.org/@react-spectrum/textfield/-/textfield-3.12.4.tgz", + "integrity": "sha512-PYCPt4QIxsxKV5Oa8Adw7B2LmMEpwnjLDblPDEgn5XtIfxbVi1WaIpV4+TzSuXHgKePuMTIQRplh+Kqo5PAFxg==", + "dependencies": { + "@react-aria/focus": "^3.18.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/textfield": "^3.14.8", + "@react-aria/utils": "^3.25.2", "@react-spectrum/form": "^3.7.8", "@react-spectrum/label": "^3.16.8", - "@react-spectrum/utils": "^3.11.9", - "@react-stately/utils": "^3.10.2", + "@react-spectrum/utils": "^3.11.10", + "@react-stately/utils": "^3.10.3", "@react-types/shared": "^3.24.1", - "@react-types/textfield": "^3.9.5", + "@react-types/textfield": "^3.9.6", "@spectrum-icons/ui": "^3.6.9", "@swc/helpers": "^0.5.0" }, @@ -6075,13 +6074,13 @@ } }, "node_modules/@react-spectrum/utils": { - "version": "3.11.9", - "resolved": "https://registry.npmjs.org/@react-spectrum/utils/-/utils-3.11.9.tgz", - "integrity": "sha512-k+0dwCflYejSix7FaRMp63ptgs/nc9ndOVa1qJVI/VGK+P9alZmqMXUhIztClLCcyFjJrd9O2YIaAEsBCkBNRw==", + "version": "3.11.10", + "resolved": "https://registry.npmjs.org/@react-spectrum/utils/-/utils-3.11.10.tgz", + "integrity": "sha512-VqmPPnc5L7cfoNx11u8CxvP0VCywlLSUjPfHIUGHoneaBPSwsnMZohlBL/qMJn6yWYJfwEk3gnYaHHYZXN42Rg==", "dependencies": { - "@react-aria/i18n": "^3.12.1", + "@react-aria/i18n": "^3.12.2", "@react-aria/ssr": "^3.9.5", - "@react-aria/utils": "^3.25.1", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" @@ -6107,12 +6106,12 @@ } }, "node_modules/@react-spectrum/well": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@react-spectrum/well/-/well-3.4.15.tgz", - "integrity": "sha512-bzSIZAtXjHaLzcENYracSDabjQgU1KJAXofQ/YwBqZwMDVsokG+kvR+bfGfW05tldgZH5/7Am9D/pIcSW4qBUQ==", + "version": "3.4.16", + "resolved": "https://registry.npmjs.org/@react-spectrum/well/-/well-3.4.16.tgz", + "integrity": "sha512-N4Z8B5p/D+Wnqgz8kKegn+5GwVbBI2RlYglplFyavBubv7IB7Lk89kSyMksodCuYYW81D2a1LfAxADgR/j4OmA==", "dependencies": { - "@react-aria/utils": "^3.25.1", - "@react-spectrum/utils": "^3.11.9", + "@react-aria/utils": "^3.25.2", + "@react-spectrum/utils": "^3.11.10", "@react-types/shared": "^3.24.1", "@react-types/well": "^3.3.11", "@swc/helpers": "^0.5.0" @@ -6188,13 +6187,13 @@ } }, "node_modules/@react-stately/calendar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.3.tgz", - "integrity": "sha512-SRwsgszyc9FNcvkjqBe81e/tnjKpRqH+yTYpG0uI9NR1HfyddmhR3Y7QilWPcqQkq4SQb7pL68SkTPH2dX2dng==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.4.tgz", + "integrity": "sha512-R2011mtFSXIjzMXaA+CZ1sflPm9XkTBMqVk77Bnxso2ZsG7FUX8nqFmaDavxwTuHFC6OUexAGSMs8bP9KycTNg==", "dependencies": { "@internationalized/date": "^3.5.5", - "@react-stately/utils": "^3.10.2", - "@react-types/calendar": "^3.4.8", + "@react-stately/utils": "^3.10.3", + "@react-types/calendar": "^3.4.9", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -6203,12 +6202,12 @@ } }, "node_modules/@react-stately/checkbox": { - "version": "3.6.7", - "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.7.tgz", - "integrity": "sha512-ZOaBNXXazpwkuKj5hk6FtGbXO7HoKEGXvf3p7FcHcIHyiEJ65GBvC7e7HwMc3jYxlBwtbebSpEcf3oFqI5dl3A==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.8.tgz", + "integrity": "sha512-c8TWjU67XHHBCpqj6+FXXhQUWGr2Pil1IKggX81pkedhWiJl3/7+WHJuZI0ivGnRjp3aISNOG8UNVlBEjS9E8A==", "dependencies": { "@react-stately/form": "^3.0.5", - "@react-stately/utils": "^3.10.2", + "@react-stately/utils": "^3.10.3", "@react-types/checkbox": "^3.8.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -6230,17 +6229,17 @@ } }, "node_modules/@react-stately/color": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.7.1.tgz", - "integrity": "sha512-pJqM7fZ7+zy8wnzCUkBMkTgmjMs+lBLjQm1k+dFbmXK2SuELiDOQLirrl6j15NVBOKn8avvRHXpAQhGX43GOCQ==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.7.2.tgz", + "integrity": "sha512-tNJ7pQjBqXtfASdLRjIYzeI8q0b3JtxqkJbusyEEdLAumpcWkbOvl3Vp9un0Bu/XXWihDa4v2dEdpKxjM+pPxg==", "dependencies": { "@internationalized/number": "^3.5.3", "@internationalized/string": "^3.2.3", - "@react-aria/i18n": "^3.12.1", + "@react-aria/i18n": "^3.12.2", "@react-stately/form": "^3.0.5", - "@react-stately/numberfield": "^3.9.5", - "@react-stately/slider": "^3.5.6", - "@react-stately/utils": "^3.10.2", + "@react-stately/numberfield": "^3.9.6", + "@react-stately/slider": "^3.5.7", + "@react-stately/utils": "^3.10.3", "@react-types/color": "3.0.0-rc.1", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -6250,16 +6249,16 @@ } }, "node_modules/@react-stately/combobox": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.9.1.tgz", - "integrity": "sha512-jmeKUKs0jK18NwDAlpu79ATufgxrc6Sn3ZMmI8KPVQ5sdPTjNlnDx6gTFyOOIa87axf/c6WYU7v3jxmcp+RDdg==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.9.2.tgz", + "integrity": "sha512-ZsbAcD58IvxZqwYxg9d2gOf8R/k5RUB2TPUiGKD6wgWfEKH6SDzY3bgRByHGOyMCyJB62cHjih/ZShizNTguqA==", "dependencies": { "@react-stately/collections": "^3.10.9", "@react-stately/form": "^3.0.5", - "@react-stately/list": "^3.10.7", - "@react-stately/overlays": "^3.6.9", - "@react-stately/select": "^3.6.6", - "@react-stately/utils": "^3.10.2", + "@react-stately/list": "^3.10.8", + "@react-stately/overlays": "^3.6.10", + "@react-stately/select": "^3.6.7", + "@react-stately/utils": "^3.10.3", "@react-types/combobox": "^3.12.1", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -6281,16 +6280,16 @@ } }, "node_modules/@react-stately/datepicker": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.10.1.tgz", - "integrity": "sha512-KXr5cxLOLUYBf3wlDSKhvshsKOWpdV2flhS075V6dgC/EPBh7igBZGUXJ9AZzndT7Hx1w8v/ul6CIffxEJz1Nw==", + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.10.2.tgz", + "integrity": "sha512-pa5IZUw+49AyOnddwu4XwU2kI5eo/1thbiIVNHP8uDpbbBrBkquSk3zVFDAGX1cu/I1U2VUkt64U/dxgkwaMQw==", "dependencies": { "@internationalized/date": "^3.5.5", "@internationalized/string": "^3.2.3", "@react-stately/form": "^3.0.5", - "@react-stately/overlays": "^3.6.9", - "@react-stately/utils": "^3.10.2", - "@react-types/datepicker": "^3.8.1", + "@react-stately/overlays": "^3.6.10", + "@react-stately/utils": "^3.10.3", + "@react-types/datepicker": "^3.8.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -6299,11 +6298,11 @@ } }, "node_modules/@react-stately/dnd": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.4.1.tgz", - "integrity": "sha512-EXPW1vKx3vNpMaXOpPKTOU1T4S+jqjllGFDyWD659Ql0lL9SQ5Y4IU/KmIK3T3yKkjps9xrMmCjLAkb75PH5zg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.4.2.tgz", + "integrity": "sha512-VrHmNoNdVGrx5JHdz/zewmN+N8rlZe+vL/iAOLmvQ74RRLEz8KDFnHdlhgKg1AZqaSg3JJ18BlHEkS7oL1n+tA==", "dependencies": { - "@react-stately/selection": "^3.16.1", + "@react-stately/selection": "^3.16.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -6332,12 +6331,12 @@ } }, "node_modules/@react-stately/grid": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.9.1.tgz", - "integrity": "sha512-LSVIcXO/cqwG0IgDSk2juDbpARBS1IzGnsTp/8vSOejMxq5MXrwxL5hUcqNczL8Ss6aLpELm42tCS0kPm3cMKw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.9.2.tgz", + "integrity": "sha512-2gK//sqAqg2Xaq6UITTFQwFUJnBRgcW+cKBVbFt+F8d152xB6UwwTS/K79E5PUkOotwqZgTEpkrSFs/aVxCLpw==", "dependencies": { "@react-stately/collections": "^3.10.9", - "@react-stately/selection": "^3.16.1", + "@react-stately/selection": "^3.16.2", "@react-types/grid": "^3.2.8", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -6347,13 +6346,13 @@ } }, "node_modules/@react-stately/layout": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-4.0.1.tgz", - "integrity": "sha512-4oNYFhQprcwP1fNV/p3dbx1a6lzMGBAKLTdcvtCuBCgclNA3etqjdQAUIZ0Bpq+Z8i9qo3c85oxr6Tr8BKQV4w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-4.0.2.tgz", + "integrity": "sha512-g3IOrYQcaWxWKW44fYCOLoLMYKEmoOAcT9vQIbgK8MLTQV9Zgt9sGREwn4WJPm85N58Ij6yP72aQ7og/PSymvg==", "dependencies": { "@react-stately/collections": "^3.10.9", - "@react-stately/table": "^3.12.1", - "@react-stately/virtualizer": "^4.0.1", + "@react-stately/table": "^3.12.2", + "@react-stately/virtualizer": "^4.0.2", "@react-types/grid": "^3.2.8", "@react-types/shared": "^3.24.1", "@react-types/table": "^3.10.1", @@ -6364,13 +6363,13 @@ } }, "node_modules/@react-stately/list": { - "version": "3.10.7", - "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.7.tgz", - "integrity": "sha512-W5PG7uG5GQV2Q59vXJE7QLKHZIoUNEx+JmHrBUCMKUgyngSpKIIEDR/R/C1b6ZJ9jMqqZA68Zlnd5iK1/mBi1A==", + "version": "3.10.8", + "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.8.tgz", + "integrity": "sha512-rHCiPLXd+Ry3ztR9DkLA5FPQeH4Zd4/oJAEDWJ77W3oBBOdiMp3ZdHDLP7KBRh17XGNLO/QruYoHWAQTPiMF4g==", "dependencies": { "@react-stately/collections": "^3.10.9", - "@react-stately/selection": "^3.16.1", - "@react-stately/utils": "^3.10.2", + "@react-stately/selection": "^3.16.2", + "@react-stately/utils": "^3.10.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -6379,11 +6378,11 @@ } }, "node_modules/@react-stately/menu": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.8.1.tgz", - "integrity": "sha512-HzAANHg+QUpyRok0CBIL/5qb+4TARteP0q9av2tKnQWPG91iJw84phJDJrmmY55uFFax4fxBgDM9dy1t12iKgQ==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.8.2.tgz", + "integrity": "sha512-lt6hIHmSixMzkKx1rKJf3lbAf01EmEvvIlENL20GLiU9cRbpPnPJ1aJMZ5Ad5ygglA7wAemAx+daPhlTQfF2rg==", "dependencies": { - "@react-stately/overlays": "^3.6.9", + "@react-stately/overlays": "^3.6.10", "@react-types/menu": "^3.9.11", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -6393,13 +6392,13 @@ } }, "node_modules/@react-stately/numberfield": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.5.tgz", - "integrity": "sha512-aWilyzrZOvkgntcXd6Kl+t1QiCbnajUCN8yll6/saByKpfuOf1k6AGYNQBJ0CO/5HyffPPdbFs+45sj4e3cdjA==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.6.tgz", + "integrity": "sha512-p2R9admGLI439qZzB39dyANhkruprJJtZwuoGVtxW/VD0ficw6BrPVqAaKG25iwKPkmveleh9p8o+yRqjGedcQ==", "dependencies": { "@internationalized/number": "^3.5.3", "@react-stately/form": "^3.0.5", - "@react-stately/utils": "^3.10.2", + "@react-stately/utils": "^3.10.3", "@react-types/numberfield": "^3.8.5", "@swc/helpers": "^0.5.0" }, @@ -6408,11 +6407,11 @@ } }, "node_modules/@react-stately/overlays": { - "version": "3.6.9", - "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.9.tgz", - "integrity": "sha512-4chfyzKw7P2UEainm0yzjUgYwG1ovBejN88eTrn+O62x5huuMCwe0cbMxmYh4y7IhRFSee3jIJd0SP0u/+i39w==", + "version": "3.6.10", + "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.10.tgz", + "integrity": "sha512-XxZ2qScT5JPwGk9qiVJE4dtVh3AXTcYwGRA5RsHzC26oyVVsegPqY2PmNJGblAh6Q57VyodoVUyebE0Eo5CzRw==", "dependencies": { - "@react-stately/utils": "^3.10.2", + "@react-stately/utils": "^3.10.3", "@react-types/overlays": "^3.8.9", "@swc/helpers": "^0.5.0" }, @@ -6421,12 +6420,12 @@ } }, "node_modules/@react-stately/radio": { - "version": "3.10.6", - "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.6.tgz", - "integrity": "sha512-wiJuUUQ6LuEv0J1DQtkC0+Sed7tO6y3sIPeB+5uIxIIsUpxvNlDcqr+JOkrQm7gZmkmvcfotb5Gv5PqaIl1zKA==", + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.7.tgz", + "integrity": "sha512-ZwGzFR+sGd42DxRlDTp3G2vLZyhMVtgHkwv2BxazPHxPMvLO9yYl7+3PPNxAmhMB4tg2u9CrzffpGX2rmEJEXA==", "dependencies": { "@react-stately/form": "^3.0.5", - "@react-stately/utils": "^3.10.2", + "@react-stately/utils": "^3.10.3", "@react-types/radio": "^3.8.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -6436,12 +6435,12 @@ } }, "node_modules/@react-stately/searchfield": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.5.tgz", - "integrity": "sha512-rKWIVNbxft5eGGxQ4CtcTKGXm2B1AuYSg6kLRQLq+VYspPNq3wfeMtVBeIdy4LNjWXsTmzs2b3o+zkFYdPqPPw==", + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.6.tgz", + "integrity": "sha512-gVzU0FeWiLYD8VOYRgWlk79Qn7b2eirqOnWhtI5VNuGN8WyNaCIuBp6SkXTW2dY8hs2Hzn8HlMbgy1MIc7130Q==", "dependencies": { - "@react-stately/utils": "^3.10.2", - "@react-types/searchfield": "^3.5.7", + "@react-stately/utils": "^3.10.3", + "@react-types/searchfield": "^3.5.8", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -6449,13 +6448,13 @@ } }, "node_modules/@react-stately/select": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.6.tgz", - "integrity": "sha512-JEpBosWNSXRexE/iReATei1EiVdTIwOWlLcCGw6K7oC/5/f+OHMsh2Kkt/c/RzM/to3vgR+Wbbqwrb712AWgYQ==", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.7.tgz", + "integrity": "sha512-hCUIddw0mPxVy1OH6jhyaDwgNea9wESjf+MYdnnTG/abRB+OZv/dWScd87OjzVsHTHWcw7CN4ZzlJoXm0FJbKQ==", "dependencies": { "@react-stately/form": "^3.0.5", - "@react-stately/list": "^3.10.7", - "@react-stately/overlays": "^3.6.9", + "@react-stately/list": "^3.10.8", + "@react-stately/overlays": "^3.6.10", "@react-types/select": "^3.9.6", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" @@ -6465,12 +6464,12 @@ } }, "node_modules/@react-stately/selection": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.16.1.tgz", - "integrity": "sha512-qmnmYaXY7IhhzmIiInec1a/yPxlPSBHka6vrWddvt0S6zN7FU5cv6sm69ONUwYwLKSoaNHgOGvZhmsTzyV0O2A==", + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.16.2.tgz", + "integrity": "sha512-C4eSKw7BIZHJLPzwqGqCnsyFHiUIEyryVQZTJDt6d0wYBOHU6k1pW+Q4VhrZuzSv+IMiI2RkiXeJKc55f0ZXrg==", "dependencies": { "@react-stately/collections": "^3.10.9", - "@react-stately/utils": "^3.10.2", + "@react-stately/utils": "^3.10.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -6479,11 +6478,11 @@ } }, "node_modules/@react-stately/slider": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.6.tgz", - "integrity": "sha512-a7DZgpOVjQyGzMLPiVRCVHISPJX8E3bT+qbZpcRQN+F7T7wReOwUt2I8gQMosnnCGWgU6kdYk8snn0obXe70Fg==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.7.tgz", + "integrity": "sha512-gEIGTcpBLcXixd8LYiLc8HKrBiGQJltrrEGoOvvTP8KVItXQxmeL+JiSsh8qgOoUdRRpzmAoFNUKGEg2/gtN8A==", "dependencies": { - "@react-stately/utils": "^3.10.2", + "@react-stately/utils": "^3.10.3", "@react-types/shared": "^3.24.1", "@react-types/slider": "^3.7.5", "@swc/helpers": "^0.5.0" @@ -6493,15 +6492,15 @@ } }, "node_modules/@react-stately/table": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.12.1.tgz", - "integrity": "sha512-Cg3lXrWJNrYkD1gqRclMxq0GGiR+ygxdeAqk2jbbsmHU8RSQuzoO/RtUCw6WAKfQjAq4gE0E60TlAsGgCUdJGA==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.12.2.tgz", + "integrity": "sha512-dUcsrdALylhWz6exqIoqtR/dnrzjIAptMyAUPT378Y/mCYs4PxKkHSvtPEQrZhdQS1ALIIgfeg9KUVIempoXPw==", "dependencies": { "@react-stately/collections": "^3.10.9", "@react-stately/flags": "^3.0.3", - "@react-stately/grid": "^3.9.1", - "@react-stately/selection": "^3.16.1", - "@react-stately/utils": "^3.10.2", + "@react-stately/grid": "^3.9.2", + "@react-stately/selection": "^3.16.2", + "@react-stately/utils": "^3.10.3", "@react-types/grid": "^3.2.8", "@react-types/shared": "^3.24.1", "@react-types/table": "^3.10.1", @@ -6512,11 +6511,11 @@ } }, "node_modules/@react-stately/tabs": { - "version": "3.6.8", - "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.8.tgz", - "integrity": "sha512-pLRwnMmXk/IWvbIJYSO5hm3/PiJ/VzrQlwKr6dlOcrDOSVIZpTjnGWHd6mJSDoPiDyBThlN/k3+2pUFMEOAcfw==", + "version": "3.6.9", + "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.9.tgz", + "integrity": "sha512-YZDqZng3HrRX+uXmg6u78x73Oi24G5ICpiXVqDKKDkO333XCA5H8MWItiuPZkYB2h3SbaCaLqSobLkvCoWYpNQ==", "dependencies": { - "@react-stately/list": "^3.10.7", + "@react-stately/list": "^3.10.8", "@react-types/shared": "^3.24.1", "@react-types/tabs": "^3.3.9", "@swc/helpers": "^0.5.0" @@ -6526,11 +6525,11 @@ } }, "node_modules/@react-stately/toggle": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.6.tgz", - "integrity": "sha512-xRZyrjNVu1VCd1xpg5RwmNYs9fXb+JHChoUaRcBmGCCjsPD0R5uR3iNuE17RXJtWS3/8o9IJVn90+/7NW7boOg==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.7.tgz", + "integrity": "sha512-AS+xB4+hHWa3wzYkbS6pwBkovPfIE02B9SnuYTe0stKcuejpWKo5L3QMptW0ftFYsW3ZPCXuneImfObEw2T01A==", "dependencies": { - "@react-stately/utils": "^3.10.2", + "@react-stately/utils": "^3.10.3", "@react-types/checkbox": "^3.8.3", "@swc/helpers": "^0.5.0" }, @@ -6539,11 +6538,11 @@ } }, "node_modules/@react-stately/tooltip": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.11.tgz", - "integrity": "sha512-r1ScIXau2LZ/lUUBQ5PI01S2TB2urF2zrPzNM2xgngFLlG2uTyfIgMga6/035quQQKd3Bd0qGigMvTgZ3GRGEg==", + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.12.tgz", + "integrity": "sha512-QKYT/cze7n9qaBsk7o5ais3jRfhYCzcVRfps+iys/W+/9FFbbhjfQG995Lwi6b+vGOHWfXxXpwmyIO2tzM1Iog==", "dependencies": { - "@react-stately/overlays": "^3.6.9", + "@react-stately/overlays": "^3.6.10", "@react-types/tooltip": "^3.4.11", "@swc/helpers": "^0.5.0" }, @@ -6552,13 +6551,13 @@ } }, "node_modules/@react-stately/tree": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.3.tgz", - "integrity": "sha512-9sRQOxkK7ZMdtSTGHx0sMabHC39PEM4tMl+IdJKkmcp60bfsm3p6LHXhha3E58jwnZaemBfUrlQmTP/E26BbGw==", + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.4.tgz", + "integrity": "sha512-HFNclIXJ/3QdGQWxXbj+tdlmIX/XwCfzAMB5m26xpJ6HtJhia6dtx3GLfcdyHNjmuRbAsTBsAAnnVKBmNRUdIQ==", "dependencies": { "@react-stately/collections": "^3.10.9", - "@react-stately/selection": "^3.16.1", - "@react-stately/utils": "^3.10.2", + "@react-stately/selection": "^3.16.2", + "@react-stately/utils": "^3.10.3", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -6567,9 +6566,9 @@ } }, "node_modules/@react-stately/utils": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.2.tgz", - "integrity": "sha512-fh6OTQtbeQC0ywp6LJuuKs6tKIgFvt/DlIZEcIpGho6/oZG229UnIk6TUekwxnDbumuYyan6D9EgUtEMmT8UIg==", + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.3.tgz", + "integrity": "sha512-moClv7MlVSHpbYtQIkm0Cx+on8Pgt1XqtPx6fy9rQFb2DNc9u1G3AUVnqA17buOkH1vLxAtX4MedlxMWyRCYYA==", "dependencies": { "@swc/helpers": "^0.5.0" }, @@ -6578,11 +6577,11 @@ } }, "node_modules/@react-stately/virtualizer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-4.0.1.tgz", - "integrity": "sha512-HCje3SlLItQFAiBHH4JZhz74mMCe2g+Q8woJa6kdKlvFqsNdmhtFHuuIr1uW6LWj76j2N0Xaa8Z7fV1f5ovX0Q==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-4.0.2.tgz", + "integrity": "sha512-LiSr6E6OoL/cKVFO088zEzkNGj41g02nlOAgLluYONncNEjoYiHmb8Yw0otPgViVLKiFjO6Kk4W+dbt8EZ51Ag==", "dependencies": { - "@react-aria/utils": "^3.25.1", + "@react-aria/utils": "^3.25.2", "@react-types/shared": "^3.24.1", "@swc/helpers": "^0.5.0" }, @@ -6669,9 +6668,9 @@ } }, "node_modules/@react-types/calendar": { - "version": "3.4.8", - "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.8.tgz", - "integrity": "sha512-KVampt/X4uJvWU0TsxIdgPdXIAUClGtxcDWHzuFRJ7YUYkA4rH8Lad0kQ1mVehnwOLpuba8j9GCYKorkbln0gw==", + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.9.tgz", + "integrity": "sha512-O/PS9c21HgO9qzxOyZ7/dTccxabFZdF6tj3UED4DrBw7AN3KZ7JMzwzYbwHinOcO7nUcklGgNoAIHk45UAKR9g==", "dependencies": { "@internationalized/date": "^3.5.5", "@react-types/shared": "^3.24.1" @@ -6727,12 +6726,12 @@ } }, "node_modules/@react-types/datepicker": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.8.1.tgz", - "integrity": "sha512-ZpxHHVT3rmZ4YsYP4TWCZSMSfOUm+067mZyyGLmvHxg55eYmctiB4uMgrRCqDoeiSiOjtxad0VtpPjf6ftK1GQ==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.8.2.tgz", + "integrity": "sha512-Ih4F0bNVGrEuwCD8XmmBAspuuOBsj/Svn/pDFtC2RyAZjXfWh+sI+n4XLz/sYKjvARh5TUI8GNy9smYS4vYXug==", "dependencies": { "@internationalized/date": "^3.5.5", - "@react-types/calendar": "^3.4.8", + "@react-types/calendar": "^3.4.9", "@react-types/overlays": "^3.8.9", "@react-types/shared": "^3.24.1" }, @@ -6930,12 +6929,12 @@ } }, "node_modules/@react-types/searchfield": { - "version": "3.5.7", - "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.7.tgz", - "integrity": "sha512-dyuPwNWGswRZfb4i50Q1Q3tCwTBxRLkrAxcMs+Rf2Rl4t93bawBdSdIQuvxu1KEhgd0EXA9ZUW53ZplqfVmtiw==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.8.tgz", + "integrity": "sha512-EcdqalHNIC6BJoRfmqUhAvXRd3aHkWlV1cFCz57JJKgUEFYyXPNrXd1b73TKLzTXEk+X/D6LKV15ILYpEaxu8w==", "dependencies": { "@react-types/shared": "^3.24.1", - "@react-types/textfield": "^3.9.5" + "@react-types/textfield": "^3.9.6" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" @@ -7028,9 +7027,9 @@ } }, "node_modules/@react-types/textfield": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.5.tgz", - "integrity": "sha512-0hwZI4WXSEStPzdltKwbNUZWlgHtwbxMWE0LfqIzEW8RB7DyBflYSKzLyTBFqwUZ8j3C1gWy9c9OPSeCOq792Q==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.6.tgz", + "integrity": "sha512-0uPqjJh4lYp1aL1HL9IlV8Cgp8eT0PcsNfdoCktfkLytvvBPmox2Pfm57W/d0xTtzZu2CjxhYNTob+JtGAOeXA==", "dependencies": { "@react-types/shared": "^3.24.1" }, @@ -9473,11 +9472,11 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.14.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz", - "integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==", + "version": "22.4.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.2.tgz", + "integrity": "sha512-nAvM3Ey230/XzxtyDcJ+VjvlzpzoHwLsF7JaDRfoI0ytO0mVheerNmM45CtA0yOILXwXXxOrcUWH3wltX+7PSw==", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/node-fetch": { @@ -9610,9 +9609,9 @@ } }, "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz", + "integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -9637,17 +9636,6 @@ "@types/reactcss": "*" } }, - "node_modules/@types/react-datepicker": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-6.2.0.tgz", - "integrity": "sha512-+JtO4Fm97WLkJTH8j8/v3Ldh7JCNRwjMYjRaKh4KHH0M3jJoXtwiD3JBCsdlg3tsFIw9eQSqyAPeVDN2H2oM9Q==", - "dev": true, - "dependencies": { - "@floating-ui/react": "^0.26.2", - "@types/react": "*", - "date-fns": "^3.3.1" - } - }, "node_modules/@types/react-dom": { "version": "18.3.0", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", @@ -9876,9 +9864,9 @@ "dev": true }, "node_modules/@types/web": { - "version": "0.0.151", - "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.151.tgz", - "integrity": "sha512-16wxPnfTZLPZdIjtNDmw1/BGxeV/gfhI9dfIhCIfg95nVkNchkoYxH3bywRo+R/UQYxPNzpZdDuTdiwlUfYEQA==" + "version": "0.0.155", + "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.155.tgz", + "integrity": "sha512-rLQhlzDvG+hAgozeVIObiFrkL6X0X8vOYq88O7llQqT41j7spvZKRocMv4EC5ZuweoAMnmlOE/y1pOdV+ZaiRQ==" }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", @@ -9952,31 +9940,31 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", - "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.2.0.tgz", + "integrity": "sha512-02tJIs655em7fvt9gps/+4k4OsKULYGtLBPJfOsmOq1+3cdClYiF0+d6mHu6qDnTcg88wJBkcPLpQhq7FyDz0A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/type-utils": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/scope-manager": "8.2.0", + "@typescript-eslint/type-utils": "8.2.0", + "@typescript-eslint/utils": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -9985,25 +9973,25 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", - "dependencies": { - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.2.0.tgz", + "integrity": "sha512-j3Di+o0lHgPrb7FxL3fdEy6LJ/j2NE8u+AP/5cQ9SKb+JLH6V6UHDqJ+e0hXBkHP1wn1YDFjYCS9LBQsZDlDEg==", + "dependencies": { + "@typescript-eslint/scope-manager": "8.2.0", + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/typescript-estree": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -10012,15 +10000,15 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.2.0.tgz", + "integrity": "sha512-OFn80B38yD6WwpoHU2Tz/fTz7CgFqInllBoC3WP+/jLbTb4gGPTy9HBSTsbDWkMdN55XlVU0mMDYAtgvlUspGw==", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -10028,26 +10016,23 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", - "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.2.0.tgz", + "integrity": "sha512-g1CfXGFMQdT5S+0PSO0fvGXUaiSkl73U1n9LTK5aRAFnPlJ8dLKkXr4AaLFvPedW8lVDoMgLLE3JN98ZZfsj0w==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/typescript-estree": "8.2.0", + "@typescript-eslint/utils": "8.2.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -10055,11 +10040,11 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.2.0.tgz", + "integrity": "sha512-6a9QSK396YqmiBKPkJtxsgZZZVjYQ6wQ/TlI0C65z7vInaETuC6HAHD98AGLC8DyIPqHytvNuS8bBVvNLKyqvQ==", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -10067,12 +10052,12 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.2.0.tgz", + "integrity": "sha512-kiG4EDUT4dImplOsbh47B1QnNmXSoUqOjWDvCJw/o8LgfD0yr7k2uy54D5Wm0j4t71Ge1NkynGhpWdS0dEIAUA==", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -10081,7 +10066,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -10105,37 +10090,37 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.2.0.tgz", + "integrity": "sha512-O46eaYKDlV3TvAVDNcoDzd5N550ckSe8G4phko++OCSC1dYIb9LTc3HDGYdWqWIAT5qDUKphO6sd9RrpIJJPfg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" + "@typescript-eslint/scope-manager": "8.2.0", + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/typescript-estree": "8.2.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.2.0.tgz", + "integrity": "sha512-sbgsPMW9yLvS7IhCi8IpuK1oBmtbWUNP+hBdwl/I9nzqVsszGnNGti5r9dUtF5RLivHUFFIdRvLiTsPhzSyJ3Q==", "dependencies": { - "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/types": "8.2.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -11045,9 +11030,9 @@ } }, "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" }, "node_modules/asynckit": { "version": "0.4.0", @@ -15056,9 +15041,9 @@ "dev": true }, "node_modules/chart.js": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", - "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", + "integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==", "dependencies": { "@kurkle/color": "^0.3.0" }, @@ -15752,9 +15737,9 @@ } }, "node_modules/core-js": { - "version": "3.38.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.0.tgz", - "integrity": "sha512-XPpwqEodRljce9KswjZShh95qJ1URisBeKCjUdq27YdenkslVe7OO0ZJhlYXAChW7OhXaRLl8AAba7IBfoIHug==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz", + "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -15762,9 +15747,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.38.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.0.tgz", - "integrity": "sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", "dependencies": { "browserslist": "^4.23.3" }, @@ -15774,9 +15759,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.38.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.0.tgz", - "integrity": "sha512-8balb/HAXo06aHP58mZMtXgD8vcnXz9tUDePgqBgJgKdmTlMt+jw3ujqniuBDQXMvTzxnMpxHFeuSM3g1jWQuQ==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.1.tgz", + "integrity": "sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -16674,9 +16659,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.12", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz", - "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==" + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" }, "node_modules/debug": { "version": "4.3.6", @@ -17260,9 +17245,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.8.tgz", - "integrity": "sha512-4Nx0gP2tPNBLTrFxBMHpkQbtn2hidPVr/+/FTtcCiBYTucqc70zRyVZiOLj17Ui3wTO7SQ1/N+hkHYzJjBzt6A==" + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.12.tgz", + "integrity": "sha512-tIhPkdlEoCL1Y+PToq3zRNehUaKp3wBX/sr7aclAWdIWjvqAe/Im/H0SiCM4c1Q8BLPHCdoJTol+ZblflydehA==" }, "node_modules/elkjs": { "version": "0.9.3", @@ -20319,6 +20304,14 @@ "node": ">= 12.20" } }, + "node_modules/formdata-node/node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" + } + }, "node_modules/formidable": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz", @@ -20925,9 +20918,9 @@ "integrity": "sha512-sIVQCiRWOymHbVD1Aw/T9/ijbPYAVGBlgGYd1N9MRKfcyBNSpjr87Vg9nSHm+RCT8ELrvK8IJYJV0QRJuVUkCQ==" }, "node_modules/google-auth-library": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.13.0.tgz", - "integrity": "sha512-p9Y03Uzp/Igcs36zAaB0XTSwZ8Y0/tpYiz5KIde5By+H9DCVUSYtDWZu6aFXsWTqENMb8BD/pDT3hR8NVrPkfA==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.0.tgz", + "integrity": "sha512-Y/eq+RWVs55Io/anIsm24sDS8X79Tq948zVLGaa7+KlJYYqaGwp1YI37w48nzrNi12RgnzMrQD4NzdmCowT90g==", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", @@ -20953,9 +20946,9 @@ } }, "node_modules/googleapis": { - "version": "140.0.1", - "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-140.0.1.tgz", - "integrity": "sha512-ZGvBX4mQcFXO9ACnVNg6Aqy3KtBPB5zTuue43YVLxwn8HSv8jB7w+uDKoIPSoWuxGROgnj2kbng6acXncOQRNA==", + "version": "142.0.0", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-142.0.0.tgz", + "integrity": "sha512-LsU1ynez4/KNPwnFMSDI93pBEsETNdQPCrT3kz2qgiNg5H2pW4dKW+1VmENMkZ4u9lMxA89nnXD3nqWBJ0rruQ==", "dependencies": { "google-auth-library": "^9.0.0", "googleapis-common": "^7.0.0" @@ -24411,9 +24404,9 @@ } }, "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", @@ -34229,9 +34222,9 @@ } }, "node_modules/openai": { - "version": "4.55.7", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.55.7.tgz", - "integrity": "sha512-I2dpHTINt0Zk+Wlns6KzkKu77MmNW3VfIIQf5qYziEUI6t7WciG1zTobfKqdPzBmZi3TTM+3DtjPumxQdcvzwA==", + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.56.0.tgz", + "integrity": "sha512-zcag97+3bG890MNNa0DQD9dGmmTWL8unJdNkulZzWRXrl+QeD+YkBI4H58rJcwErxqGK6a0jVPZ4ReJjhDGcmw==", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", @@ -34254,9 +34247,9 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.44", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.44.tgz", - "integrity": "sha512-ZsbGerYg72WMXUIE9fYxtvfzLEuq6q8mKERdWFnqTmOvudMxnz+CBNRoOwJ2kNpFOncrKjT1hZwxjlFgQ9qvQA==", + "version": "18.19.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.45.tgz", + "integrity": "sha512-VZxPKNNhjKmaC1SUYowuXSRSMGyQGmQjvvA1xE4QZ0xce2kLtEhPDS+kqpCPBZYgqblCLQ2DAjSzmgCM5auvhA==", "dependencies": { "undici-types": "~5.26.4" } @@ -34266,6 +34259,11 @@ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" }, + "node_modules/openai/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/opentype.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz", @@ -35292,9 +35290,9 @@ } }, "node_modules/prosemirror-view": { - "version": "1.33.10", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.10.tgz", - "integrity": "sha512-wsKg9JeQkWlkXG8DDcloI/tbB9r3CysziubigoC8wTuE6zobN/9cl8bGRk1J1XjkUp7rxGBziOSxrhoILL84hg==", + "version": "1.33.11", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.11.tgz", + "integrity": "sha512-K0z9oMf6EI2ZifS9yW8PUPjEw2o1ZoFAaNzvcuyfcjIzsU6pJMo3tk9r26MyzEsuGHXZwmKPEmrjgFd78biTGA==", "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -35689,46 +35687,46 @@ } }, "node_modules/react-aria": { - "version": "3.34.1", - "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.34.1.tgz", - "integrity": "sha512-vA4BP+SWjFFRfOTQcNJtIp9gKlxuC7kPUXQK9fuNA+2K4mJdIc9mBnmwXQiLl/eAthMf43fD4fETfY9SiCm1Zg==", + "version": "3.34.3", + "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.34.3.tgz", + "integrity": "sha512-wSprEI5EojDFCm357MxnKAxJZN68OYIt6UH6N0KCo6MEUAVZMbhMSmGYjw/kLK4rI7KrbJDqGqUMQkwc93W9Ng==", "dependencies": { "@internationalized/string": "^3.2.3", - "@react-aria/breadcrumbs": "^3.5.15", - "@react-aria/button": "^3.9.7", - "@react-aria/calendar": "^3.5.10", - "@react-aria/checkbox": "^3.14.5", - "@react-aria/combobox": "^3.10.1", - "@react-aria/datepicker": "^3.11.1", - "@react-aria/dialog": "^3.5.16", - "@react-aria/dnd": "^3.7.1", - "@react-aria/focus": "^3.18.1", - "@react-aria/gridlist": "^3.9.1", - "@react-aria/i18n": "^3.12.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/label": "^3.7.10", - "@react-aria/link": "^3.7.3", - "@react-aria/listbox": "^3.13.1", - "@react-aria/menu": "^3.15.1", - "@react-aria/meter": "^3.4.15", - "@react-aria/numberfield": "^3.11.5", - "@react-aria/overlays": "^3.23.1", - "@react-aria/progress": "^3.4.15", - "@react-aria/radio": "^3.10.6", - "@react-aria/searchfield": "^3.7.7", - "@react-aria/select": "^3.14.7", - "@react-aria/selection": "^3.19.1", - "@react-aria/separator": "^3.4.1", - "@react-aria/slider": "^3.7.10", + "@react-aria/breadcrumbs": "^3.5.16", + "@react-aria/button": "^3.9.8", + "@react-aria/calendar": "^3.5.11", + "@react-aria/checkbox": "^3.14.6", + "@react-aria/combobox": "^3.10.3", + "@react-aria/datepicker": "^3.11.2", + "@react-aria/dialog": "^3.5.17", + "@react-aria/dnd": "^3.7.2", + "@react-aria/focus": "^3.18.2", + "@react-aria/gridlist": "^3.9.3", + "@react-aria/i18n": "^3.12.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/label": "^3.7.11", + "@react-aria/link": "^3.7.4", + "@react-aria/listbox": "^3.13.3", + "@react-aria/menu": "^3.15.3", + "@react-aria/meter": "^3.4.16", + "@react-aria/numberfield": "^3.11.6", + "@react-aria/overlays": "^3.23.2", + "@react-aria/progress": "^3.4.16", + "@react-aria/radio": "^3.10.7", + "@react-aria/searchfield": "^3.7.8", + "@react-aria/select": "^3.14.9", + "@react-aria/selection": "^3.19.3", + "@react-aria/separator": "^3.4.2", + "@react-aria/slider": "^3.7.11", "@react-aria/ssr": "^3.9.5", - "@react-aria/switch": "^3.6.6", - "@react-aria/table": "^3.15.1", - "@react-aria/tabs": "^3.9.3", - "@react-aria/tag": "^3.4.3", - "@react-aria/textfield": "^3.14.7", - "@react-aria/tooltip": "^3.7.6", - "@react-aria/utils": "^3.25.1", - "@react-aria/visually-hidden": "^3.8.14", + "@react-aria/switch": "^3.6.7", + "@react-aria/table": "^3.15.3", + "@react-aria/tabs": "^3.9.5", + "@react-aria/tag": "^3.4.5", + "@react-aria/textfield": "^3.14.8", + "@react-aria/tooltip": "^3.7.7", + "@react-aria/utils": "^3.25.2", + "@react-aria/visually-hidden": "^3.8.15", "@react-types/shared": "^3.24.1" }, "peerDependencies": { @@ -35737,28 +35735,28 @@ } }, "node_modules/react-aria-components": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.3.1.tgz", - "integrity": "sha512-yUTA8uHbioQHU5d7iNvSLZLEfQlcTAmyhhkY+NMc8pIGPdtf0qnrlF0nPtJq8Mro5irpVrgUlqKBvvCiKwFNiQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.3.3.tgz", + "integrity": "sha512-wNjcoyIFTL14Z07OJ1I5m37CYB+1oH2DW8PIgZQjGt9lLcYKKEBLSgsenHVKu1F1L9tqlpXgYk5TeXCzU/xUKw==", "dependencies": { "@internationalized/date": "^3.5.5", "@internationalized/string": "^3.2.3", - "@react-aria/collections": "3.0.0-alpha.3", - "@react-aria/color": "3.0.0-rc.1", - "@react-aria/dnd": "^3.7.1", - "@react-aria/focus": "^3.18.1", - "@react-aria/interactions": "^3.22.1", - "@react-aria/menu": "^3.15.1", - "@react-aria/toolbar": "3.0.0-beta.7", - "@react-aria/tree": "3.0.0-alpha.3", - "@react-aria/utils": "^3.25.1", - "@react-aria/virtualizer": "^4.0.1", - "@react-stately/color": "^3.7.1", - "@react-stately/layout": "^4.0.1", - "@react-stately/menu": "^3.8.1", - "@react-stately/table": "^3.12.1", - "@react-stately/utils": "^3.10.2", - "@react-stately/virtualizer": "^4.0.1", + "@react-aria/collections": "3.0.0-alpha.4", + "@react-aria/color": "3.0.0-rc.2", + "@react-aria/dnd": "^3.7.2", + "@react-aria/focus": "^3.18.2", + "@react-aria/interactions": "^3.22.2", + "@react-aria/menu": "^3.15.3", + "@react-aria/toolbar": "3.0.0-beta.8", + "@react-aria/tree": "3.0.0-alpha.5", + "@react-aria/utils": "^3.25.2", + "@react-aria/virtualizer": "^4.0.2", + "@react-stately/color": "^3.7.2", + "@react-stately/layout": "^4.0.2", + "@react-stately/menu": "^3.8.2", + "@react-stately/table": "^3.12.2", + "@react-stately/utils": "^3.10.3", + "@react-stately/virtualizer": "^4.0.2", "@react-types/color": "3.0.0-rc.1", "@react-types/form": "^3.7.6", "@react-types/grid": "^3.2.8", @@ -35766,8 +35764,8 @@ "@react-types/table": "^3.10.1", "@swc/helpers": "^0.5.0", "client-only": "^0.0.1", - "react-aria": "^3.34.1", - "react-stately": "^3.32.1", + "react-aria": "^3.34.3", + "react-stately": "^3.32.2", "use-sync-external-store": "^1.2.0" }, "peerDependencies": { @@ -36125,32 +36123,32 @@ } }, "node_modules/react-stately": { - "version": "3.32.1", - "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.32.1.tgz", - "integrity": "sha512-znw+bqHJk1fvv34O3HoVH61otyYJomRu1gI7A4B3UHCnSFS6E6nMI6D3nRv9RrAWhf4ekLLg35FwDTHDcG1zdg==", + "version": "3.32.2", + "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.32.2.tgz", + "integrity": "sha512-pDSrbCIJtir4HeSa//PTqLSR7Tl7pFC9usmkkBObNKktObQq3Vdgkf46cxeTD1ov7J7GDdR3meIyjXGnZoEzUg==", "dependencies": { - "@react-stately/calendar": "^3.5.3", - "@react-stately/checkbox": "^3.6.7", + "@react-stately/calendar": "^3.5.4", + "@react-stately/checkbox": "^3.6.8", "@react-stately/collections": "^3.10.9", - "@react-stately/combobox": "^3.9.1", + "@react-stately/combobox": "^3.9.2", "@react-stately/data": "^3.11.6", - "@react-stately/datepicker": "^3.10.1", - "@react-stately/dnd": "^3.4.1", + "@react-stately/datepicker": "^3.10.2", + "@react-stately/dnd": "^3.4.2", "@react-stately/form": "^3.0.5", - "@react-stately/list": "^3.10.7", - "@react-stately/menu": "^3.8.1", - "@react-stately/numberfield": "^3.9.5", - "@react-stately/overlays": "^3.6.9", - "@react-stately/radio": "^3.10.6", - "@react-stately/searchfield": "^3.5.5", - "@react-stately/select": "^3.6.6", - "@react-stately/selection": "^3.16.1", - "@react-stately/slider": "^3.5.6", - "@react-stately/table": "^3.12.1", - "@react-stately/tabs": "^3.6.8", - "@react-stately/toggle": "^3.7.6", - "@react-stately/tooltip": "^3.4.11", - "@react-stately/tree": "^3.8.3", + "@react-stately/list": "^3.10.8", + "@react-stately/menu": "^3.8.2", + "@react-stately/numberfield": "^3.9.6", + "@react-stately/overlays": "^3.6.10", + "@react-stately/radio": "^3.10.7", + "@react-stately/searchfield": "^3.5.6", + "@react-stately/select": "^3.6.7", + "@react-stately/selection": "^3.16.2", + "@react-stately/slider": "^3.5.7", + "@react-stately/table": "^3.12.2", + "@react-stately/tabs": "^3.6.9", + "@react-stately/toggle": "^3.7.7", + "@react-stately/tooltip": "^3.4.12", + "@react-stately/tree": "^3.8.4", "@react-types/shared": "^3.24.1" }, "peerDependencies": { @@ -36509,9 +36507,9 @@ } }, "node_modules/rehype-katex": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz", - "integrity": "sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", "dependencies": { "@types/hast": "^3.0.0", "@types/katex": "^0.16.0", @@ -37755,9 +37753,9 @@ } }, "node_modules/sass-loader": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.2.1.tgz", - "integrity": "sha512-G0VcnMYU18a4N7VoNDegg2OuMjYtxnqzQWARVWCIVSZwJeiL9kg8QMsuIZOplsJgTzZLF6jGxI3AClj8I9nRdQ==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.1.tgz", + "integrity": "sha512-xACl1ToTsKnL9Ce5yYpRxrLj9QUDCnwZNhzpC7tKiFyA8zXsd3Ap+HGVnbCgkdQcm43E+i6oKAWBsvGA6ZoiMw==", "dependencies": { "neo-async": "^2.6.2" }, @@ -40400,9 +40398,9 @@ } }, "node_modules/type-fest": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.24.0.tgz", - "integrity": "sha512-spAaHzc6qre0TlZQQ2aA/nGMe+2Z/wyGk5Z+Ru2VUfdNwT6kWO6TjevOlpebsATEG1EIQ2sOiDszud3lO5mt/Q==", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.25.0.tgz", + "integrity": "sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==", "engines": { "node": ">=16" }, @@ -40513,25 +40511,22 @@ "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==" }, "node_modules/typescript-eslint": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.18.0.tgz", - "integrity": "sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.2.0.tgz", + "integrity": "sha512-DmnqaPcML0xYwUzgNbM1XaKXpEb7BShYf2P1tkUmmcl8hyeG7Pj08Er7R9bNy6AufabywzJcOybQAtnD/c9DGw==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "7.18.0", - "@typescript-eslint/parser": "7.18.0", - "@typescript-eslint/utils": "7.18.0" + "@typescript-eslint/eslint-plugin": "8.2.0", + "@typescript-eslint/parser": "8.2.0", + "@typescript-eslint/utils": "8.2.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -40609,9 +40604,9 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -41333,11 +41328,13 @@ } }, "node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", + "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", + "optional": true, + "peer": true, "engines": { - "node": ">= 14" + "node": ">= 8" } }, "node_modules/web-worker": { @@ -41471,9 +41468,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.3.0.tgz", - "integrity": "sha512-xD2qnNew+F6KwOGZR7kWdbIou/ud7cVqLEXeK1q0nHcNsX/u7ul/fSdlOTX4ntSL5FNFy7ZJJXbf0piF591JYw==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.1.tgz", + "integrity": "sha512-/t6KpZw/bnmCR0VKILjJT05mWecbf1aIM2VxCJUvBbg0iXqaQJFxbJ4PCrsY4iBH7PGwnccm4BYyoP1G+lGfAA==", "dependencies": { "colorette": "^2.0.10", "memfs": "^4.6.0", diff --git a/package.json b/package.json index 302831bd2..17e349428 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@types/libxmljs": "^0.18.12", "@types/lodash": "^4.14.202", "@types/mocha": "^10.0.6", - "@types/node": "^20.10.3", + "@types/node": "^22.4.2", "@types/nodemailer": "^6.4.14", "@types/passport": "^1.0.16", "@types/passport-google-oauth20": "^2.0.14", @@ -56,7 +56,6 @@ "@types/react": "^18.2.41", "@types/react-autosuggest": "^10.1.10", "@types/react-color": "^3.0.10", - "@types/react-datepicker": "^6.2.0", "@types/react-dom": "^18.2.17", "@types/react-grid-layout": "^1.3.5", "@types/react-measure": "^2.0.12", @@ -93,7 +92,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", - "typescript-eslint": "^7.8.0", + "typescript-eslint": "^8.2.0", "webpack-dev-server": "^5.0.4" }, "dependencies": { @@ -139,9 +138,9 @@ "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/textfit": "^2.4.4", - "@types/web": "^0.0.151", + "@types/web": "^0.0.155", "@types/webpack-hot-middleware": "^2.25.9", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/parser": "^8.2.0", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", "archiver": "^7.0.1", @@ -205,7 +204,7 @@ "function-plot": "^1.23.3", "golden-layout": "^2.6.0", "google-auth-library": "^9.4.1", - "googleapis": "^140.0.1", + "googleapis": "^142.0.0", "googlephotos": "^0.3.5", "got": "^14.0.0", "howler": "^2.2.4", @@ -300,7 +299,7 @@ "reveal.js": "^5.0.2", "rimraf": "^6.0.0", "sass": "^1.69.5", - "sass-loader": "^14.2.0", + "sass-loader": "^16.0.1", "serializr": "^3.0.2", "shelljs": "^0.8.5", "socket.io": "^4.7.2", -- cgit v1.2.3-70-g09d2 From 77aa0be0ee4a5375544dbea65a4636d8487cd0fc Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Aug 2024 23:44:13 -0400 Subject: revert eslint to pre-9 --- .eslintrc.json | 4 +- package-lock.json | 169 +++++++++++++++++++++++++++++++++--------------------- package.json | 4 +- 3 files changed, 109 insertions(+), 68 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index d4f43f04c..aba260657 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -39,8 +39,8 @@ "node/no-unsupported-features/es-syntax": ["error", { "ignores": ["modules"] }], "react/jsx-filename-extension": [2, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }], "import/prefer-default-export": "off", - "no-unused-expressions": "off", - "@typescript-eslint/no-unused-expressions": "off", + "no-unused-expressions": "warn", + "@typescript-eslint/no-unused-expressions": "warn", "prefer-template": "off", "no-inner-declarations": "off", "no-plusplus": "off", diff --git a/package-lock.json b/package-lock.json index 0e43875f4..94e10fa4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "@types/textfit": "^2.4.4", "@types/web": "^0.0.155", "@types/webpack-hot-middleware": "^2.25.9", - "@typescript-eslint/parser": "^8.2.0", + "@typescript-eslint/parser": "^7.8.0", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", "archiver": "^7.0.1", @@ -316,7 +316,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", - "typescript-eslint": "^8.2.0", + "typescript-eslint": "^7.8.0", "webpack-dev-server": "^5.0.4" }, "engines": { @@ -9781,6 +9781,12 @@ "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz", "integrity": "sha512-YvMLqFak/7rt//lPBtEHv3M4sRNA+HGxrhFZ+DQs9K2IkYJbNwVIb8avtJfhDiuaUBX/AW0jnjv48FV8h3u9bQ==" }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -9986,31 +9992,33 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.2.0.tgz", - "integrity": "sha512-02tJIs655em7fvt9gps/+4k4OsKULYGtLBPJfOsmOq1+3cdClYiF0+d6mHu6qDnTcg88wJBkcPLpQhq7FyDz0A==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", + "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.2.0", - "@typescript-eslint/type-utils": "8.2.0", - "@typescript-eslint/utils": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/type-utils": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", + "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -10018,26 +10026,38 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/parser": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.2.0.tgz", - "integrity": "sha512-j3Di+o0lHgPrb7FxL3fdEy6LJ/j2NE8u+AP/5cQ9SKb+JLH6V6UHDqJ+e0hXBkHP1wn1YDFjYCS9LBQsZDlDEg==", - "dependencies": { - "@typescript-eslint/scope-manager": "8.2.0", - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/typescript-estree": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", + "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "dependencies": { + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -10046,15 +10066,15 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.2.0.tgz", - "integrity": "sha512-OFn80B38yD6WwpoHU2Tz/fTz7CgFqInllBoC3WP+/jLbTb4gGPTy9HBSTsbDWkMdN55XlVU0mMDYAtgvlUspGw==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", + "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", "dependencies": { - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0" + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -10062,23 +10082,26 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.2.0.tgz", - "integrity": "sha512-g1CfXGFMQdT5S+0PSO0fvGXUaiSkl73U1n9LTK5aRAFnPlJ8dLKkXr4AaLFvPedW8lVDoMgLLE3JN98ZZfsj0w==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", + "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.2.0", - "@typescript-eslint/utils": "8.2.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/utils": "7.8.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "^8.56.0" + }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -10086,11 +10109,11 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.2.0.tgz", - "integrity": "sha512-6a9QSK396YqmiBKPkJtxsgZZZVjYQ6wQ/TlI0C65z7vInaETuC6HAHD98AGLC8DyIPqHytvNuS8bBVvNLKyqvQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", + "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -10098,12 +10121,12 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.2.0.tgz", - "integrity": "sha512-kiG4EDUT4dImplOsbh47B1QnNmXSoUqOjWDvCJw/o8LgfD0yr7k2uy54D5Wm0j4t71Ge1NkynGhpWdS0dEIAUA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", + "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", "dependencies": { - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -10112,7 +10135,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -10136,37 +10159,52 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.2.0.tgz", - "integrity": "sha512-O46eaYKDlV3TvAVDNcoDzd5N550ckSe8G4phko++OCSC1dYIb9LTc3HDGYdWqWIAT5qDUKphO6sd9RrpIJJPfg==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", + "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.2.0", - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/typescript-estree": "8.2.0" + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "semver": "^7.6.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.2.0.tgz", - "integrity": "sha512-sbgsPMW9yLvS7IhCi8IpuK1oBmtbWUNP+hBdwl/I9nzqVsszGnNGti5r9dUtF5RLivHUFFIdRvLiTsPhzSyJ3Q==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", + "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", "dependencies": { - "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/types": "7.8.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -40581,22 +40619,25 @@ "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==" }, "node_modules/typescript-eslint": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.2.0.tgz", - "integrity": "sha512-DmnqaPcML0xYwUzgNbM1XaKXpEb7BShYf2P1tkUmmcl8hyeG7Pj08Er7R9bNy6AufabywzJcOybQAtnD/c9DGw==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.8.0.tgz", + "integrity": "sha512-sheFG+/D8N/L7gC3WT0Q8sB97Nm573Yfr+vZFzl/4nBdYcmviBPtwGSX9TJ7wpVg28ocerKVOt+k2eGmHzcgVA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.2.0", - "@typescript-eslint/parser": "8.2.0", - "@typescript-eslint/utils": "8.2.0" + "@typescript-eslint/eslint-plugin": "7.8.0", + "@typescript-eslint/parser": "7.8.0", + "@typescript-eslint/utils": "7.8.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "^8.56.0" + }, "peerDependenciesMeta": { "typescript": { "optional": true diff --git a/package.json b/package.json index 6595a1599..fe9f37923 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", - "typescript-eslint": "^8.2.0", + "typescript-eslint": "^7.8.0", "webpack-dev-server": "^5.0.4" }, "dependencies": { @@ -140,7 +140,7 @@ "@types/textfit": "^2.4.4", "@types/web": "^0.0.155", "@types/webpack-hot-middleware": "^2.25.9", - "@typescript-eslint/parser": "^8.2.0", + "@typescript-eslint/parser": "^7.8.0", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", "archiver": "^7.0.1", -- cgit v1.2.3-70-g09d2 From 166d40bd856b85bd4bbde9f9ffe2c1ec0fb648d5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Aug 2024 10:57:53 -0400 Subject: more lint fixes after update --- eslint.config.mjs | 45 ++++++++++++++++++++++++- package-lock.json | 46 ++++++++++---------------- src/ClientUtils.ts | 1 - src/ServerUtils.ts | 1 - src/client/Network.ts | 2 +- src/client/documents/DocUtils.ts | 3 +- src/client/documents/Documents.ts | 4 +-- src/client/util/DictationManager.ts | 4 --- src/client/util/DragManager.ts | 1 - src/client/util/History.ts | 1 - src/client/util/InteractionUtils.tsx | 1 - src/client/util/ScriptingGlobals.ts | 2 +- src/client/util/SearchUtil.ts | 1 - src/client/util/SerializationHelper.ts | 1 - src/client/util/UndoManager.ts | 1 - src/client/views/DocViewUtils.ts | 1 - src/pen-gestures/GestureUtils.ts | 1 - src/server/DashStats.ts | 2 +- src/server/DashUploadUtils.ts | 1 - src/server/Message.ts | 1 - src/server/Search.ts | 1 - src/server/SharedMediaTypes.ts | 2 -- src/server/apis/google/GoogleApiServerUtils.ts | 2 +- src/server/server_Initialization.ts | 9 +++++ src/server/websocket.ts | 1 - 25 files changed, 77 insertions(+), 58 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index b35601abd..04655ce13 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -3,4 +3,47 @@ import pluginReactConfig from 'eslint-plugin-react/configs/recommended.js'; import globals from 'globals'; import tseslint from 'typescript-eslint'; -export default [{ languageOptions: { globals: { ...globals.browser, ...globals.node } } }, pluginJs.configs.recommended, ...tseslint.configs.recommended, pluginReactConfig]; +export default [ + { + languageOptions: { globals: { ...globals.browser, ...globals.node } }, + }, + pluginJs.configs.recommended, + ...tseslint.configs.recommended, + { + rules: { + 'node/no-missing-import': 0, + 'no-console': 'off', + 'func-names': 'off', + 'no-process-exit': 'off', + 'object-shorthand': 'off', + 'class-methods-use-this': 'off', + 'single-quote': 'off', + 'max-classes-per-file': 0, + + 'react/jsx-filename-extension': [ + 2, + { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + ], + + 'import/prefer-default-export': 'off', + 'no-unused-expressions': 'off', + 'prefer-template': 'off', + 'no-inner-declarations': 'off', + 'no-plusplus': 'off', + 'no-multi-assign': 'off', + 'no-underscore-dangle': 'off', + 'no-nested-ternary': 'off', + 'lines-between-class-members': 'off', + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': 'warn', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-namespace': 'off', + 'react/destructuring-assignment': 0, + 'no-restricted-globals': ['error', 'event'], + }, + }, + pluginReactConfig, +]; diff --git a/package-lock.json b/package-lock.json index 41922228a..565463980 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2423,14 +2423,14 @@ "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" }, "node_modules/@emotion/react": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", - "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.12.0", "@emotion/cache": "^11.13.0", - "@emotion/serialize": "^1.3.0", + "@emotion/serialize": "^1.3.1", "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", "@emotion/utils": "^1.4.0", "@emotion/weak-memoize": "^0.4.0", @@ -2446,13 +2446,13 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", - "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.1.tgz", + "integrity": "sha512-dEPNKzBPU+vFPGa+z3axPRn8XVDetYORmDC0wAiej+TNcOZE70ZMJa0X7JdeoM6q/nWTMZeLpN/fTnD9o8MQBA==", "dependencies": { "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.9.0", + "@emotion/unitless": "^0.10.0", "@emotion/utils": "^1.4.0", "csstype": "^3.0.2" } @@ -2491,9 +2491,9 @@ "peer": true }, "node_modules/@emotion/unitless": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", - "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.1.0", @@ -17245,9 +17245,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.5.12", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.12.tgz", - "integrity": "sha512-tIhPkdlEoCL1Y+PToq3zRNehUaKp3wBX/sr7aclAWdIWjvqAe/Im/H0SiCM4c1Q8BLPHCdoJTol+ZblflydehA==" + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", + "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==" }, "node_modules/elkjs": { "version": "0.9.3", @@ -20304,14 +20304,6 @@ "node": ">= 12.20" } }, - "node_modules/formdata-node/node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", - "engines": { - "node": ">= 14" - } - }, "node_modules/formidable": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz", @@ -41328,13 +41320,11 @@ } }, "node_modules/web-streams-polyfill": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", - "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", - "optional": true, - "peer": true, + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", "engines": { - "node": ">= 8" + "node": ">= 14" } }, "node_modules/web-worker": { diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts index fc048b155..55801df81 100644 --- a/src/ClientUtils.ts +++ b/src/ClientUtils.ts @@ -82,7 +82,6 @@ export function returnEmptyFilter() { return [] as string[]; } -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace ClientUtils { export const CLICK_TIME = 300; export const DRAG_THRESHOLD = 4; diff --git a/src/ServerUtils.ts b/src/ServerUtils.ts index 8b2d0b9f6..715341ab3 100644 --- a/src/ServerUtils.ts +++ b/src/ServerUtils.ts @@ -2,7 +2,6 @@ import { Socket } from 'socket.io'; import { Message } from './server/Message'; import { Utils } from './Utils'; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace ServerUtils { export function Emit(socket: Socket, message: Message, args: T) { Utils.log('Emit', message.Name, args, false); diff --git a/src/client/Network.ts b/src/client/Network.ts index 8876d8190..6c60c4151 100644 --- a/src/client/Network.ts +++ b/src/client/Network.ts @@ -8,7 +8,7 @@ import { Upload } from '../server/SharedMediaTypes'; * mainly provides methods that the client can use to begin the process of * interacting with the server, such as fetching or uploading files. */ -// eslint-disable-next-line @typescript-eslint/no-namespace + export namespace Networking { export async function FetchFromServer(relativeRoute: string) { return (await fetch(relativeRoute)).text(); diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index a503d732b..5ee7d0f9c 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -40,7 +40,6 @@ const { DFLT_IMAGE_NATIVE_DIM } = require('../views/global/globalCssVariables.mo const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', '')); -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DocUtils { function matchFieldValue(doc: Doc, key: string, valueIn: unknown): boolean { let value = valueIn; @@ -467,7 +466,7 @@ export namespace DocUtils { .concat(userTypes) .concat(clickFuncs) .map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc) - .filter(doc => doc.isTemplateDoc); + .filter(d => d.isTemplateDoc); // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document. but type is not reliable and there could be other types of template searches so this should be generalized // first try to find a template that matches the specific document type (_). otherwise, fallback to a general match on !docLayoutTemplate && diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index b108b73db..41c6ce39b 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -487,9 +487,7 @@ export class DocumentOptions { export const DocOptions = new DocumentOptions(); -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Docs { - // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Prototypes { type LayoutSource = { LayoutString: (key: string) => string }; type PrototypeTemplate = { @@ -647,7 +645,7 @@ export namespace Docs { * Encapsulates the factory used to create new document instances * delegated from top-level prototypes */ - // eslint-disable-next-line @typescript-eslint/no-namespace + export namespace Create { /** * This function receives the relevant document prototype and uses diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts index 16a0df120..a0e1413b6 100644 --- a/src/client/util/DictationManager.ts +++ b/src/client/util/DictationManager.ts @@ -32,14 +32,12 @@ import { UndoManager } from './UndoManager'; * to add new commands as classes or components are constructed. */ -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DictationManager { /** * Some type maneuvering to access Webkit's built-in * speech recognizer. */ - // eslint-disable-next-line @typescript-eslint/no-namespace namespace CORE { export interface IWindow extends Window { webkitSpeechRecognition: { new (): SpeechRecognition }; @@ -48,7 +46,6 @@ export namespace DictationManager { const { webkitSpeechRecognition }: CORE.IWindow = window as unknown as CORE.IWindow; export const placeholder = 'Listening...'; - // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Controls { export const Infringed = 'unable to process: dictation manager still involved in previous session'; const browser = (() => { @@ -230,7 +227,6 @@ export namespace DictationManager { }; } - // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Commands { export const dictationFadeDuration = 2000; diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index c237a75de..7db13689d 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -70,7 +70,6 @@ export function SetupDrag(_reference: React.RefObject, docFunc: () return onItemDown; } -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DragManager { export const dragClassName = 'collectionFreeFormDocumentView-container'; let dragDiv: HTMLDivElement; diff --git a/src/client/util/History.ts b/src/client/util/History.ts index 067c28c6b..0d0c056a4 100644 --- a/src/client/util/History.ts +++ b/src/client/util/History.ts @@ -10,7 +10,6 @@ import { OmitKeys, ClientUtils } from '../../ClientUtils'; import { DocServer } from '../DocServer'; import { DashboardView } from '../views/DashboardView'; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace HistoryUtil { export interface DocInitializerList { [key: string]: string | number; diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index f3ede596d..4231c2ca8 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -4,7 +4,6 @@ import { Utils } from '../../Utils'; import { Gestures } from '../../pen-gestures/GestureTypes'; import './InteractionUtils.scss'; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace InteractionUtils { export const MOUSETYPE = 'mouse'; export const TOUCHTYPE = 'touch'; diff --git a/src/client/util/ScriptingGlobals.ts b/src/client/util/ScriptingGlobals.ts index 4a1a70633..444e8fc0a 100644 --- a/src/client/util/ScriptingGlobals.ts +++ b/src/client/util/ScriptingGlobals.ts @@ -6,7 +6,7 @@ const _scriptingGlobals: { [name: string]: unknown } = {}; const _scriptingDescriptions: { [name: string]: string } = {}; const _scriptingParams: { [name: string]: string } = {}; export let scriptingGlobals: { [name: string]: unknown } = _scriptingGlobals; -// eslint-disable-next-line @typescript-eslint/no-namespace + export namespace ScriptingGlobals { export function getGlobals() { return Object.keys(_scriptingGlobals); } // prettier-ignore export function getGlobalObj() { return _scriptingGlobals; } // prettier-ignore diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index 6cad7060b..733eae5f4 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -5,7 +5,6 @@ import { StrCast } from '../../fields/Types'; import { DocumentType } from '../documents/DocumentTypes'; import { DocOptions, FInfo } from '../documents/Documents'; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace SearchUtil { export type HighlightingResult = { [id: string]: { [key: string]: string[] } }; diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts index 0386b2455..ccb02fb79 100644 --- a/src/client/util/SerializationHelper.ts +++ b/src/client/util/SerializationHelper.ts @@ -12,7 +12,6 @@ export function afterDocDeserialize(cb: (err: unknown, val: unknown) => void, er const serializationTypes: { [name: string]: { ctor: { new (): unknown }; afterDeserialize?: (obj: unknown) => void | Promise } } = {}; const reverseMap: { [ctor: string]: string } = {}; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace SerializationHelper { export function IsSerializing() { return serializing > 0; diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts index 5fd935370..ce0e7768b 100644 --- a/src/client/util/UndoManager.ts +++ b/src/client/util/UndoManager.ts @@ -83,7 +83,6 @@ export function undoBatch(target: any, key?: string | symbol, descriptor?: Typed return descriptor; } -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace UndoManager { export interface UndoEvent { undo: () => void; diff --git a/src/client/views/DocViewUtils.ts b/src/client/views/DocViewUtils.ts index 49a30aa08..1f5f29c7e 100644 --- a/src/client/views/DocViewUtils.ts +++ b/src/client/views/DocViewUtils.ts @@ -6,7 +6,6 @@ import { Doc, SetActiveAudioLinker } from '../../fields/Doc'; import { DocUtils } from '../documents/DocUtils'; import { FieldViewProps } from './nodes/FieldView'; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DocViewUtils { export const ActiveRecordings: { props: FieldViewProps; getAnchor: (addAsAnnotation: boolean) => Doc }[] = []; diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts index bf5475042..c7051c87c 100644 --- a/src/pen-gestures/GestureUtils.ts +++ b/src/pen-gestures/GestureUtils.ts @@ -2,7 +2,6 @@ import { Rect } from 'react-measure'; import { Gestures, PointData } from './GestureTypes'; import { NDollarRecognizer } from './ndollar'; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace GestureUtils { export class GestureEvent { readonly gesture: Gestures; diff --git a/src/server/DashStats.ts b/src/server/DashStats.ts index 6b9fb8971..8e1d4661f 100644 --- a/src/server/DashStats.ts +++ b/src/server/DashStats.ts @@ -9,7 +9,7 @@ import { socketMap, timeMap, userOperations } from './SocketData'; * This includes time connected, number of operations, and * the rate of their operations */ -// eslint-disable-next-line @typescript-eslint/no-namespace + export namespace DashStats { export const SAMPLING_INTERVAL = 1000; // in milliseconds (ms) - Time interval to update the frontend. export const RATE_INTERVAL = 10; // in seconds (s) - Used to calculate rate diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index 5e58db103..8f012f783 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -47,7 +47,6 @@ function usingAzure() { return process.env.USE_AZURE === 'true'; } -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace DashUploadUtils { export interface Size { width: number; diff --git a/src/server/Message.ts b/src/server/Message.ts index b904a5ba3..01a42fc68 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -43,7 +43,6 @@ export interface RoomMessage { readonly room: string; } -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace MessageStore { export const Foo = new Message('Foo'); export const Bar = new Message('Bar'); diff --git a/src/server/Search.ts b/src/server/Search.ts index 06af18776..b21ee853a 100644 --- a/src/server/Search.ts +++ b/src/server/Search.ts @@ -3,7 +3,6 @@ import * as rp from 'request-promise'; const pathTo = (relative: string) => `http://localhost:8983/solr/dash/${relative}`; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Search { export async function updateDocument(document: any) { try { diff --git a/src/server/SharedMediaTypes.ts b/src/server/SharedMediaTypes.ts index 680db9cd0..9aa4b120f 100644 --- a/src/server/SharedMediaTypes.ts +++ b/src/server/SharedMediaTypes.ts @@ -1,7 +1,6 @@ import { ExifData } from 'exif'; import { File } from 'formidable'; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace AcceptableMedia { export const gifs = ['.gif']; export const pngs = ['.png']; @@ -19,7 +18,6 @@ export enum AudioAnnoState { playing = 'playing', } -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Upload { export function isImageInformation(uploadResponse: Upload.FileInformation): uploadResponse is Upload.ImageInformation { return 'nativeWidth' in uploadResponse; diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts index 47206f415..21c405bee 100644 --- a/src/server/apis/google/GoogleApiServerUtils.ts +++ b/src/server/apis/google/GoogleApiServerUtils.ts @@ -21,7 +21,7 @@ const scope = ['documents.readonly', 'documents', 'presentations', 'presentation * This namespace manages server side authentication for Google API queries, either * from the standard v1 APIs or the Google Photos REST API. */ -// eslint-disable-next-line @typescript-eslint/no-namespace + export namespace GoogleApiServerUtils { /** * As we expand out to more Google APIs that are accessible from diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index 2190e27c7..8d3afc3ad 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -113,6 +113,7 @@ function registerEmbeddedBrowseRelativePathHandler(server: express.Express) { }); } +// eslint-disable-next-line @typescript-eslint/no-explicit-any function proxyServe(req: any, requrl: string, response: any) { // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires const htmlBodyMemoryStream = new (require('memorystream'))(); @@ -137,8 +138,10 @@ function proxyServe(req: any, requrl: string, response: any) { response.send(header?.includes('gzip') ? zlib.gzipSync(htmlText) : htmlText); } else { req.pipe(request(requrl)) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('requrl ', e)) .pipe(response) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('response pipe error', e)); console.log('EMPTY body:' + req.url); } @@ -147,14 +150,17 @@ function proxyServe(req: any, requrl: string, response: any) { } } else { req.pipe(htmlBodyMemoryStream) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('html body memorystream error', e)) .pipe(response) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('html body memory stream response error', e)); } }; const retrieveHTTPBody = () => { // req.headers.cookie = ''; req.pipe(request(requrl)) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => { console.log(`CORS url error: ${requrl}`, e); response.send(` @@ -163,6 +169,7 @@ function proxyServe(req: any, requrl: string, response: any) {

${e}

`); }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('response', (res: any) => { res.headers; const headers = Object.keys(res.headers); @@ -187,6 +194,7 @@ function proxyServe(req: any, requrl: string, response: any) { }) .on('end', sendModifiedBody) .pipe(htmlBodyMemoryStream) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .on('error', (e: any) => console.log('http body pipe error', e)); }; retrieveHTTPBody(); @@ -244,6 +252,7 @@ export default async function InitializeServer(routeSetter: RouteSetter) { app.use(whm(compiler)); app.get(/^\/+$/, (req, res) => res.redirect(req.user ? '/home' : '/login')); // target urls that consist of one or more '/'s with nothing in between app.use(express.static(publicDirectory, { setHeaders: res => res.setHeader('Access-Control-Allow-Origin', '*') })); // all urls that start with dash's public directory: /files/ (e.g., /files/images, /files/audio, etc) + // eslint-disable-next-line @typescript-eslint/no-explicit-any app.use(cors({ origin: (_origin: any, callback: any) => callback(null, true) })); registerAuthenticationRoutes(app); // this adds routes to authenticate a user (login, etc) registerCorsProxy(app); // this adds a /corsProxy/ route to allow clients to get to urls that would otherwise be blocked by cors policies diff --git a/src/server/websocket.ts b/src/server/websocket.ts index ccbcb1c5f..1e25a8a27 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -15,7 +15,6 @@ import { resolvedPorts, socketMap, timeMap, userOperations } from './SocketData' import { initializeGuest } from './authentication/DashUserModel'; import { Database } from './database'; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace WebSocket { let CurUser: string | undefined; export let _socket: Socket; -- cgit v1.2.3-70-g09d2 From 518cd0aefa803da13d2ffd51a6abff9cba419718 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Aug 2024 11:08:38 -0400 Subject: updated to latest eslint --- package-lock.json | 2581 +++++------------------------------------------------ package.json | 14 +- 2 files changed, 211 insertions(+), 2384 deletions(-) diff --git a/package-lock.json b/package-lock.json index 60d133483..c030077c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,6 @@ "@types/textfit": "^2.4.4", "@types/web": "^0.0.155", "@types/webpack-hot-middleware": "^2.25.9", - "@typescript-eslint/parser": "^7.8.0", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", "archiver": "^7.0.1", @@ -296,17 +295,8 @@ "@types/youtube": "0.0.50", "chai": "^5.0.0", "cross-env": "^7.0.3", - "eslint": "^8.57.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-node": "^4.1.0", - "eslint-config-prettier": "^9.1.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsx-a11y": "^6.8.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^5.0.1", + "eslint": "^9.9.0", "eslint-plugin-react": "^7.34.1", - "eslint-plugin-react-hooks": "^4.6.0", "globals": "^15.1.0", "jsdom": "^24.0.0", "mocha": "^10.2.0", @@ -316,7 +306,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", - "typescript-eslint": "^7.8.0", + "typescript-eslint": "^8.2.0", "webpack-dev-server": "^5.0.4" }, "engines": { @@ -2537,15 +2527,48 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -2553,7 +2576,7 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2574,14 +2597,11 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2609,22 +2629,18 @@ "node": "*" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/js": { "version": "9.9.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", - "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -2856,40 +2872,6 @@ "supercluster": "^8.0.1" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -2902,11 +2884,17 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead" + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@icons/material": { "version": "0.2.4", @@ -4111,18 +4099,6 @@ "node": ">=14" } }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -9411,12 +9387,6 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, "node_modules/@types/katex": { "version": "0.16.7", "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", @@ -9781,12 +9751,6 @@ "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz", "integrity": "sha512-YvMLqFak/7rt//lPBtEHv3M4sRNA+HGxrhFZ+DQs9K2IkYJbNwVIb8avtJfhDiuaUBX/AW0jnjv48FV8h3u9bQ==" }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -9992,33 +9956,31 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", - "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.2.0.tgz", + "integrity": "sha512-02tJIs655em7fvt9gps/+4k4OsKULYGtLBPJfOsmOq1+3cdClYiF0+d6mHu6qDnTcg88wJBkcPLpQhq7FyDz0A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/type-utils": "7.8.0", - "@typescript-eslint/utils": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "8.2.0", + "@typescript-eslint/type-utils": "8.2.0", + "@typescript-eslint/utils": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -10026,38 +9988,27 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", - "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", - "dependencies": { - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.2.0.tgz", + "integrity": "sha512-j3Di+o0lHgPrb7FxL3fdEy6LJ/j2NE8u+AP/5cQ9SKb+JLH6V6UHDqJ+e0hXBkHP1wn1YDFjYCS9LBQsZDlDEg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.2.0", + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/typescript-estree": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -10066,15 +10017,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.2.0.tgz", + "integrity": "sha512-OFn80B38yD6WwpoHU2Tz/fTz7CgFqInllBoC3WP+/jLbTb4gGPTy9HBSTsbDWkMdN55XlVU0mMDYAtgvlUspGw==", + "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -10082,26 +10034,23 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", - "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.2.0.tgz", + "integrity": "sha512-g1CfXGFMQdT5S+0PSO0fvGXUaiSkl73U1n9LTK5aRAFnPlJ8dLKkXr4AaLFvPedW8lVDoMgLLE3JN98ZZfsj0w==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/typescript-estree": "8.2.0", + "@typescript-eslint/utils": "8.2.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -10109,11 +10058,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.2.0.tgz", + "integrity": "sha512-6a9QSK396YqmiBKPkJtxsgZZZVjYQ6wQ/TlI0C65z7vInaETuC6HAHD98AGLC8DyIPqHytvNuS8bBVvNLKyqvQ==", + "dev": true, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -10121,12 +10071,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.2.0.tgz", + "integrity": "sha512-kiG4EDUT4dImplOsbh47B1QnNmXSoUqOjWDvCJw/o8LgfD0yr7k2uy54D5Wm0j4t71Ge1NkynGhpWdS0dEIAUA==", + "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -10135,7 +10086,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -10151,6 +10102,7 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -10159,52 +10111,38 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", - "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.2.0.tgz", + "integrity": "sha512-O46eaYKDlV3TvAVDNcoDzd5N550ckSe8G4phko++OCSC1dYIb9LTc3HDGYdWqWIAT5qDUKphO6sd9RrpIJJPfg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "8.2.0", + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/typescript-estree": "8.2.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.2.0.tgz", + "integrity": "sha512-sbgsPMW9yLvS7IhCi8IpuK1oBmtbWUNP+hBdwl/I9nzqVsszGnNGti5r9dUtF5RLivHUFFIdRvLiTsPhzSyJ3Q==", + "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "8.2.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -10652,33 +10590,6 @@ "node": ">=6" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -10805,47 +10716,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/aria-query/node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", @@ -10942,26 +10812,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -11098,21 +10948,6 @@ "node": ">=0.10.0" } }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true - }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", @@ -11150,15 +10985,6 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.1.tgz", "integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==" }, - "node_modules/axe-core": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", - "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/axios": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", @@ -11169,47 +10995,6 @@ "proxy-from-env": "^1.1.0" } }, - "node_modules/axobject-query": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", - "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", - "dev": true, - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/axobject-query/node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/b4a": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", @@ -11226,36 +11011,6 @@ "babel-node": "lib/cli.js" } }, - "node_modules/babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "eslint": ">= 4.12.1" - } - }, - "node_modules/babel-eslint/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/babel-loader": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", @@ -15118,12 +14873,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "node_modules/chart.js": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", @@ -15247,27 +14996,6 @@ "node": ">=0.10.0" } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -15683,12 +15411,6 @@ "quickselect": "^2.0.0" } }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, "node_modules/connect-flash": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz", @@ -16644,12 +16366,6 @@ "lodash-es": "^4.17.21" } }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true - }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -17149,6 +16865,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, "dependencies": { "path-type": "^4.0.0" }, @@ -17168,17 +16885,6 @@ "node": ">=6" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", @@ -17560,26 +17266,6 @@ "node": ">= 0.4" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-iterator-helpers": { "version": "1.0.19", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", @@ -17692,40 +17378,36 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz", + "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.9.0", "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", @@ -17739,1223 +17421,16 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-airbnb": { - "version": "19.0.4", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", - "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", - "dev": true, - "dependencies": { - "eslint-config-airbnb-base": "^15.0.0", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5" - }, - "engines": { - "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.28.0", - "eslint-plugin-react-hooks": "^4.3.0" - } - }, - "node_modules/eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-config-esnext": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-esnext/-/eslint-config-esnext-4.1.0.tgz", - "integrity": "sha512-GhfVEXdqYKEIIj7j+Fw2SQdL9qyZMekgXfq6PyXM66cQw0B435ddjz3P3kxOBVihMRJ0xGYjosaveQz5Y6z0uA==", - "dev": true, - "dependencies": { - "babel-eslint": "^10.0.1", - "eslint": "^6.8.0", - "eslint-plugin-babel": "^5.2.1", - "eslint-plugin-import": "^2.14.0" - }, - "peerDependencies": { - "eslint": "^6.0.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-esnext/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-config-esnext/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/eslint-config-esnext/node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/eslint-config-esnext/node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-esnext/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-esnext/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-esnext/node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-esnext/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-esnext/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/eslint-config-esnext/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-config-esnext/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/eslint-config-esnext/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-config-esnext/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint-config-esnext/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-config-esnext/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/eslint-config-esnext/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-esnext/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/eslint-config-esnext/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-esnext/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-config-esnext/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/eslint-config-node": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-node/-/eslint-config-node-4.1.0.tgz", - "integrity": "sha512-Wz17xV5O2WFG8fGdMYEBdbiL6TL7YNJSJvSX9V4sXQownewfYmoqlly7wxqLkOUv/57pq6LnnotMiQQrrPjCqQ==", - "dev": true, - "dependencies": { - "eslint": "^6.8.0", - "eslint-config-esnext": "^4.1.0" - }, - "peerDependencies": { - "eslint": "^6.0.0" - } - }, - "node_modules/eslint-config-node/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/eslint-config-node/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-node/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-config-node/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/eslint-config-node/node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/eslint-config-node/node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-node/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-config-node/node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-node/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-node/node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint-config-node/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-config-node/node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-node/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-node/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/eslint-config-node/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-config-node/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/eslint-config-node/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-config-node/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint-config-node/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-node/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-config-node/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/eslint-config-node/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-node/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-node/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-node/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/eslint-config-node/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/eslint-config-node/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-config-node/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-config-node/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-node/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-node/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-config-node/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", - "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "enhanced-resolve": "^5.12.0", - "eslint-module-utils": "^2.7.4", - "fast-glob": "^3.3.1", - "get-tsconfig": "^4.5.0", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-5.3.1.tgz", - "integrity": "sha512-VsQEr6NH3dj664+EyxJwO4FCYm/00JhYb3Sk3ft8o+fpKuIfQ9TaW6uVUfvwMXHcf/lsnRIoyFPsLMyiWCSL/g==", - "dev": true, - "dependencies": { - "eslint-rule-composer": "^0.3.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": ">=4.0.0" - } - }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", - "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", - "dev": true, - "dependencies": { - "aria-query": "~5.1.3", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "^4.9.1", - "axobject-query": "~3.1.1", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.19", - "hasown": "^2.0.2", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.0" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-node/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", - "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" + "url": "https://eslint.org/donate" }, "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" + "jiti": "*" }, "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { + "jiti": { "optional": true } } @@ -18992,18 +17467,6 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, "node_modules/eslint-plugin-react/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -19055,54 +17518,21 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-rule-composer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", - "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -19137,14 +17567,6 @@ "webpack": "^5.0.0" } }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -19159,11 +17581,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -19204,18 +17621,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/has-flag": { @@ -19226,17 +17640,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -19259,17 +17662,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/esm": { "version": "3.2.25", "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", @@ -19279,16 +17671,27 @@ } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -19615,20 +18018,6 @@ "node": ">=0.10.0" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/extract-colors": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/extract-colors/-/extract-colors-4.0.6.tgz", @@ -19661,12 +18050,6 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, "node_modules/fast-equals": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-4.0.3.tgz", @@ -19681,6 +18064,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -19696,6 +18080,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -19793,39 +18178,15 @@ "when": ">= 0.0.1" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-loader": { @@ -20014,71 +18375,15 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/flat-cache/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flat-cache/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=16" } }, "node_modules/flatted": { @@ -20402,6 +18707,14 @@ "node": ">= 12.20" } }, + "node_modules/formdata-node/node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" + } + }, "node_modules/formidable": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz", @@ -20538,12 +18851,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -20830,18 +19137,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", - "integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", - "dev": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -20987,6 +19282,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -21131,7 +19427,8 @@ "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "node_modules/grid-index": { "version": "1.1.0", @@ -22277,120 +20574,6 @@ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz", "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==" }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/inquirer/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/inspect-function": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.3.4.tgz", @@ -23847,24 +22030,6 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "dev": true - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dev": true, - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/launch-editor": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", @@ -29370,6 +27535,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "engines": { "node": ">= 8" } @@ -31363,12 +29529,6 @@ "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "node_modules/nan": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", @@ -31441,12 +29601,6 @@ "double-bits": "^1.1.0" } }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -34214,20 +32368,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -34395,15 +32535,6 @@ "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==" }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-cancelable": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-4.0.1.tgz", @@ -35209,18 +33340,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -35253,15 +33372,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -36554,18 +34664,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/regexpu-core": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", @@ -37509,15 +35607,6 @@ "node": ">=8" } }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, "node_modules/resolve-protobuf-schema": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", @@ -37540,25 +35629,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -37707,15 +35777,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -37743,24 +35804,6 @@ "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -38465,31 +36508,9 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/socket.io": { @@ -38841,18 +36862,6 @@ "node": ">=0.10.0" } }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "dev": true, - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/stream-browserify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", @@ -38990,16 +36999,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" }, - "node_modules/string.prototype.includes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", - "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, "node_modules/string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -39362,42 +37361,11 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/synckit": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", - "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", - "dev": true, - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/table-layout": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", @@ -39413,56 +37381,6 @@ "node": ">=4.0.0" } }, - "node_modules/table/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -39651,12 +37569,6 @@ "tslib": "^2" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -39688,18 +37600,6 @@ "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -39880,6 +37780,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, "engines": { "node": ">=16" }, @@ -40160,39 +38061,6 @@ "strip-json-comments": "^2.0.0" } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/tsconfig/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -40611,25 +38479,22 @@ "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==" }, "node_modules/typescript-eslint": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.8.0.tgz", - "integrity": "sha512-sheFG+/D8N/L7gC3WT0Q8sB97Nm573Yfr+vZFzl/4nBdYcmviBPtwGSX9TJ7wpVg28ocerKVOt+k2eGmHzcgVA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.2.0.tgz", + "integrity": "sha512-DmnqaPcML0xYwUzgNbM1XaKXpEb7BShYf2P1tkUmmcl8hyeG7Pj08Er7R9bNy6AufabywzJcOybQAtnD/c9DGw==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "7.8.0", - "@typescript-eslint/parser": "7.8.0", - "@typescript-eslint/utils": "7.8.0" + "@typescript-eslint/eslint-plugin": "8.2.0", + "@typescript-eslint/parser": "8.2.0", + "@typescript-eslint/utils": "8.2.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -41193,12 +39058,6 @@ "node": ">=8" } }, - "node_modules/v8-compile-cache": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", - "dev": true - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -41431,11 +39290,13 @@ } }, "node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", + "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", + "optional": true, + "peer": true, "engines": { - "node": ">= 14" + "node": ">= 8" } }, "node_modules/web-worker": { @@ -42161,30 +40022,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/write/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", diff --git a/package.json b/package.json index fe9f37923..658ba7ab5 100644 --- a/package.json +++ b/package.json @@ -72,17 +72,8 @@ "@types/youtube": "0.0.50", "chai": "^5.0.0", "cross-env": "^7.0.3", - "eslint": "^8.57.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-node": "^4.1.0", - "eslint-config-prettier": "^9.1.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsx-a11y": "^6.8.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^5.0.1", + "eslint": "^9.9.0", "eslint-plugin-react": "^7.34.1", - "eslint-plugin-react-hooks": "^4.6.0", "globals": "^15.1.0", "jsdom": "^24.0.0", "mocha": "^10.2.0", @@ -92,7 +83,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", - "typescript-eslint": "^7.8.0", + "typescript-eslint": "^8.2.0", "webpack-dev-server": "^5.0.4" }, "dependencies": { @@ -140,7 +131,6 @@ "@types/textfit": "^2.4.4", "@types/web": "^0.0.155", "@types/webpack-hot-middleware": "^2.25.9", - "@typescript-eslint/parser": "^7.8.0", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", "archiver": "^7.0.1", -- cgit v1.2.3-70-g09d2 From cd78d4e45951c7ee54a2d9e5f31a8d814f837714 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Aug 2024 11:11:08 -0400 Subject: upgraded eslint to latest --- package-lock.json | 2650 ++++++----------------------------------------------- package.json | 11 +- 2 files changed, 259 insertions(+), 2402 deletions(-) diff --git a/package-lock.json b/package-lock.json index 565463980..524d6002e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -294,17 +294,8 @@ "@types/youtube": "0.0.50", "chai": "^5.0.0", "cross-env": "^7.0.3", - "eslint": "^8.57.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-node": "^4.1.0", - "eslint-config-prettier": "^9.1.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsx-a11y": "^6.8.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^5.0.1", + "eslint": "^9.9.0", "eslint-plugin-react": "^7.34.1", - "eslint-plugin-react-hooks": "^4.6.0", "globals": "^15.1.0", "jsdom": "^24.0.0", "mocha": "^10.2.0", @@ -2535,15 +2526,48 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -2551,7 +2575,7 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2572,14 +2596,11 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2607,22 +2628,18 @@ "node": "*" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/js": { "version": "9.9.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", - "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -2854,40 +2871,6 @@ "supercluster": "^8.0.1" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -2900,11 +2883,17 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead" + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@icons/material": { "version": "0.2.4", @@ -4109,18 +4098,6 @@ "node": ">=14" } }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -9385,12 +9362,6 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, "node_modules/@types/katex": { "version": "0.16.7", "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", @@ -10568,33 +10539,6 @@ "node": ">=6" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -10721,47 +10665,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/aria-query/node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", @@ -10858,26 +10761,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -11014,21 +10897,6 @@ "node": ">=0.10.0" } }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true - }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", @@ -11066,15 +10934,6 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.1.tgz", "integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==" }, - "node_modules/axe-core": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", - "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/axios": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", @@ -11085,47 +10944,6 @@ "proxy-from-env": "^1.1.0" } }, - "node_modules/axobject-query": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", - "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", - "dev": true, - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/axobject-query/node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/b4a": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", @@ -11142,36 +10960,6 @@ "babel-node": "lib/cli.js" } }, - "node_modules/babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "eslint": ">= 4.12.1" - } - }, - "node_modules/babel-eslint/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/babel-loader": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", @@ -15034,12 +14822,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "node_modules/chart.js": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", @@ -15163,27 +14945,6 @@ "node": ">=0.10.0" } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -15599,12 +15360,6 @@ "quickselect": "^2.0.0" } }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, "node_modules/connect-flash": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz", @@ -16560,12 +16315,6 @@ "lodash-es": "^4.17.21" } }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true - }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -17084,17 +16833,6 @@ "node": ">=6" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", @@ -17476,26 +17214,6 @@ "node": ">= 0.4" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-iterator-helpers": { "version": "1.0.19", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", @@ -17608,40 +17326,36 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz", + "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.9.0", "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", @@ -17655,89 +17369,53 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-airbnb": { - "version": "19.0.4", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", - "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", - "dev": true, - "dependencies": { - "eslint-config-airbnb-base": "^15.0.0", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5" - }, - "engines": { - "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" + "url": "https://eslint.org/donate" }, "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.28.0", - "eslint-plugin-react-hooks": "^4.3.0" + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "node_modules/eslint-plugin-react": { + "version": "7.35.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", + "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", "dev": true, "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.19", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-config-esnext": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-esnext/-/eslint-config-esnext-4.1.0.tgz", - "integrity": "sha512-GhfVEXdqYKEIIj7j+Fw2SQdL9qyZMekgXfq6PyXM66cQw0B435ddjz3P3kxOBVihMRJ0xGYjosaveQz5Y6z0uA==", - "dev": true, - "dependencies": { - "babel-eslint": "^10.0.1", - "eslint": "^6.8.0", - "eslint-plugin-babel": "^5.2.1", - "eslint-plugin-import": "^2.14.0" + "node": ">=4" }, "peerDependencies": { - "eslint": "^6.0.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, - "node_modules/eslint-config-esnext/node_modules/brace-expansion": { + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", @@ -17747,1413 +17425,170 @@ "concat-map": "0.0.1" } }, - "node_modules/eslint-config-esnext/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "esutils": "^2.0.2" }, "engines": { - "node": ">=4.8" + "node": ">=0.10.0" } }, - "node_modules/eslint-config-esnext/node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "bin": { - "semver": "bin/semver" + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/eslint-config-esnext/node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "resolve": "bin/resolve" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-config-esnext/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, + "node_modules/eslint-scope": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-config-esnext/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-config-esnext/node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, + "node_modules/eslint-webpack-plugin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-4.2.0.tgz", + "integrity": "sha512-rsfpFQ01AWQbqtjgPRr2usVRxhWDuG0YDYcG8DJOteD3EFnpeuYuOwk0PQiN7PRBTqS6ElNdtPZPggj8If9WnA==", "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "@types/eslint": "^8.56.10", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^8.0.0 || ^9.0.0", + "webpack": "^5.0.0" } }, - "node_modules/eslint-config-esnext/node_modules/estraverse": { + "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { - "flat-cache": "^2.0.1" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint-config-esnext/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/eslint-config-esnext/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/eslint-config-esnext/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "*" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/eslint-config-esnext/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { - "is-glob": "^4.0.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 6" + "node": ">=7.0.0" } }, - "node_modules/eslint-config-esnext/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-config-esnext/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-config-esnext/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/eslint-config-esnext/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-config-esnext/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/eslint-config-esnext/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-esnext/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/eslint-config-esnext/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-esnext/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-esnext/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-config-esnext/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/eslint-config-node": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-node/-/eslint-config-node-4.1.0.tgz", - "integrity": "sha512-Wz17xV5O2WFG8fGdMYEBdbiL6TL7YNJSJvSX9V4sXQownewfYmoqlly7wxqLkOUv/57pq6LnnotMiQQrrPjCqQ==", - "dev": true, - "dependencies": { - "eslint": "^6.8.0", - "eslint-config-esnext": "^4.1.0" - }, - "peerDependencies": { - "eslint": "^6.0.0" - } - }, - "node_modules/eslint-config-node/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/eslint-config-node/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-node/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-config-node/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/eslint-config-node/node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/eslint-config-node/node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-node/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-config-node/node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-node/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-node/node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint-config-node/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-config-node/node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-node/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-node/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/eslint-config-node/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-config-node/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/eslint-config-node/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-config-node/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint-config-node/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-node/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-config-node/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/eslint-config-node/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-node/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-node/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-node/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/eslint-config-node/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/eslint-config-node/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-config-node/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-config-node/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-config-node/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint-config-node/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-config-node/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", - "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "enhanced-resolve": "^5.12.0", - "eslint-module-utils": "^2.7.4", - "fast-glob": "^3.3.1", - "get-tsconfig": "^4.5.0", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-5.3.1.tgz", - "integrity": "sha512-VsQEr6NH3dj664+EyxJwO4FCYm/00JhYb3Sk3ft8o+fpKuIfQ9TaW6uVUfvwMXHcf/lsnRIoyFPsLMyiWCSL/g==", - "dev": true, - "dependencies": { - "eslint-rule-composer": "^0.3.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": ">=4.0.0" - } - }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", - "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", - "dev": true, - "dependencies": { - "aria-query": "~5.1.3", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "^4.9.1", - "axobject-query": "~3.1.1", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.19", - "hasown": "^2.0.2", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.0" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-node/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", - "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.35.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", - "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.tosorted": "^1.1.4", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.19", - "estraverse": "^5.3.0", - "hasown": "^2.0.2", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.8", - "object.fromentries": "^2.0.8", - "object.values": "^1.2.0", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11", - "string.prototype.repeat": "^1.0.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-rule-composer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", - "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-webpack-plugin": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-4.2.0.tgz", - "integrity": "sha512-rsfpFQ01AWQbqtjgPRr2usVRxhWDuG0YDYcG8DJOteD3EFnpeuYuOwk0PQiN7PRBTqS6ElNdtPZPggj8If9WnA==", - "dependencies": { - "@types/eslint": "^8.56.10", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.2.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^8.0.0 || ^9.0.0", - "webpack": "^5.0.0" - } - }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/minimatch": { + "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", @@ -19175,17 +17610,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/esm": { "version": "3.2.25", "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", @@ -19195,16 +17619,27 @@ } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -19531,20 +17966,6 @@ "node": ">=0.10.0" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/extract-colors": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/extract-colors/-/extract-colors-4.0.6.tgz", @@ -19563,12 +17984,6 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, "node_modules/fast-equals": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-4.0.3.tgz", @@ -19695,39 +18110,15 @@ "when": ">= 0.0.1" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-loader": { @@ -19916,71 +18307,15 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/flat-cache/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flat-cache/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=16" } }, "node_modules/flatted": { @@ -20304,6 +18639,14 @@ "node": ">= 12.20" } }, + "node_modules/formdata-node/node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" + } + }, "node_modules/formidable": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz", @@ -20440,12 +18783,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -20732,18 +19069,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", - "integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", - "dev": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -21033,7 +19358,8 @@ "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "node_modules/grid-index": { "version": "1.1.0", @@ -22179,120 +20505,6 @@ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz", "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==" }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/inquirer/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/inspect-function": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.3.4.tgz", @@ -23749,24 +21961,6 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "dev": true - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dev": true, - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/launch-editor": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", @@ -24297,9 +22491,9 @@ } }, "node_modules/mathquill": { - "version": "0.10.1-a", - "resolved": "https://registry.npmjs.org/mathquill/-/mathquill-0.10.1-a.tgz", - "integrity": "sha512-snSAEwAtwdwBFSor+nVBnWWQtTw67kgAgKMyAIxuz4ZPboy0qkWZmd7BL3lfOXp/INihhRlU1PcfaAtDaRhmzA==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/mathquill/-/mathquill-0.10.1.tgz", + "integrity": "sha512-dGtVAUDyKIoS2BPYYgQK7aZAarKQB6oEEWItS5WKmMjYexPOVDm4vYL+I1puYiLvpD4auFUi2z8FeQZP4+FYOA==", "dependencies": { "jquery": "^1.12.3" } @@ -31260,12 +29454,6 @@ "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "node_modules/nan": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", @@ -31338,12 +29526,6 @@ "double-bits": "^1.1.0" } }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -34111,20 +32293,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -34292,15 +32460,6 @@ "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==" }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-cancelable": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-4.0.1.tgz", @@ -35106,18 +33265,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -35150,15 +33297,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -36451,18 +34589,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/regexpu-core": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", @@ -37406,15 +35532,6 @@ "node": ">=8" } }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, "node_modules/resolve-protobuf-schema": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", @@ -37437,25 +35554,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -37604,15 +35702,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -37640,24 +35729,6 @@ "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -38361,29 +36432,6 @@ "node": ">=8" } }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/socket.io": { "version": "4.7.5", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", @@ -38733,18 +36781,6 @@ "node": ">=0.10.0" } }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "dev": true, - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/stream-browserify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", @@ -38882,16 +36918,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" }, - "node_modules/string.prototype.includes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", - "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, "node_modules/string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -39254,42 +37280,11 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/synckit": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", - "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", - "dev": true, - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/table-layout": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", @@ -39305,56 +37300,6 @@ "node": ">=4.0.0" } }, - "node_modules/table/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -39543,12 +37488,6 @@ "tslib": "^2" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -39580,18 +37519,6 @@ "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -40052,39 +37979,6 @@ "strip-json-comments": "^2.0.0" } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/tsconfig/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -41082,12 +38976,6 @@ "node": ">=8" } }, - "node_modules/v8-compile-cache": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", - "dev": true - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -41320,11 +39208,13 @@ } }, "node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", + "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", + "optional": true, + "peer": true, "engines": { - "node": ">= 14" + "node": ">= 8" } }, "node_modules/web-worker": { @@ -42050,30 +39940,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/write/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", diff --git a/package.json b/package.json index 17e349428..fe85e9357 100644 --- a/package.json +++ b/package.json @@ -72,17 +72,8 @@ "@types/youtube": "0.0.50", "chai": "^5.0.0", "cross-env": "^7.0.3", - "eslint": "^8.57.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-node": "^4.1.0", - "eslint-config-prettier": "^9.1.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsx-a11y": "^6.8.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^5.0.1", + "eslint": "^9.9.0", "eslint-plugin-react": "^7.34.1", - "eslint-plugin-react-hooks": "^4.6.0", "globals": "^15.1.0", "jsdom": "^24.0.0", "mocha": "^10.2.0", -- cgit v1.2.3-70-g09d2 From 25ee9e6b3f7da67bcf94eb2affd5793c67777930 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Aug 2024 17:04:32 -0400 Subject: cleanup of face recognition. some lint fixes. --- eslint.config.mjs | 8 + src/.DS_Store | Bin 10244 -> 10244 bytes src/client/util/CurrentUserUtils.ts | 5 - src/client/util/DocumentManager.ts | 1 - src/client/views/MainView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 4 +- .../collectionFreeForm/FaceCollectionBox.tsx | 121 ++++++------- src/client/views/nodes/DocumentView.tsx | 8 +- src/client/views/search/FaceRecognitionHandler.tsx | 190 +++++++++++++++------ src/fields/Doc.ts | 6 +- src/fields/RichTextUtils.ts | 4 - src/server/database.ts | 3 - src/server/server_Initialization.ts | 2 +- 13 files changed, 198 insertions(+), 156 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 04655ce13..119f2f486 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -29,6 +29,7 @@ export default [ 'import/prefer-default-export': 'off', 'no-unused-expressions': 'off', + '@typescript-eslint/no-unused-expressions': 'off', 'prefer-template': 'off', 'no-inner-declarations': 'off', 'no-plusplus': 'off', @@ -42,6 +43,13 @@ export default [ '@typescript-eslint/no-unused-vars': 'error', '@typescript-eslint/no-namespace': 'off', 'react/destructuring-assignment': 0, + 'prefer-arrow-callback': 'error', + 'no-return-assign': 'error', + 'no-await-in-loop': 'error', + 'no-loop-func': 'error', + 'no-conditional-assign': 'error', + 'no-use-before-define': 'error', + 'no-explicit-any': 'error', 'no-restricted-globals': ['error', 'event'], }, }, diff --git a/src/.DS_Store b/src/.DS_Store index 7a0b53ce0..426a2ee90 100644 Binary files a/src/.DS_Store and b/src/.DS_Store differ diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 2962682c2..0681a21cb 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -95,7 +95,6 @@ export class CurrentUserUtils { }); const reqdOpts:DocumentOptions = { title: "child click editors", _height:75, isSystem: true}; - // eslint-disable-next-line no-return-assign return DocUtils.AssignOpts(tempClicks, reqdOpts, reqdClickList) ?? (doc[field] = Docs.Create.TreeDocument(reqdClickList, reqdOpts)); } @@ -120,7 +119,6 @@ export class CurrentUserUtils { }); const reqdOpts:DocumentOptions = {title: "click editor templates", _height:75, isSystem: true}; - // eslint-disable-next-line no-return-assign return DocUtils.AssignOpts(tempClicks, reqdOpts, reqdClickList) ?? (doc[field] = Docs.Create.TreeDocument(reqdClickList, reqdOpts)); } @@ -138,7 +136,6 @@ export class CurrentUserUtils { }), ... DocListCast(tempNotes?.data).filter(note => !reqdTempOpts.find(reqd => reqd.title === note.title))]; const reqdOpts:DocumentOptions = { title: "Note Layouts", _height: 75, isSystem: true }; - // eslint-disable-next-line no-return-assign return DocUtils.AssignOpts(tempNotes, reqdOpts, reqdNoteList) ?? (doc[field] = Docs.Create.TreeDocument(reqdNoteList, reqdOpts)); } static setupUserTemplates(doc: Doc, field="template_user") { @@ -146,7 +143,6 @@ export class CurrentUserUtils { const reqdUserList = DocListCast(tempUsers?.data); const reqdOpts:DocumentOptions = { title: "User Layouts", _height: 75, isSystem: true }; - // eslint-disable-next-line no-return-assign return DocUtils.AssignOpts(tempUsers, reqdOpts, reqdUserList) ?? (doc[field] = Docs.Create.TreeDocument(reqdUserList, reqdOpts)); } @@ -183,7 +179,6 @@ export class CurrentUserUtils { default: return labelBox; }})(); const allopts = {isSystem: true, onClickScriptDisable: "never", ...opts, title}; - // eslint-disable-next-line no-return-assign return DocUtils.AssignScripts( (curIcon?.iconTemplate === opts.iconTemplate ? DocUtils.AssignOpts(curIcon, allopts):undefined) ?? ((templateIconsDoc[title] = MakeTemplate(creator(allopts, templateField)))), {onClick:"deiconifyView(documentView)", onDoubleClick: "deiconifyViewToLightbox(documentView)", }); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index a10237fcc..83b83240e 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -17,7 +17,6 @@ export class DocumentManager { // eslint-disable-next-line no-use-before-define private static _instance: DocumentManager; public static get Instance(): DocumentManager { - // eslint-disable-next-line no-return-assign return this._instance || (this._instance = new this()); } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 62ad0a3fb..9f1c7da3d 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -75,7 +75,7 @@ import { AnchorMenu } from './pdf/AnchorMenu'; import { GPTPopup } from './pdf/GPTPopup/GPTPopup'; import { TopBar } from './topbar/TopBar'; -// eslint-disable-next-line @typescript-eslint/no-var-requires +// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore @observer diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index a6768ab35..5782d407e 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -1,4 +1,4 @@ -import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import * as React from 'react'; import * as rp from 'request-promise'; import { ClientUtils, returnFalse } from '../../../ClientUtils'; @@ -9,7 +9,7 @@ import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; -import { BoolCast, Cast, DocCast, ScriptCast, StrCast } from '../../../fields/Types'; +import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index d5a2809dc..94f9a3c94 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -3,28 +3,28 @@ import { IconButton, Size } from 'browndash-components'; import * as faceapi from 'face-api.js'; import { FaceMatcher } from 'face-api.js'; import 'ldrs/ring'; -import { action, computed, makeObservable, observable } from 'mobx'; +import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; -import { Utils } from '../../../../Utils'; -import { Doc, DocListCast } from '../../../../fields/Doc'; -import { DocData } from '../../../../fields/DocSymbols'; +import { setupMoveUpEvents } from '../../../../ClientUtils'; +import { Utils, emptyFunction } from '../../../../Utils'; +import { Doc, Opt } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; -import { listSpec } from '../../../../fields/Schema'; -import { Cast, ImageCast, StrCast } from '../../../../fields/Types'; +import { ImageCast } from '../../../../fields/Types'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; +import { dropActionType } from '../../../util/DropActionTypes'; import { SnappingManager } from '../../../util/SnappingManager'; import { undoable } from '../../../util/UndoManager'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocumentView } from '../../nodes/DocumentView'; import { FieldView, FieldViewProps } from '../../nodes/FieldView'; +import { FaceRecognitionHandler } from '../../search/FaceRecognitionHandler'; import './FaceCollectionBox.scss'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; -import { FaceRecognitionHandler } from '../../search/FaceRecognitionHandler'; interface FaceDocumentProps { faceDoc: Doc; @@ -50,49 +50,29 @@ export class FaceDocumentItem extends ObservableReactComponent doc.type === DocumentType.IMG); - filteredDocs.forEach(doc => { - // If the current Face Document has no items, and the doc has more than one face descriptor, don't let the user add the document first. - if ((this._props.faceDoc[DocData].face_descriptors as List>).length === 0 && (doc[DocData][FaceRecognitionHandler.FacesField(doc)] as List>).length > 1) { + de.complete.docDragData?.droppedDocuments + ?.filter(doc => doc.type === DocumentType.IMG) + .forEach(imgDoc => { + // If the current Face Document has no faces, and the doc has more than one face descriptor, don't let the user add the document first. Or should we just use the first face ? + if (FaceRecognitionHandler.FaceDocDescriptors(this._props.faceDoc).length === 0 && FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).length > 1) { alert('Cannot add a document with multiple faces as the first item!'); } else { - // Loop through the documents' face descriptors. - // Choose the face with the smallest distance to add. - const float32Array = (this._props.faceDoc[DocData].face_descriptors as List>).map(faceDescriptor => new Float32Array(Array.from(faceDescriptor))); - const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(StrCast(this._props.faceDoc[DocData].face_label), float32Array); - const faceDescriptors: faceapi.LabeledFaceDescriptors[] = [labeledFaceDescriptor]; - - const faceMatcher = new FaceMatcher(faceDescriptors, 1); - let cur_lowest_distance = 1; - let cur_matching_face = new List(); - - (doc[DocData][FaceRecognitionHandler.FacesField(doc)] as List>).forEach(face => { - // If the face has the current lowest distance, mark it as such - // Once that lowest distance is found, add the face descriptor to the faceDoc, and add the associated doc - const convered_32_array: Float32Array = new Float32Array(Array.from(face)); - const match = faceMatcher.matchDescriptor(convered_32_array); - - if (match.distance < cur_lowest_distance) { - cur_lowest_distance = match.distance; - cur_matching_face = face; - } - }); - - const faceFieldKey = FaceRecognitionHandler.FaceField(doc, this._props.faceDoc); - if (doc[DocData][faceFieldKey]) { - Cast(doc[DocData][faceFieldKey], listSpec('number'), null).push(cur_matching_face as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that - } else { - doc[DocData][faceFieldKey] = new List>([cur_matching_face]); - } - - Doc.AddDocToList(this._props.faceDoc[DocData], 'face_docList', doc); - Cast(this._props.faceDoc[DocData].face_descriptors, listSpec('number'), null).push(cur_matching_face as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that + // Loop through the documents' face descriptors and choose the face in the iage with the smallest distance (most similar to the face colleciton) + const faceDescriptorsAsFloat32Array = FaceRecognitionHandler.FaceDocDescriptors(this._props.faceDoc).map(fd => new Float32Array(Array.from(fd))); + const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.FaceDocLabel(this._props.faceDoc), faceDescriptorsAsFloat32Array); + const faceMatcher = new FaceMatcher([labeledFaceDescriptor], 1); + const { face_match } = FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).reduce( + (prev, face) => { + const match = faceMatcher.matchDescriptor(new Float32Array(Array.from(face))); + return match.distance < prev.dist ? { dist: match.distance, face_match: face } : prev; + }, + { dist: 1, face_match: new List() as Opt> } + ); + + // assign the face in the image that's closest to the face collection to be the face that's assigned to the collection + face_match && FaceRecognitionHandler.ImageDocAddFace(imgDoc, face_match, this._props.faceDoc); } }); - return false; - } return false; } @@ -108,23 +88,16 @@ export class FaceDocumentItem extends ObservableReactComponent { - if (Doc.ActiveDashboard) { - Doc.RemoveDocFromList(Doc.ActiveDashboard[DocData], 'faceDocuments', this._props.faceDoc); - } - }, 'remove face'); + FaceRecognitionHandler.DeleteFaceDoc(this._props.faceDoc); + }, 'delete face'); /** * Deletes a document from a Face Document's associated docs list. * @param doc */ - @action - deleteAssociatedDoc = (doc: Doc) => { - this._props.faceDoc[DocData].face_descriptors = new List>( - (this._props.faceDoc[DocData].face_descriptors as List>).filter(fd => !(doc[DocData][FaceRecognitionHandler.FaceField(doc, this._props.faceDoc)] as List>).includes(fd)) - ); - doc[DocData][FaceRecognitionHandler.FaceField(doc, this._props.faceDoc)] = new List>(); - Doc.RemoveDocFromList(this._props.faceDoc[DocData], 'face_docList', doc); - }; + deleteAssociatedDoc = undoable((imgDoc: Doc) => { + FaceRecognitionHandler.FaceDocRemoveImageDocFace(imgDoc, this._props.faceDoc); + }, 'remove doc from face'); render() { return ( @@ -133,7 +106,7 @@ export class FaceDocumentItem extends ObservableReactComponent
-

{StrCast(this._props.faceDoc[DocData].face_label)}

+

{FaceRecognitionHandler.FaceDocLabel(this._props.faceDoc)}

{this._displayImages ? (
- {DocListCast(this._props.faceDoc[DocData].face_docList).map(doc => { + {FaceRecognitionHandler.FaceDocFaces(this._props.faceDoc).map(doc => { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return ( -
+
+ setupMoveUpEvents( + this, + e, + () => { + DragManager.StartDocumentDrag([e.target as HTMLElement], new DragManager.DocumentDragData([doc], dropActionType.embed), e.clientX, e.clientY); + return true; + }, + emptyFunction, + emptyFunction + ) + }> DocumentView.showDocument(doc, { willZoomCentered: true })} style={{ maxWidth: '60px', margin: '10px' }} src={`${name}_o.${type}`} />
this.deleteAssociatedDoc(doc)} icon={'x'} style={{ width: '4px' }} size={Size.XSMALL} /> @@ -168,25 +155,15 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { return FieldView.LayoutString(FaceCollectionBox, fieldKey); } - public static Instance: FaceCollectionBox; - - @computed get currentDocs() { - if (Doc.ActiveDashboard) { - return DocListCast(Doc.ActiveDashboard[DocData].faceDocuments); - } - return []; - } - constructor(props: FieldViewProps) { super(props); makeObservable(this); - FaceCollectionBox.Instance = this; } render() { return (
- {this.currentDocs.map(doc => ( + {FaceRecognitionHandler.FaceDocuments().map(doc => ( ))}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index c807d99ac..5efdb3df4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,5 +1,4 @@ /* eslint-disable no-use-before-define */ -/* eslint-disable react/jsx-props-no-spreading */ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { Property } from 'csstype'; import { Howl } from 'howler'; @@ -341,7 +340,6 @@ export class DocumentViewInternal extends DocComponent { if (this._props.isGroupActive?.() === GroupActive.child && !this._props.isDocumentActive?.()) return; - // eslint-disable-next-line no-use-before-define this._longPressSelector = setTimeout(() => SnappingManager.LongPress && this._props.select(false), 1000); if (!DocumentView.DownDocView) DocumentView.DownDocView = this._docView; @@ -405,7 +402,6 @@ export class DocumentViewInternal extends DocComponent() { ) ); } - // eslint-disable-next-line default-param-last + public static FocusOrOpen(docIn: Doc, optionsIn: FocusViewOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) { let doc = docIn; const options = optionsIn; diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index dc271fe73..3ef6f9674 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -10,7 +10,22 @@ import { DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; /** - * A class that handles face recognition. + * A singleton class that handles face recognition and manages face Doc collections for each face found. + * Displaying an image doc anywhere will trigger this class to test if the image contains any faces. + * If it does, each recognized face will be compared to a global set of faces (each is a face collection Doc + * that have already been found. If the face matches a face collection Doc, then it will be added to that + * collection along with the numerical representation of the face, its face descriptor. + * + * Image Doc's that are added to one or more face collection Docs will be given these metadata fields: + * _Face - a nunerical representation of the Nth face found in the image + * _Faces - a list of all the numerical face representations found in the image (why is this needed?) + * + * Face collection Doc's are created for each person identified and are stored in the Dashboard's faceDocument's list + * + * Each Face collection Doc represents all the images found for that person. It has these fields: + * face_label - a string label for the person that was recognized (currently it's just a 'face#') + * face_descriptors - a list of all the face descriptors for different images of the person + * face_docList - a list of all image Docs that contain a face for the person */ export class FaceRecognitionHandler { static _instance: FaceRecognitionHandler; @@ -18,13 +33,90 @@ export class FaceRecognitionHandler { private _processingDocs: Set = new Set(); private _pendingLoadDocs: Doc[] = []; - public static FaceField = (target: Doc, doc: Doc) => `${Doc.LayoutFieldKey(target)}_${doc.face_label}`; - public static FacesField = (target: Doc) => `${Doc.LayoutFieldKey(target)}_Faces`; + private static imgDocFaceField = (imgDoc: Doc, faceDoc: Doc) => `${Doc.LayoutFieldKey(imgDoc)}_${FaceRecognitionHandler.FaceDocLabel(faceDoc)}`; + /** + * initializes an image with an empty list of face descriptors + * @param imgDoc image to initialize + */ + private static initImageDocFaceDescriptors = (imgDoc: Doc) => { + imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`] = new List>(); + }; + /** + * returns the face descriptors for each face found on an image Doc + * @param imgDoc + * @returns list of face descriptors + */ + public static ImageDocFaceDescriptors = (imgDoc: Doc) => imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`] as List>; + + /** + * Adds metadata to an image Doc describing a face found in the image + * @param imgDoc image Doc containing faces + * @param faceDescriptor descriptor for the face found + * @param faceDoc face collection Doc containing the same face + */ + public static ImageDocAddFace = (imgDoc: Doc, faceDescriptor: List, faceDoc: Doc) => { + const faceFieldKey = FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc); + if (imgDoc[DocData][faceFieldKey]) { + Cast(imgDoc[DocData][faceFieldKey], listSpec('number'), null).push(faceDescriptor as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that + } else { + imgDoc[DocData][faceFieldKey] = new List>([faceDescriptor]); + } + }; + + /** + * returns a list of all face collection Docs on the current dashboard + * @returns face collection Doc list + */ + public static FaceDocuments = () => DocListCast(Doc.ActiveDashboard?.[DocData].faceDocuments); + + public static DeleteFaceDoc = (faceDoc: Doc) => Doc.ActiveDashboard && Doc.RemoveDocFromList(Doc.ActiveDashboard[DocData], 'faceDocuments', faceDoc); + + /** + * returns the labels associated with a face collection Doc + * @param faceDoc the face collection Doc + * @returns label string + */ + public static FaceDocLabel = (faceDoc: Doc) => StrCast(faceDoc[DocData].face_label); + /** + * Returns all the face descriptors associated with a face collection Doc + * @param faceDoc a face collection Doc + * @returns face descriptors + */ + public static FaceDocDescriptors = (faceDoc: Doc) => faceDoc[DocData].face_descriptors as List>; + + /** + * Returns a list of all face image Docs associated with the face collection + * @param faceDoc a face collection Doc + * @returns image Docs + */ + public static FaceDocFaces = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_docList); + + /** + * Adds a face image to the list of faces in a face collection Doc, and updates the face collection's list of image descriptors + * @param img - image with faces to add to a face collection Doc + * @param faceDescriptor - the face descriptor for the face in the image to add + * @param faceDoc - the face collection Doc + */ + public static FaceDocAddImageDocFace = (img: Doc, faceDescriptor: List, faceDoc: Doc) => { + Doc.AddDocToList(faceDoc, 'face_docList', img); + Cast(faceDoc.face_descriptors, listSpec('number'), null).push(faceDescriptor as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that + }; + + /** + * Removes a face from a face Doc collection, and updates the face collection's list of image descriptors + * @param imgDoc - image with faces to remove from the face Doc collectoin + * @param faceDoc - the face Doc collection + */ + public static FaceDocRemoveImageDocFace = (imgDoc: Doc, faceDoc: Doc) => { + imgDoc[DocData][FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc)] = new List>(); + Doc.RemoveDocFromList(faceDoc[DocData], 'face_docList', imgDoc); + faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.FaceDocDescriptors(faceDoc).filter(fd => !(imgDoc[DocData][FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc)] as List>).includes(fd))); + }; constructor() { FaceRecognitionHandler._instance = this; - this.loadModels().then(() => this._pendingLoadDocs.forEach(this.findMatches)); - DocumentManager.Instance.AddAnyViewRenderedCB(dv => FaceRecognitionHandler.Instance.findMatches(dv.Document)); + this.loadModels().then(() => this._pendingLoadDocs.forEach(this.classifyFacesInImage)); + DocumentManager.Instance.AddAnyViewRenderedCB(dv => FaceRecognitionHandler.Instance.classifyFacesInImage(dv.Document)); } @computed get examinedFaceDocs() { @@ -48,48 +140,42 @@ export class FaceRecognitionHandler { /** * When a document is added, look for matching face documents. - * @param doc The document being analyzed. + * @param imgDoc The document being analyzed. */ - public findMatches = async (doc: Doc) => { + public classifyFacesInImage = async (imgDoc: Doc) => { if (!this._loadedModels || !Doc.ActiveDashboard) { - this._pendingLoadDocs.push(doc); + this._pendingLoadDocs.push(imgDoc); return; } - if (doc.type === DocumentType.LOADING && !doc.loadingError) { - setTimeout(() => this.findMatches(doc), 1000); + if (imgDoc.type === DocumentType.LOADING && !imgDoc.loadingError) { + setTimeout(() => this.classifyFacesInImage(imgDoc), 1000); return; } - const imgUrl = ImageCast(doc[Doc.LayoutFieldKey(doc)]); + const imgUrl = ImageCast(imgDoc[Doc.LayoutFieldKey(imgDoc)]); // If the doc isn't an image or currently already been examined or is being processed, stop examining the document. - if (!imgUrl || this.examinedFaceDocs.includes(doc) || this._processingDocs.has(doc)) { + if (!imgUrl || this.examinedFaceDocs.includes(imgDoc) || this._processingDocs.has(imgDoc)) { return; } // Mark the document as being processed. - this._processingDocs.add(doc); + this._processingDocs.add(imgDoc); + FaceRecognitionHandler.initImageDocFaceDescriptors(imgDoc); // Get the image the document contains and analyze for faces. const [name, type] = imgUrl.url.href.split('.'); const imageURL = `${name}_o.${type}`; - const img = await this.loadImage(imageURL); - - const fullFaceDescriptions = await faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors(); - - doc[DocData][FaceRecognitionHandler.FacesField(doc)] = new List>(); + const imgDocFaceDescriptions = await faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors(); // For each face detected, find a match. - for (const fd of fullFaceDescriptions) { - let match = this.findMatch(fd.descriptor); - const converted_list = new List(Array.from(fd.descriptor)); - - if (match) { - // If a matching Face Document has been found, add the document to the Face Document's associated docs and append the face - // descriptor to the Face Document's descriptor list. - Doc.AddDocToList(match, 'face_docList', doc); - Cast(match.face_descriptors, listSpec('number'), null).push(converted_list as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that + for (const fd of imgDocFaceDescriptions) { + let faceDocMatch = this.findMatchingFaceDoc(fd.descriptor); + const faceDescriptor = new List(Array.from(fd.descriptor)); + + if (faceDocMatch) { + FaceRecognitionHandler.FaceDocAddImageDocFace(imgDoc, faceDescriptor, faceDocMatch); } else { // If a matching Face Document has not been found, create a new Face Document. Doc.UserDoc().faceDocNum = NumCast(Doc.UserDoc().faceDocNum) + 1; @@ -98,53 +184,45 @@ export class FaceRecognitionHandler { newFaceDocument.title = `Face ${Doc.UserDoc().faceDocNum}`; newFaceDocument.face = ''; // just to make prettyprinting look better newFaceDocument.face_label = `Face${Doc.UserDoc().faceDocNum}`; - newFaceDocument.face_docList = new List([doc]); - newFaceDocument.face_descriptors = new List>([converted_list]); + newFaceDocument.face_docList = new List([imgDoc]); + newFaceDocument.face_descriptors = new List>([faceDescriptor]); Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'faceDocuments', newFaceDocument); - match = newFaceDocument; + faceDocMatch = newFaceDocument; } // Assign a field in the document of the matching Face Document. - const faceDescripField = FaceRecognitionHandler.FaceField(doc, match); - if (doc[DocData][faceDescripField]) { - Cast(doc[DocData][faceDescripField], listSpec('number'), null).push(converted_list as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that - } else { - doc[DocData][faceDescripField] = new List>([converted_list]); - } - - Cast(doc[DocData][FaceRecognitionHandler.FacesField(doc)], listSpec('number'), null).push(converted_list as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that - - Doc.AddDocToList(Doc.UserDoc(), 'examinedFaceDocs', doc); + FaceRecognitionHandler.ImageDocAddFace(imgDoc, faceDescriptor, faceDocMatch); + Doc.AddDocToList(Doc.UserDoc(), 'examinedFaceDocs', imgDoc); } - this._processingDocs.delete(doc); + this._processingDocs.delete(imgDoc); }; /** - * Finds a matching Face Document given a descriptor - * @param cur_descriptor The current descriptor whose match is being searched for. - * @returns The most similar Face Document. + * Finds the most similar matching Face Document to a face descriptor + * @param faceDescriptor face descriptor number list + * @returns face Doc */ - private findMatch(cur_descriptor: Float32Array) { - if (!Doc.ActiveDashboard || DocListCast(Doc.ActiveDashboard[DocData].faceDocuments).length < 1) { - return null; + private findMatchingFaceDoc = (faceDescriptor: Float32Array) => { + if (!Doc.ActiveDashboard || FaceRecognitionHandler.FaceDocuments().length < 1) { + return undefined; } - const faceDescriptors: faceapi.LabeledFaceDescriptors[] = DocListCast(Doc.ActiveDashboard[DocData].faceDocuments).map(faceDocument => { - const float32Array = (faceDocument[DocData].face_descriptors as List>).map(faceDescriptor => new Float32Array(Array.from(faceDescriptor))); - return new faceapi.LabeledFaceDescriptors(StrCast(faceDocument[DocData].face_label), float32Array); + const faceDescriptors = FaceRecognitionHandler.FaceDocuments().map(faceDoc => { + const float32Array = FaceRecognitionHandler.FaceDocDescriptors(faceDoc).map(fd => new Float32Array(Array.from(fd))); + return new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.FaceDocLabel(faceDoc), float32Array); }); const faceMatcher = new FaceMatcher(faceDescriptors, 0.6); - const match = faceMatcher.findBestMatch(cur_descriptor); + const match = faceMatcher.findBestMatch(faceDescriptor); if (match.label !== 'unknown') { - for (const doc of DocListCast(Doc.ActiveDashboard[DocData].faceDocuments)) { - if (doc[DocData].face_label === match.label) { - return doc; + for (const faceDoc of FaceRecognitionHandler.FaceDocuments()) { + if (FaceRecognitionHandler.FaceDocLabel(faceDoc) === match.label) { + return faceDoc; } } } - return null; - } + return undefined; + }; /** * Loads an image diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index eb6ed9757..ffb5aab79 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-namespace */ -/* eslint-disable default-param-last */ /* eslint-disable no-use-before-define */ import { action, computed, makeObservable, observable, ObservableMap, ObservableSet, runInAction } from 'mobx'; import { computedFn } from 'mobx-utils'; @@ -127,9 +125,7 @@ export type FieldResult = Opt | FieldWaiting * If no default value is given, and the returned value is not undefined, it can be safely modified. */ export function DocListCastAsync(field: FieldResult): Promise; -// eslint-disable-next-line no-redeclare export function DocListCastAsync(field: FieldResult, defaultValue: Doc[]): Promise; -// eslint-disable-next-line no-redeclare export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) { const list = Cast(field, listSpec(Doc)); return list ? Promise.all(list).then(() => list) : Promise.resolve(defaultValue); @@ -437,7 +433,6 @@ export class Doc extends RefField { const writeMode = DocServer.getFieldWriteMode(fKey); if (fKey.startsWith('acl_') || writeMode !== DocServer.WriteMode.Playground) { delete this[CachedUpdates][fKey]; - // eslint-disable-next-line no-await-in-loop await fn(); } else { this[CachedUpdates][fKey] = fn; @@ -1576,6 +1571,7 @@ export namespace Doc { try { resolved = JSON.parse(typeof data === 'string' ? data : JSON.stringify(data)); } catch (e) { + console.error(e); return undefined; } let output: Opt; diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts index d1316d256..b3534dde7 100644 --- a/src/fields/RichTextUtils.ts +++ b/src/fields/RichTextUtils.ts @@ -394,13 +394,11 @@ export namespace RichTextUtils { for (const markName of Object.keys(schema.marks)) { // eslint-disable-next-line no-cond-assign if (ignored.includes(markName) || !(mark = markMap[markName])) { - // eslint-disable-next-line no-continue continue; } let converted = MarkToStyle.get(markName) || (markName as keyof docsV1.Schema$TextStyle); let value: unknown = true; if (!converted) { - // eslint-disable-next-line no-continue continue; } // eslint-disable-next-line @typescript-eslint/no-shadow @@ -412,10 +410,8 @@ export namespace RichTextUtils { const docDelimeter = '/doc/'; const alreadyShared = '?sharing=true'; if (new RegExp(window.location.origin + docDelimeter).test(url) && !url.endsWith(alreadyShared)) { - // eslint-disable-next-line no-await-in-loop const linkDoc = await DocServer.GetRefField(url.split(docDelimeter)[1]); if (linkDoc instanceof Doc) { - // eslint-disable-next-line no-await-in-loop let exported = (await Cast(linkDoc.link_anchor_2, Doc))!; if (!exported.customLayout) { exported = Doc.MakeEmbedding(exported); diff --git a/src/server/database.ts b/src/server/database.ts index 975b9eb80..10dc540c3 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-namespace */ import * as mongodb from 'mongodb'; import * as mongoose from 'mongoose'; import { Opt } from '../fields/Doc'; @@ -148,9 +147,7 @@ export namespace Database { } public delete(query: any, collectionName?: string): Promise; - // eslint-disable-next-line no-dupe-class-members public delete(id: string, collectionName?: string): Promise; - // eslint-disable-next-line no-dupe-class-members public delete(idIn: any, collectionName = DocumentsCollection) { let id = idIn; if (typeof id === 'string') { diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index 97c63a93e..0cf9a6e58 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -115,7 +115,7 @@ function registerEmbeddedBrowseRelativePathHandler(server: express.Express) { // eslint-disable-next-line @typescript-eslint/no-explicit-any function proxyServe(req: any, requrl: string, response: any) { - // eslint-disable-next-line global-require, @typescript-eslint/no-require-imports + // eslint-disable-next-line global-require, @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires const htmlBodyMemoryStream = new (require('memorystream'))(); let wasinBrFormat = false; const sendModifiedBody = () => { -- cgit v1.2.3-70-g09d2 From 4091d1681437527bfb55cb79570e8b652e9b190f Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Aug 2024 17:12:35 -0400 Subject: from last --- .../views/collections/collectionFreeForm/FaceCollectionBox.tsx | 5 ++++- src/client/views/search/FaceRecognitionHandler.tsx | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 94f9a3c94..dd8dea41e 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -70,7 +70,10 @@ export class FaceDocumentItem extends ObservableReactComponent>([faceDescriptor]); } + FaceRecognitionHandler.FaceDocAddImageDocFace(imgDoc, faceDescriptor, faceDoc); }; /** -- cgit v1.2.3-70-g09d2 From b6275b9d630131e50727f76af44936acc0cb7d7d Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Aug 2024 17:25:01 -0400 Subject: from last --- src/client/views/search/FaceRecognitionHandler.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 6494a1ed4..c446df6ff 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -61,7 +61,6 @@ export class FaceRecognitionHandler { } else { imgDoc[DocData][faceFieldKey] = new List>([faceDescriptor]); } - FaceRecognitionHandler.FaceDocAddImageDocFace(imgDoc, faceDescriptor, faceDoc); }; /** @@ -109,7 +108,6 @@ export class FaceRecognitionHandler { * @param faceDoc - the face Doc collection */ public static FaceDocRemoveImageDocFace = (imgDoc: Doc, faceDoc: Doc) => { - imgDoc[DocData][FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc)] = new List>(); Doc.RemoveDocFromList(faceDoc[DocData], 'face_docList', imgDoc); faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.FaceDocDescriptors(faceDoc).filter(fd => !(imgDoc[DocData][FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc)] as List>).includes(fd))); }; -- cgit v1.2.3-70-g09d2 From 95071fa118ee36d7365250f10756dce335dc76d9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Aug 2024 11:00:14 -0400 Subject: more cleanup for face collections --- src/client/views/Main.tsx | 2 +- .../collectionFreeForm/FaceCollectionBox.tsx | 62 ++++++--- src/client/views/search/FaceRecognitionHandler.tsx | 151 +++++++++++---------- 3 files changed, 121 insertions(+), 94 deletions(-) diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 5a408f593..023324881 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -138,7 +138,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; PresBox, PresElementBox, SearchBox, - ImageLabelBox, //Here! + ImageLabelBox, FaceCollectionBox, FunctionPlotBox, InkingStroke, diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index dd8dea41e..6005da6dd 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -26,18 +26,27 @@ import { FaceRecognitionHandler } from '../../search/FaceRecognitionHandler'; import './FaceCollectionBox.scss'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; -interface FaceDocumentProps { +/** + * This code is used to render the sidebar collection of unique recognized faces, where each + * unique face in turn displays the set of images that correspond to the face. + */ + +interface UniqueFaceProps { faceDoc: Doc; } /** - * A componenent to visually represent a Face Document. + * React component for rendering a unique face and its collection of image Docs. + * + * This both displays a collection of images corresponding tp a unique face, and + * allows for editing the face collection by removing an image, or drag-and-dropping + * an image that was not recognized. */ @observer -export class FaceDocumentItem extends ObservableReactComponent { +export class UniqueFaceView extends ObservableReactComponent { private _dropDisposer?: DragManager.DragDropDisposer; - constructor(props: FaceDocumentProps) { + constructor(props: UniqueFaceProps) { super(props); makeObservable(this); } @@ -54,12 +63,12 @@ export class FaceDocumentItem extends ObservableReactComponent doc.type === DocumentType.IMG) .forEach(imgDoc => { // If the current Face Document has no faces, and the doc has more than one face descriptor, don't let the user add the document first. Or should we just use the first face ? - if (FaceRecognitionHandler.FaceDocDescriptors(this._props.faceDoc).length === 0 && FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).length > 1) { + if (FaceRecognitionHandler.UniqueFaceDescriptors(this._props.faceDoc).length === 0 && FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).length > 1) { alert('Cannot add a document with multiple faces as the first item!'); } else { // Loop through the documents' face descriptors and choose the face in the iage with the smallest distance (most similar to the face colleciton) - const faceDescriptorsAsFloat32Array = FaceRecognitionHandler.FaceDocDescriptors(this._props.faceDoc).map(fd => new Float32Array(Array.from(fd))); - const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.FaceDocLabel(this._props.faceDoc), faceDescriptorsAsFloat32Array); + const faceDescriptorsAsFloat32Array = FaceRecognitionHandler.UniqueFaceDescriptors(this._props.faceDoc).map(fd => new Float32Array(Array.from(fd))); + const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(this._props.faceDoc), faceDescriptorsAsFloat32Array); const faceMatcher = new FaceMatcher([labeledFaceDescriptor], 1); const { face_match } = FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).reduce( (prev, face) => { @@ -71,8 +80,8 @@ export class FaceDocumentItem extends ObservableReactComponent { - FaceRecognitionHandler.DeleteFaceDoc(this._props.faceDoc); + deleteUniqueFace = undoable(() => { + FaceRecognitionHandler.DeleteUniqueFace(this._props.faceDoc); }, 'delete face'); /** - * Deletes a document from a Face Document's associated docs list. - * @param doc + * Removes a face image Doc from a unique face's list of images. + * @param imgDoc - image Doc to remove */ - deleteAssociatedDoc = undoable((imgDoc: Doc) => { - FaceRecognitionHandler.FaceDocRemoveImageDocFace(imgDoc, this._props.faceDoc); + removeFaceImageFromUniqueFace = undoable((imgDoc: Doc) => { + FaceRecognitionHandler.ImageDocDeassociateUniqueFace(imgDoc, this._props.faceDoc); + FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, this._props.faceDoc); }, 'remove doc from face'); render() { return (
this.createDropTarget(ele!)}>
- +
-

{FaceRecognitionHandler.FaceDocLabel(this._props.faceDoc)}

+

{FaceRecognitionHandler.UniqueFaceLabel(this._props.faceDoc)}

{this._displayImages ? (
- {FaceRecognitionHandler.FaceDocFaces(this._props.faceDoc).map(doc => { + {FaceRecognitionHandler.UniqueFaceImages(this._props.faceDoc).map(doc => { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return (
DocumentView.showDocument(doc, { willZoomCentered: true })} style={{ maxWidth: '60px', margin: '10px' }} src={`${name}_o.${type}`} />
- this.deleteAssociatedDoc(doc)} icon={'x'} style={{ width: '4px' }} size={Size.XSMALL} /> + this.removeFaceImageFromUniqueFace(doc)} icon={'x'} style={{ width: '4px' }} size={Size.XSMALL} />
); @@ -152,6 +162,14 @@ export class FaceDocumentItem extends ObservableReactComponent() { public static LayoutString(fieldKey: string) { @@ -166,8 +184,8 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { render() { return (
- {FaceRecognitionHandler.FaceDocuments().map(doc => ( - + {FaceRecognitionHandler.UniqueFaces().map(doc => ( + ))}
); diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index c446df6ff..c239c775c 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -1,6 +1,5 @@ import * as faceapi from 'face-api.js'; import { FaceMatcher } from 'face-api.js'; -import { computed } from 'mobx'; import { Doc, DocListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; @@ -12,28 +11,27 @@ import { DocumentManager } from '../../util/DocumentManager'; /** * A singleton class that handles face recognition and manages face Doc collections for each face found. * Displaying an image doc anywhere will trigger this class to test if the image contains any faces. - * If it does, each recognized face will be compared to a global set of faces (each is a face collection Doc - * that have already been found. If the face matches a face collection Doc, then it will be added to that + * If it does, each recognized face will be compared to a stored, global set of faces (each face is represented + * as a face collection Doc). If the face matches a face collection Doc, then it will be added to that * collection along with the numerical representation of the face, its face descriptor. * * Image Doc's that are added to one or more face collection Docs will be given these metadata fields: - * _Face - a nunerical representation of the Nth face found in the image - * _Faces - a list of all the numerical face representations found in the image (why is this needed?) + * _Face - a numerical representation of the Nth face found in the image + * _Faces - a list of all the numerical face representations found in the image. (TODO: this is inelegant as it duplicates each Face) * - * Face collection Doc's are created for each person identified and are stored in the Dashboard's faceDocument's list + * unique face Doc's are created for each person identified and are stored in the Dashboard's uniqueFaces field * - * Each Face collection Doc represents all the images found for that person. It has these fields: - * face_label - a string label for the person that was recognized (currently it's just a 'face#') + * Each unique face Doc represents a unique face and collects all matching face images for that person. It has these fields: + * face_label - a string label for the person that was recognized (TODO: currently it's just a 'face#') * face_descriptors - a list of all the face descriptors for different images of the person * face_docList - a list of all image Docs that contain a face for the person */ export class FaceRecognitionHandler { static _instance: FaceRecognitionHandler; private _loadedModels: boolean = false; - private _processingDocs: Set = new Set(); private _pendingLoadDocs: Doc[] = []; - private static imgDocFaceField = (imgDoc: Doc, faceDoc: Doc) => `${Doc.LayoutFieldKey(imgDoc)}_${FaceRecognitionHandler.FaceDocLabel(faceDoc)}`; + private static imgDocFaceField = (imgDoc: Doc, faceDoc: Doc) => `${Doc.LayoutFieldKey(imgDoc)}_${FaceRecognitionHandler.UniqueFaceLabel(faceDoc)}`; /** * initializes an image with an empty list of face descriptors * @param imgDoc image to initialize @@ -49,67 +47,82 @@ export class FaceRecognitionHandler { public static ImageDocFaceDescriptors = (imgDoc: Doc) => imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`] as List>; /** - * Adds metadata to an image Doc describing a face found in the image + * Adds metadata to an image Doc associating it to a unique face that corresponds to a face found in the image * @param imgDoc image Doc containing faces - * @param faceDescriptor descriptor for the face found - * @param faceDoc face collection Doc containing the same face + * @param faceDescriptor descriptor for the face + * @param faceDoc unique face */ - public static ImageDocAddFace = (imgDoc: Doc, faceDescriptor: List, faceDoc: Doc) => { + public static ImageDocAssociateUniqueFace = (imgDoc: Doc, faceDescriptor: List, faceDoc: Doc) => { const faceFieldKey = FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc); if (imgDoc[DocData][faceFieldKey]) { Cast(imgDoc[DocData][faceFieldKey], listSpec('number'), null).push(faceDescriptor as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that } else { imgDoc[DocData][faceFieldKey] = new List>([faceDescriptor]); } + Cast(imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`], listSpec('number'), null).push(faceDescriptor as unknown as number); + }; + + /** + * Removes metadata from an image Doc to deassociate it from a unique face + * @param imgDoc image Doc containing faces + * @param faceDoc unique face + */ + public static ImageDocDeassociateUniqueFace = (imgDoc: Doc, faceDoc: Doc) => { + // fill in.. }; /** * returns a list of all face collection Docs on the current dashboard * @returns face collection Doc list */ - public static FaceDocuments = () => DocListCast(Doc.ActiveDashboard?.[DocData].faceDocuments); + public static UniqueFaces = () => DocListCast(Doc.ActiveDashboard?.[DocData].uniqueFaces); - public static DeleteFaceDoc = (faceDoc: Doc) => Doc.ActiveDashboard && Doc.RemoveDocFromList(Doc.ActiveDashboard[DocData], 'faceDocuments', faceDoc); + /** + * Removes a unique face from the set of recognized unique faces + * @param faceDoc unique face Doc + * @returns + */ + public static DeleteUniqueFace = (faceDoc: Doc) => Doc.ActiveDashboard && Doc.RemoveDocFromList(Doc.ActiveDashboard[DocData], 'uniqueFaces', faceDoc); /** * returns the labels associated with a face collection Doc - * @param faceDoc the face collection Doc + * @param faceDoc unique face Doc * @returns label string */ - public static FaceDocLabel = (faceDoc: Doc) => StrCast(faceDoc[DocData].face_label); + public static UniqueFaceLabel = (faceDoc: Doc) => StrCast(faceDoc[DocData].face_label); /** - * Returns all the face descriptors associated with a face collection Doc - * @param faceDoc a face collection Doc + * Returns all the face descriptors associated with a unique face Doc + * @param faceDoc unique face Doc * @returns face descriptors */ - public static FaceDocDescriptors = (faceDoc: Doc) => faceDoc[DocData].face_descriptors as List>; + public static UniqueFaceDescriptors = (faceDoc: Doc) => faceDoc[DocData].face_descriptors as List>; /** - * Returns a list of all face image Docs associated with the face collection - * @param faceDoc a face collection Doc + * Returns a list of all face image Docs associated with a unique face Doc + * @param faceDoc unique face Doc * @returns image Docs */ - public static FaceDocFaces = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_docList); + public static UniqueFaceImages = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_images); /** - * Adds a face image to the list of faces in a face collection Doc, and updates the face collection's list of image descriptors + * Adds a face image to a unique face Doc, and updates the unique face's set of face image descriptors * @param img - image with faces to add to a face collection Doc * @param faceDescriptor - the face descriptor for the face in the image to add - * @param faceDoc - the face collection Doc + * @param faceDoc - unique face Doc */ - public static FaceDocAddImageDocFace = (img: Doc, faceDescriptor: List, faceDoc: Doc) => { - Doc.AddDocToList(faceDoc, 'face_docList', img); + public static UniqueFaceAddFaceImage = (img: Doc, faceDescriptor: List, faceDoc: Doc) => { + Doc.AddDocToList(faceDoc, 'face_images', img); Cast(faceDoc.face_descriptors, listSpec('number'), null).push(faceDescriptor as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that }; /** - * Removes a face from a face Doc collection, and updates the face collection's list of image descriptors - * @param imgDoc - image with faces to remove from the face Doc collectoin - * @param faceDoc - the face Doc collection + * Removes a face from a unique Face Doc, and updates the unique face's set of face image descriptors + * @param imgDoc - image with faces to remove + * @param faceDoc - unique face Doc */ - public static FaceDocRemoveImageDocFace = (imgDoc: Doc, faceDoc: Doc) => { - Doc.RemoveDocFromList(faceDoc[DocData], 'face_docList', imgDoc); - faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.FaceDocDescriptors(faceDoc).filter(fd => !(imgDoc[DocData][FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc)] as List>).includes(fd))); + public static UniqueFaceRemoveFaceImage = (imgDoc: Doc, faceDoc: Doc) => { + Doc.RemoveDocFromList(faceDoc[DocData], 'face_images', imgDoc); + faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).filter(fd => !(imgDoc[DocData][FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc)] as List>).includes(fd))); }; constructor() { @@ -118,10 +131,6 @@ export class FaceRecognitionHandler { DocumentManager.Instance.AddAnyViewRenderedCB(dv => FaceRecognitionHandler.Instance.classifyFacesInImage(dv.Document)); } - @computed get examinedFaceDocs() { - return DocListCast(Doc.UserDoc().examinedFaceDocs); - } - /** * Loads the face detection models. */ @@ -138,7 +147,27 @@ export class FaceRecognitionHandler { } /** - * When a document is added, look for matching face documents. + * Creates a new, empty unique face Doc + * @returns a unique face Doc + */ + createUniqueFaceDoc = (dashboard: Doc) => { + const faceDocNum = NumCast(dashboard.uniqueFaces_count) + 1; + dashboard.uniqueFaces_count = faceDocNum; // TODO: improve to a better name + + const uniqueFaceDoc = new Doc(); + uniqueFaceDoc.title = `Face ${faceDocNum}`; + uniqueFaceDoc.face = ''; // just to make prettyprinting look better + uniqueFaceDoc.face_label = `Face${faceDocNum}`; + uniqueFaceDoc.face_images = new List(); + uniqueFaceDoc.face_descriptors = new List>(); + + Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'uniqueFaces', uniqueFaceDoc); + return uniqueFaceDoc; + }; + + /** + * When a document is added, this finds faces in the images and tries to + * match them to existing unique faces, otherwise new unique face(s) are created. * @param imgDoc The document being analyzed. */ public classifyFacesInImage = async (imgDoc: Doc) => { @@ -154,12 +183,11 @@ export class FaceRecognitionHandler { const imgUrl = ImageCast(imgDoc[Doc.LayoutFieldKey(imgDoc)]); // If the doc isn't an image or currently already been examined or is being processed, stop examining the document. - if (!imgUrl || this.examinedFaceDocs.includes(imgDoc) || this._processingDocs.has(imgDoc)) { + if (!imgUrl || DocListCast(Doc.MyFaceCollection.examinedFaceDocs).includes(imgDoc)) { return; } + Doc.AddDocToList(Doc.MyFaceCollection, 'examinedFaceDocs', imgDoc); - // Mark the document as being processed. - this._processingDocs.add(imgDoc); FaceRecognitionHandler.initImageDocFaceDescriptors(imgDoc); // Get the image the document contains and analyze for faces. @@ -170,31 +198,12 @@ export class FaceRecognitionHandler { // For each face detected, find a match. for (const fd of imgDocFaceDescriptions) { - let faceDocMatch = this.findMatchingFaceDoc(fd.descriptor); const faceDescriptor = new List(Array.from(fd.descriptor)); - - if (faceDocMatch) { - FaceRecognitionHandler.FaceDocAddImageDocFace(imgDoc, faceDescriptor, faceDocMatch); - } else { - // If a matching Face Document has not been found, create a new Face Document. - Doc.UserDoc().faceDocNum = NumCast(Doc.UserDoc().faceDocNum) + 1; - - const newFaceDocument = new Doc(); - newFaceDocument.title = `Face ${Doc.UserDoc().faceDocNum}`; - newFaceDocument.face = ''; // just to make prettyprinting look better - newFaceDocument.face_label = `Face${Doc.UserDoc().faceDocNum}`; - newFaceDocument.face_docList = new List([imgDoc]); - newFaceDocument.face_descriptors = new List>([faceDescriptor]); - - Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'faceDocuments', newFaceDocument); - faceDocMatch = newFaceDocument; - } - - // Assign a field in the document of the matching Face Document. - FaceRecognitionHandler.ImageDocAddFace(imgDoc, faceDescriptor, faceDocMatch); - Doc.AddDocToList(Doc.UserDoc(), 'examinedFaceDocs', imgDoc); + const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(Doc.ActiveDashboard); + // Add image to unique face's image collection, and assign image metadata referencing unique face + FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); + FaceRecognitionHandler.ImageDocAssociateUniqueFace(imgDoc, faceDescriptor, matchedUniqueFace); } - this._processingDocs.delete(imgDoc); }; /** @@ -203,19 +212,19 @@ export class FaceRecognitionHandler { * @returns face Doc */ private findMatchingFaceDoc = (faceDescriptor: Float32Array) => { - if (!Doc.ActiveDashboard || FaceRecognitionHandler.FaceDocuments().length < 1) { + if (!Doc.ActiveDashboard || FaceRecognitionHandler.UniqueFaces().length < 1) { return undefined; } - const faceDescriptors = FaceRecognitionHandler.FaceDocuments().map(faceDoc => { - const float32Array = FaceRecognitionHandler.FaceDocDescriptors(faceDoc).map(fd => new Float32Array(Array.from(fd))); - return new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.FaceDocLabel(faceDoc), float32Array); + const faceDescriptors = FaceRecognitionHandler.UniqueFaces().map(faceDoc => { + const float32Array = FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).map(fd => new Float32Array(Array.from(fd))); + return new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(faceDoc), float32Array); }); const faceMatcher = new FaceMatcher(faceDescriptors, 0.6); const match = faceMatcher.findBestMatch(faceDescriptor); if (match.label !== 'unknown') { - for (const faceDoc of FaceRecognitionHandler.FaceDocuments()) { - if (FaceRecognitionHandler.FaceDocLabel(faceDoc) === match.label) { + for (const faceDoc of FaceRecognitionHandler.UniqueFaces()) { + if (FaceRecognitionHandler.UniqueFaceLabel(faceDoc) === match.label) { return faceDoc; } } -- cgit v1.2.3-70-g09d2 From a1f90b7c3a99aff9366a353631ea963c778b4740 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Aug 2024 11:16:39 -0400 Subject: fixing up removing faces from unique faces --- .../collectionFreeForm/FaceCollectionBox.tsx | 2 +- src/client/views/search/FaceRecognitionHandler.tsx | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 6005da6dd..d1db19e43 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -108,8 +108,8 @@ export class UniqueFaceView extends ObservableReactComponent { * @param imgDoc - image Doc to remove */ removeFaceImageFromUniqueFace = undoable((imgDoc: Doc) => { - FaceRecognitionHandler.ImageDocDeassociateUniqueFace(imgDoc, this._props.faceDoc); FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, this._props.faceDoc); + FaceRecognitionHandler.ImageDocDisassociateUniqueFace(imgDoc, this._props.faceDoc); }, 'remove doc from face'); render() { diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index c239c775c..487c35d90 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -46,6 +46,15 @@ export class FaceRecognitionHandler { */ public static ImageDocFaceDescriptors = (imgDoc: Doc) => imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`] as List>; + /** + * Adds a face descriptor for a face found in an image + * @param imgDoc image Doc with face + * @param faceDescriptor descriptor of a face + */ + public static ImageDocAddFaceDescriptor = (imgDoc: Doc, faceDescriptor: List) => { + Cast(imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`], listSpec('number'), null).push(faceDescriptor as unknown as number); + }; + /** * Adds metadata to an image Doc associating it to a unique face that corresponds to a face found in the image * @param imgDoc image Doc containing faces @@ -59,7 +68,6 @@ export class FaceRecognitionHandler { } else { imgDoc[DocData][faceFieldKey] = new List>([faceDescriptor]); } - Cast(imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`], listSpec('number'), null).push(faceDescriptor as unknown as number); }; /** @@ -67,10 +75,10 @@ export class FaceRecognitionHandler { * @param imgDoc image Doc containing faces * @param faceDoc unique face */ - public static ImageDocDeassociateUniqueFace = (imgDoc: Doc, faceDoc: Doc) => { - // fill in.. + public static ImageDocDisassociateUniqueFace = (imgDoc: Doc, faceDoc: Doc) => { + const faceFieldKey = FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc); + imgDoc[DocData][faceFieldKey] = undefined; }; - /** * returns a list of all face collection Docs on the current dashboard * @returns face collection Doc list @@ -122,7 +130,8 @@ export class FaceRecognitionHandler { */ public static UniqueFaceRemoveFaceImage = (imgDoc: Doc, faceDoc: Doc) => { Doc.RemoveDocFromList(faceDoc[DocData], 'face_images', imgDoc); - faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).filter(fd => !(imgDoc[DocData][FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc)] as List>).includes(fd))); + // TODO: remove face descriptor from images' list of face descriptors (below doesn't work) + // faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).filter(fd => !(imgDoc[DocData][FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc)] as List>).includes(fd))); }; constructor() { @@ -203,6 +212,8 @@ export class FaceRecognitionHandler { // Add image to unique face's image collection, and assign image metadata referencing unique face FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); FaceRecognitionHandler.ImageDocAssociateUniqueFace(imgDoc, faceDescriptor, matchedUniqueFace); + // save the descriptor for the image's list of faces + FaceRecognitionHandler.ImageDocAddFaceDescriptor(imgDoc, faceDescriptor); } }; -- cgit v1.2.3-70-g09d2 From abac2baf512a545714379fbef3623b46e3be20a8 Mon Sep 17 00:00:00 2001 From: geireann Date: Thu, 22 Aug 2024 13:38:03 -0400 Subject: changes to face recognition to store list of face docs , not descriptors on images. --- .../collectionFreeForm/FaceCollectionBox.tsx | 2 - src/client/views/search/FaceRecognitionHandler.tsx | 61 +++++++++------------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index d1db19e43..46d90db86 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -80,7 +80,6 @@ export class UniqueFaceView extends ObservableReactComponent { // assign the face in the image that's closest to the face collection to be the face that's assigned to the collection if (face_match) { - FaceRecognitionHandler.ImageDocAssociateUniqueFace(imgDoc, face_match, this._props.faceDoc); FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, face_match, this._props.faceDoc); } } @@ -109,7 +108,6 @@ export class UniqueFaceView extends ObservableReactComponent { */ removeFaceImageFromUniqueFace = undoable((imgDoc: Doc) => { FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, this._props.faceDoc); - FaceRecognitionHandler.ImageDocDisassociateUniqueFace(imgDoc, this._props.faceDoc); }, 'remove doc from face'); render() { diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 487c35d90..f00c3fdf1 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -16,8 +16,7 @@ import { DocumentManager } from '../../util/DocumentManager'; * collection along with the numerical representation of the face, its face descriptor. * * Image Doc's that are added to one or more face collection Docs will be given these metadata fields: - * _Face - a numerical representation of the Nth face found in the image - * _Faces - a list of all the numerical face representations found in the image. (TODO: this is inelegant as it duplicates each Face) + * _faceDescriptors - a list of all the numerical face representations found in the image. * * unique face Doc's are created for each person identified and are stored in the Dashboard's uniqueFaces field * @@ -31,20 +30,34 @@ export class FaceRecognitionHandler { private _loadedModels: boolean = false; private _pendingLoadDocs: Doc[] = []; - private static imgDocFaceField = (imgDoc: Doc, faceDoc: Doc) => `${Doc.LayoutFieldKey(imgDoc)}_${FaceRecognitionHandler.UniqueFaceLabel(faceDoc)}`; + + /** + * return the metadata field name where unique face Docs are stored + * @param imgDoc image with faces + * @returns name of field + */ + private static ImageDocFaceField = (imgDoc: Doc) => `${Doc.LayoutFieldKey(imgDoc)}_faces`; + + /** + * Returns an array of faceDocs for each face recognized in the image + * @param imgDoc image with faces + * @returns faceDoc array + */ + private static ImageDocFaces = (imgDoc: Doc) => DocListCast(imgDoc[`${Doc.LayoutFieldKey(imgDoc)}_faces`]); + /** * initializes an image with an empty list of face descriptors * @param imgDoc image to initialize */ private static initImageDocFaceDescriptors = (imgDoc: Doc) => { - imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`] = new List>(); + imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_faceDescriptors`] = new List>(); }; /** * returns the face descriptors for each face found on an image Doc * @param imgDoc * @returns list of face descriptors */ - public static ImageDocFaceDescriptors = (imgDoc: Doc) => imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`] as List>; + public static ImageDocFaceDescriptors = (imgDoc: Doc) => imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_faceDescriptors`] as List>; /** * Adds a face descriptor for a face found in an image @@ -52,33 +65,10 @@ export class FaceRecognitionHandler { * @param faceDescriptor descriptor of a face */ public static ImageDocAddFaceDescriptor = (imgDoc: Doc, faceDescriptor: List) => { - Cast(imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_Faces`], listSpec('number'), null).push(faceDescriptor as unknown as number); + Cast(imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_faceDescriptors`], listSpec('number'), null).push(faceDescriptor as unknown as number); }; - /** - * Adds metadata to an image Doc associating it to a unique face that corresponds to a face found in the image - * @param imgDoc image Doc containing faces - * @param faceDescriptor descriptor for the face - * @param faceDoc unique face - */ - public static ImageDocAssociateUniqueFace = (imgDoc: Doc, faceDescriptor: List, faceDoc: Doc) => { - const faceFieldKey = FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc); - if (imgDoc[DocData][faceFieldKey]) { - Cast(imgDoc[DocData][faceFieldKey], listSpec('number'), null).push(faceDescriptor as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that - } else { - imgDoc[DocData][faceFieldKey] = new List>([faceDescriptor]); - } - }; - /** - * Removes metadata from an image Doc to deassociate it from a unique face - * @param imgDoc image Doc containing faces - * @param faceDoc unique face - */ - public static ImageDocDisassociateUniqueFace = (imgDoc: Doc, faceDoc: Doc) => { - const faceFieldKey = FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc); - imgDoc[DocData][faceFieldKey] = undefined; - }; /** * returns a list of all face collection Docs on the current dashboard * @returns face collection Doc list @@ -121,17 +111,19 @@ export class FaceRecognitionHandler { public static UniqueFaceAddFaceImage = (img: Doc, faceDescriptor: List, faceDoc: Doc) => { Doc.AddDocToList(faceDoc, 'face_images', img); Cast(faceDoc.face_descriptors, listSpec('number'), null).push(faceDescriptor as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that + Doc.AddDocToList(img[DocData], FaceRecognitionHandler.ImageDocFaceField(img), faceDoc); }; /** * Removes a face from a unique Face Doc, and updates the unique face's set of face image descriptors - * @param imgDoc - image with faces to remove + * @param img - image with faces to remove * @param faceDoc - unique face Doc */ - public static UniqueFaceRemoveFaceImage = (imgDoc: Doc, faceDoc: Doc) => { - Doc.RemoveDocFromList(faceDoc[DocData], 'face_images', imgDoc); - // TODO: remove face descriptor from images' list of face descriptors (below doesn't work) - // faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).filter(fd => !(imgDoc[DocData][FaceRecognitionHandler.imgDocFaceField(imgDoc, faceDoc)] as List>).includes(fd))); + public static UniqueFaceRemoveFaceImage = (img: Doc, faceDoc: Doc) => { + Doc.RemoveDocFromList(faceDoc[DocData], 'face_images', img); + const descriptorsEqual = (a:List, b:List) => a === b ? true : a.length === b.length ? a.every((element, index) => element === b[index]) : false; + faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).filter(fd => !FaceRecognitionHandler.ImageDocFaceDescriptors(img).some(desc => descriptorsEqual(fd, desc)))); + Doc.RemoveDocFromList(img[DocData], FaceRecognitionHandler.ImageDocFaceField(img), faceDoc); }; constructor() { @@ -211,7 +203,6 @@ export class FaceRecognitionHandler { const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(Doc.ActiveDashboard); // Add image to unique face's image collection, and assign image metadata referencing unique face FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); - FaceRecognitionHandler.ImageDocAssociateUniqueFace(imgDoc, faceDescriptor, matchedUniqueFace); // save the descriptor for the image's list of faces FaceRecognitionHandler.ImageDocAddFaceDescriptor(imgDoc, faceDescriptor); } -- cgit v1.2.3-70-g09d2 From 979bd048c3a55fb437352d01bdc5083d1a000084 Mon Sep 17 00:00:00 2001 From: geireann Date: Thu, 22 Aug 2024 13:43:03 -0400 Subject: eslint fix --- eslint.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 119f2f486..619966f20 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -47,7 +47,7 @@ export default [ 'no-return-assign': 'error', 'no-await-in-loop': 'error', 'no-loop-func': 'error', - 'no-conditional-assign': 'error', + 'no-cond-assign': 'error', 'no-use-before-define': 'error', 'no-explicit-any': 'error', 'no-restricted-globals': ['error', 'event'], -- cgit v1.2.3-70-g09d2 From f18978c507dd4c9c0940a1ce17daa2e7000bccdd Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Aug 2024 15:29:45 -0400 Subject: from last --- src/client/views/search/FaceRecognitionHandler.tsx | 116 ++++++++++----------- 1 file changed, 55 insertions(+), 61 deletions(-) diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index f00c3fdf1..9b97fdfbd 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -7,6 +7,7 @@ import { listSpec } from '../../../fields/Schema'; import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; +import { ImageField } from '../../../fields/URLField'; /** * A singleton class that handles face recognition and manages face Doc collections for each face found. @@ -16,7 +17,8 @@ import { DocumentManager } from '../../util/DocumentManager'; * collection along with the numerical representation of the face, its face descriptor. * * Image Doc's that are added to one or more face collection Docs will be given these metadata fields: - * _faceDescriptors - a list of all the numerical face representations found in the image. + * _faceDescriptors - list of all the numerical face representations found in the image. + * _faces - list of unique face Docs corresponding to recognized faces in the image. * * unique face Doc's are created for each person identified and are stored in the Dashboard's uniqueFaces field * @@ -27,14 +29,33 @@ import { DocumentManager } from '../../util/DocumentManager'; */ export class FaceRecognitionHandler { static _instance: FaceRecognitionHandler; - private _loadedModels: boolean = false; - private _pendingLoadDocs: Doc[] = []; + private _apiModelReady = false; + private _pendingAPIModelReadyDocs: Doc[] = []; + public static get Instance() { + return FaceRecognitionHandler._instance ?? new FaceRecognitionHandler(); + } + + /** + * Loads an image + */ + private static loadImage = (imgUrl: ImageField): Promise => { + const [name, type] = imgUrl.url.href.split('.'); + const imageURL = `${name}_o.${type}`; + + return new Promise((resolve, reject) => { + const img = new Image(); + img.crossOrigin = 'anonymous'; + img.onload = () => resolve(img); + img.onerror = err => reject(err); + img.src = imageURL; + }); + }; /** * return the metadata field name where unique face Docs are stored * @param imgDoc image with faces - * @returns name of field + * @returns name of field */ private static ImageDocFaceField = (imgDoc: Doc) => `${Doc.LayoutFieldKey(imgDoc)}_faces`; @@ -68,7 +89,6 @@ export class FaceRecognitionHandler { Cast(imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_faceDescriptors`], listSpec('number'), null).push(faceDescriptor as unknown as number); }; - /** * returns a list of all face collection Docs on the current dashboard * @returns face collection Doc list @@ -103,7 +123,8 @@ export class FaceRecognitionHandler { public static UniqueFaceImages = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_images); /** - * Adds a face image to a unique face Doc, and updates the unique face's set of face image descriptors + * Adds a face image to a unique face Doc, adds the unique face Doc to the images list of reognized faces, + * and updates the unique face's set of face image descriptors * @param img - image with faces to add to a face collection Doc * @param faceDescriptor - the face descriptor for the face in the image to add * @param faceDoc - unique face Doc @@ -121,37 +142,33 @@ export class FaceRecognitionHandler { */ public static UniqueFaceRemoveFaceImage = (img: Doc, faceDoc: Doc) => { Doc.RemoveDocFromList(faceDoc[DocData], 'face_images', img); - const descriptorsEqual = (a:List, b:List) => a === b ? true : a.length === b.length ? a.every((element, index) => element === b[index]) : false; + const descriptorsEqual = (a: List, b: List) => (a === b ? true : a.length === b.length ? a.every((element, index) => element === b[index]) : false); faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).filter(fd => !FaceRecognitionHandler.ImageDocFaceDescriptors(img).some(desc => descriptorsEqual(fd, desc)))); Doc.RemoveDocFromList(img[DocData], FaceRecognitionHandler.ImageDocFaceField(img), faceDoc); }; constructor() { FaceRecognitionHandler._instance = this; - this.loadModels().then(() => this._pendingLoadDocs.forEach(this.classifyFacesInImage)); + this.loadAPIModels().then(() => this._pendingAPIModelReadyDocs.forEach(this.classifyFacesInImage)); DocumentManager.Instance.AddAnyViewRenderedCB(dv => FaceRecognitionHandler.Instance.classifyFacesInImage(dv.Document)); } /** * Loads the face detection models. */ - loadModels = async () => { + private loadAPIModels = async () => { const MODEL_URL = `/models`; await faceapi.loadFaceDetectionModel(MODEL_URL); await faceapi.loadFaceLandmarkModel(MODEL_URL); await faceapi.loadFaceRecognitionModel(MODEL_URL); - this._loadedModels = true; + this._apiModelReady = true; }; - public static get Instance() { - return FaceRecognitionHandler._instance ?? new FaceRecognitionHandler(); - } - /** * Creates a new, empty unique face Doc * @returns a unique face Doc */ - createUniqueFaceDoc = (dashboard: Doc) => { + private createUniqueFaceDoc = (dashboard: Doc) => { const faceDocNum = NumCast(dashboard.uniqueFaces_count) + 1; dashboard.uniqueFaces_count = faceDocNum; // TODO: improve to a better name @@ -171,40 +188,30 @@ export class FaceRecognitionHandler { * match them to existing unique faces, otherwise new unique face(s) are created. * @param imgDoc The document being analyzed. */ - public classifyFacesInImage = async (imgDoc: Doc) => { - if (!this._loadedModels || !Doc.ActiveDashboard) { - this._pendingLoadDocs.push(imgDoc); - return; - } - - if (imgDoc.type === DocumentType.LOADING && !imgDoc.loadingError) { + private classifyFacesInImage = async (imgDoc: Doc) => { + const activeDashboard = Doc.ActiveDashboard; + if (!this._apiModelReady || !activeDashboard) { + this._pendingAPIModelReadyDocs.push(imgDoc); + } else if (imgDoc.type === DocumentType.LOADING && !imgDoc.loadingError) { setTimeout(() => this.classifyFacesInImage(imgDoc), 1000); - return; - } - - const imgUrl = ImageCast(imgDoc[Doc.LayoutFieldKey(imgDoc)]); - // If the doc isn't an image or currently already been examined or is being processed, stop examining the document. - if (!imgUrl || DocListCast(Doc.MyFaceCollection.examinedFaceDocs).includes(imgDoc)) { - return; - } - Doc.AddDocToList(Doc.MyFaceCollection, 'examinedFaceDocs', imgDoc); - - FaceRecognitionHandler.initImageDocFaceDescriptors(imgDoc); - - // Get the image the document contains and analyze for faces. - const [name, type] = imgUrl.url.href.split('.'); - const imageURL = `${name}_o.${type}`; - const img = await this.loadImage(imageURL); - const imgDocFaceDescriptions = await faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors(); - - // For each face detected, find a match. - for (const fd of imgDocFaceDescriptions) { - const faceDescriptor = new List(Array.from(fd.descriptor)); - const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(Doc.ActiveDashboard); - // Add image to unique face's image collection, and assign image metadata referencing unique face - FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); - // save the descriptor for the image's list of faces - FaceRecognitionHandler.ImageDocAddFaceDescriptor(imgDoc, faceDescriptor); + } else { + const imgUrl = ImageCast(imgDoc[Doc.LayoutFieldKey(imgDoc)]); + if (imgUrl && !DocListCast(Doc.MyFaceCollection.examinedFaceDocs).includes(imgDoc)) { // only examine Docs that have an image and that haven't already been examined. + Doc.AddDocToList(Doc.MyFaceCollection, 'examinedFaceDocs', imgDoc); + FaceRecognitionHandler.initImageDocFaceDescriptors(imgDoc); + FaceRecognitionHandler.loadImage(imgUrl).then( // load image and analyze faces + img => faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors() + .then(imgDocFaceDescriptions => { // For each face detected, find a match. + for (const fd of imgDocFaceDescriptions) { + const faceDescriptor = new List(Array.from(fd.descriptor)); + FaceRecognitionHandler.ImageDocAddFaceDescriptor(imgDoc, faceDescriptor); // add face descriptor to image's list of descriptors + const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(activeDashboard); + FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); // add image/faceDescriptor to matched unique face + } // + return imgDocFaceDescriptions; + }) + ); + } // prettier-ignore } }; @@ -233,17 +240,4 @@ export class FaceRecognitionHandler { } return undefined; }; - - /** - * Loads an image - */ - private loadImage = (src: string): Promise => { - return new Promise((resolve, reject) => { - const img = new Image(); - img.crossOrigin = 'anonymous'; - img.onload = () => resolve(img); - img.onerror = err => reject(err); - img.src = src; - }); - }; } -- cgit v1.2.3-70-g09d2 From c9c5514c0607dcacaf8b84ef4a7730a815451d98 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Aug 2024 15:36:41 -0400 Subject: from last --- .../collectionFreeForm/FaceCollectionBox.tsx | 2 +- src/client/views/search/FaceRecognitionHandler.tsx | 52 +++++++++++----------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 46d90db86..de7c2c027 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -75,7 +75,7 @@ export class UniqueFaceView extends ObservableReactComponent { const match = faceMatcher.matchDescriptor(new Float32Array(Array.from(face))); return match.distance < prev.dist ? { dist: match.distance, face_match: face } : prev; }, - { dist: 1, face_match: new List() as Opt> } + { dist: 1, face_match: undefined as Opt> } ); // assign the face in the image that's closest to the face collection to be the face that's assigned to the collection diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 9b97fdfbd..f5fc12a8d 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -183,6 +183,32 @@ export class FaceRecognitionHandler { return uniqueFaceDoc; }; + /** + * Finds the most similar matching Face Document to a face descriptor + * @param faceDescriptor face descriptor number list + * @returns face Doc + */ + private findMatchingFaceDoc = (faceDescriptor: Float32Array) => { + if (!Doc.ActiveDashboard || FaceRecognitionHandler.UniqueFaces().length < 1) { + return undefined; + } + + const faceDescriptors = FaceRecognitionHandler.UniqueFaces().map(faceDoc => { + const float32Array = FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).map(fd => new Float32Array(Array.from(fd))); + return new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(faceDoc), float32Array); + }); + const faceMatcher = new FaceMatcher(faceDescriptors, 0.6); + const match = faceMatcher.findBestMatch(faceDescriptor); + if (match.label !== 'unknown') { + for (const faceDoc of FaceRecognitionHandler.UniqueFaces()) { + if (FaceRecognitionHandler.UniqueFaceLabel(faceDoc) === match.label) { + return faceDoc; + } + } + } + return undefined; + }; + /** * When a document is added, this finds faces in the images and tries to * match them to existing unique faces, otherwise new unique face(s) are created. @@ -214,30 +240,4 @@ export class FaceRecognitionHandler { } // prettier-ignore } }; - - /** - * Finds the most similar matching Face Document to a face descriptor - * @param faceDescriptor face descriptor number list - * @returns face Doc - */ - private findMatchingFaceDoc = (faceDescriptor: Float32Array) => { - if (!Doc.ActiveDashboard || FaceRecognitionHandler.UniqueFaces().length < 1) { - return undefined; - } - - const faceDescriptors = FaceRecognitionHandler.UniqueFaces().map(faceDoc => { - const float32Array = FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).map(fd => new Float32Array(Array.from(fd))); - return new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(faceDoc), float32Array); - }); - const faceMatcher = new FaceMatcher(faceDescriptors, 0.6); - const match = faceMatcher.findBestMatch(faceDescriptor); - if (match.label !== 'unknown') { - for (const faceDoc of FaceRecognitionHandler.UniqueFaces()) { - if (FaceRecognitionHandler.UniqueFaceLabel(faceDoc) === match.label) { - return faceDoc; - } - } - } - return undefined; - }; } -- cgit v1.2.3-70-g09d2 From efb80649dc524d152b424c8c539e4fee33450403 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Aug 2024 15:54:00 -0400 Subject: added '@' prefix syntax to show metadata field value in keywords box --- src/client/views/KeywordBox.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx index fc9c38a11..20cb63d66 100644 --- a/src/client/views/KeywordBox.tsx +++ b/src/client/views/KeywordBox.tsx @@ -13,6 +13,7 @@ import { DragManager } from '../util/DragManager'; import { SnappingManager } from '../util/SnappingManager'; import { DocumentView } from './nodes/DocumentView'; import { ObservableReactComponent } from './ObservableReactComponent'; +import { undoable } from '../util/UndoManager'; interface KeywordItemProps { doc: Doc; @@ -123,9 +124,18 @@ export class KeywordItem extends ObservableReactComponent { }; render() { + const keyword = this._props.keyword.replace(/^@/, ''); + const metadata = this._props.keyword.startsWith('@'); return (
- {this._props.keyword} + {metadata ? ( + + {keyword}  + {this._props.doc[keyword] as string}{' '} + + ) : ( + keyword + )} {this.props.isEditing && }
); @@ -218,7 +228,7 @@ export class KeywordBox extends ObservableReactComponent { * Adds the keyword to the document. * @param keyword */ - submitLabel = (keyword: string) => { + submitLabel = undoable((keyword: string) => { // If the active Dashboard does not have a keyword collection, create it. if (Doc.ActiveDashboard && !Doc.ActiveDashboard.myKeywordCollections) { Doc.ActiveDashboard.myKeywordCollections = new List(); @@ -261,7 +271,7 @@ export class KeywordBox extends ObservableReactComponent { this._props.doc![DocData][`${submittedLabel}`] = true; this._currentInput = ''; // Clear the input box } - }; + }, 'added doc label'); @action onInputChange = (e: React.ChangeEvent) => { -- cgit v1.2.3-70-g09d2 From add4926f62b397fc6c655be31a711dd7b83b469a Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 23 Aug 2024 00:45:10 -0400 Subject: starting to cleanup keywordsBox --- src/client/views/KeywordBox.tsx | 390 +++++++++++++++++-------------------- src/client/views/StyleProvider.tsx | 8 +- 2 files changed, 180 insertions(+), 218 deletions(-) diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx index 20cb63d66..703299ae6 100644 --- a/src/client/views/KeywordBox.tsx +++ b/src/client/views/KeywordBox.tsx @@ -3,17 +3,17 @@ import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; import { returnFalse, setupMoveUpEvents } from '../../ClientUtils'; -import { Doc, DocListCast } from '../../fields/Doc'; +import { Utils, emptyFunction } from '../../Utils'; +import { Doc, DocListCast, StrListCast } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; import { NumCast, StrCast } from '../../fields/Types'; -import { emptyFunction, Utils } from '../../Utils'; import { DocumentType } from '../documents/DocumentTypes'; import { DragManager } from '../util/DragManager'; +import { SelectionManager } from '../util/SelectionManager'; import { SnappingManager } from '../util/SnappingManager'; -import { DocumentView } from './nodes/DocumentView'; -import { ObservableReactComponent } from './ObservableReactComponent'; import { undoable } from '../util/UndoManager'; +import { ObservableReactComponent } from './ObservableReactComponent'; interface KeywordItemProps { doc: Doc; @@ -28,69 +28,149 @@ interface KeywordItemProps { */ @observer export class KeywordItem extends ObservableReactComponent { - constructor(props: any) { - super(props); - makeObservable(this); - this.ref = React.createRef(); + /** + * return list of all Docs that collect Docs with specified keywords + */ + public static get AllKeywordCollections() { + return DocListCast(Doc.ActiveDashboard?.myKeywordCollections); } + /** + * Find Doc that collects all Docs with given keyword + * @param keyword keyword string + * @returns keyword collection Doc or undefined + */ + public static findKeywordCollectionDoc = (keyword: String) => KeywordItem.AllKeywordCollections.find(doc => doc.title === keyword); - private ref: React.RefObject; + /** + * Creates a Doc that collects Docs with the specified keyword + * @param keyword keyword string + * @returns collection Doc + */ + public static createKeywordCollectionDoc = (keyword: string) => { + const newKeywordCol = new Doc(); + newKeywordCol.title = keyword; + newKeywordCol.collections = new List(); + newKeywordCol[DocData].docs = new List(); + // If the active Dashboard does not have a keyword collection, create it. + if (Doc.ActiveDashboard) { + if (!Doc.ActiveDashboard.myKeywordCollections) Doc.ActiveDashboard.myKeywordCollections = new List(); + Doc.AddDocToList(Doc.ActiveDashboard, 'myKeywordCollections', newKeywordCol); + } + return newKeywordCol; + }; /** - * Gets the documents that a keyword is associated with. + * Gets all Docs that have the specified keyword + * @param keyword keyword string * @returns An array of documents that contain the keyword. */ - getKeywordCollectionDocs = () => { - for (const doc of DocListCast(Doc.ActiveDashboard?.myKeywordCollections)) { - if (doc.title === this._props.keyword) { - return doc[DocData].docs; + public static allDocsWithKeyword = (keyword: string) => DocListCast(KeywordItem.findKeywordCollectionDoc(keyword)?.[DocData].docs); + + /** + * Adds a keyword to the metadata of this document + * @param keyword keyword string + */ + public static addLabelToDoc = (doc: Doc, keyword: string) => { + // If the keyword collection is not in active Dashboard, add it as a new doc, with the keyword as its title. + const keywordCollection = KeywordItem.findKeywordCollectionDoc(keyword) ?? KeywordItem.createKeywordCollectionDoc(keyword); + + // If the document is of type COLLECTION, make it a smart collection, otherwise, add the keyword to the document. + if (doc.type === DocumentType.COL) { + Doc.AddDocToList(keywordCollection[DocData], 'collections', doc); + + // Iterate through the keyword Doc collections and add a copy of the document to each collection + for (const cdoc of DocListCast(keywordCollection[DocData].docs)) { + if (!DocListCast(doc[DocData].data).find(d => Doc.AreProtosEqual(d, cdoc))) { + const newEmbedding = Doc.MakeEmbedding(cdoc); + Doc.AddDocToList(doc[DocData], 'data', newEmbedding); + Doc.SetContainer(newEmbedding, doc); + } + } + } else { + // Add this document to the keyword's collection of associated documents. + Doc.AddDocToList(keywordCollection[DocData], 'docs', doc); + + // Iterate through the keyword document's collections and add a copy of the document to each collection + for (const collection of DocListCast(keywordCollection.collections)) { + if (!DocListCast(collection[DocData].data).find(d => Doc.AreProtosEqual(d, doc))) { + const newEmbedding = Doc.MakeEmbedding(doc); + Doc.AddDocToList(collection[DocData], 'data', newEmbedding); + Doc.SetContainer(newEmbedding, collection); + } } } - return null; + + if (!doc[DocData].data_labels) doc[DocData].data_labels = new List(); + (doc[DocData].data_labels as List).push(keyword); + doc[DocData][keyword] = true; }; + public static RemoveLabel = (doc: Doc, keyword: string, keywordDoc: Doc) => { + if (doc[DocData].data_labels) { + if (doc.type === DocumentType.COL) { + Doc.RemoveDocFromList(keywordDoc[DocData], 'collections', doc); + + for (const cur_doc of KeywordItem.allDocsWithKeyword(keyword)) { + doc[DocData].data = new List(DocListCast(doc[DocData].data).filter(d => !Doc.AreProtosEqual(cur_doc, d))); + } + } else { + Doc.RemoveDocFromList(keywordDoc[DocData], 'docs', doc); + + for (const collection of DocListCast(keywordDoc.collections)) { + collection[DocData].data = new List(DocListCast(collection[DocData].data).filter(d => !Doc.AreProtosEqual(doc, d))); + } + } + } + doc[DocData].data_labels = new List((doc[DocData].data_labels as List).filter(label => label !== keyword)); + doc[DocData][keyword] = undefined; + }; + + private _ref: React.RefObject; + + constructor(props: any) { + super(props); + makeObservable(this); + this._ref = React.createRef(); + } + /** * Creates a smart collection. * @returns */ createCollection = () => { // Get the documents that contain the keyword. - const selected = DocListCast(this.getKeywordCollectionDocs()!); - const newEmbeddings = selected.map(doc => Doc.MakeEmbedding(doc)); + const newEmbeddings = KeywordItem.allDocsWithKeyword(this._props.keyword).map(doc => Doc.MakeEmbedding(doc)); // Create a new collection and set up configurations. const newCollection = ((doc: Doc) => { const docData = doc[DocData]; docData.data = new List(newEmbeddings); docData.title = this._props.keyword; + docData.data_labels = new List([this._props.keyword]); + docData[`${this._props.keyword}`] = true; + docData.showLabels = true; doc._freeform_panX = doc._freeform_panY = 0; + doc._width = 900; + doc._height = 900; + doc.layout_fitWidth = true; return doc; })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true)); - newEmbeddings.forEach(embed => (embed.embedContainer = newCollection)); - newCollection._width = 900; - newCollection._height = 900; - newCollection.layout_fitWidth = true; + newEmbeddings.forEach(embed => Doc.SetContainer(embed, newCollection)); // Add the collection to the keyword document's list of associated smart collections. - this._props.keywordDoc.collections = new List([...DocListCast(this._props.keywordDoc.collections), newCollection]); - newCollection[DocData].data_labels = new List([this._props.keyword]); - newCollection[DocData][`${this._props.keyword}`] = true; - newCollection[DocData].showLabels = true; + Doc.AddDocToList(this._props.keywordDoc, 'collections', newCollection); return newCollection; }; @action handleDragStart = (e: React.PointerEvent) => { if (this._props.isEditing) { - const clone = this.ref.current?.cloneNode(true) as HTMLElement; - if (!clone) return; - setupMoveUpEvents( this, e, () => { const dragData = new DragManager.DocumentDragData([this.createCollection()]); - DragManager.StartDocumentDrag([this.ref.current!], dragData, e.clientX, e.clientY, {}); + DragManager.StartDocumentDrag([this._ref.current!], dragData, e.clientX, e.clientY, {}); return true; }, returnFalse, @@ -100,51 +180,34 @@ export class KeywordItem extends ObservableReactComponent { } }; - @action - removeLabel = () => { - if (this._props.doc[DocData].data_labels) { - if (this._props.doc.type === DocumentType.COL) { - const filtered_collections = new List(DocListCast(this._props.keywordDoc.collections).filter(doc => doc !== this._props.doc)); - this._props.keywordDoc.collections = filtered_collections; - - for (const cur_doc of DocListCast(this.getKeywordCollectionDocs()!, [])) { - this._props.doc[DocData].data = new List(DocListCast(this._props.doc[DocData].data).filter(doc => !Doc.AreProtosEqual(cur_doc, doc))); - } - } else { - const filtered_docs = new List(DocListCast(this.getKeywordCollectionDocs()!).filter(doc => doc !== this._props.doc)); - this._props.keywordDoc[DocData].docs = filtered_docs; - - for (const collection of DocListCast(this._props.keywordDoc.collections)) { - collection[DocData].data = new List(DocListCast(collection[DocData].data).filter(doc => !Doc.AreProtosEqual(this._props.doc, doc))); - } - } - } - this._props.doc[DocData].data_labels = (this._props.doc[DocData].data_labels as List).filter(label => label !== this._props.keyword) as List; - this._props.doc![DocData][`${this._props.keyword}`] = false; - }; - render() { const keyword = this._props.keyword.replace(/^@/, ''); const metadata = this._props.keyword.startsWith('@'); return ( -
+
{metadata ? ( {keyword}  - {this._props.doc[keyword] as string}{' '} + {this._props.doc[keyword] as string} ) : ( keyword )} - {this.props.isEditing && } + {this.props.isEditing && ( + KeywordItem.RemoveLabel(this._props.doc, this._props.keyword, this._props.keywordDoc), `remove label ${this._props.keyword}`)} + icon={'X'} + style={{ width: '8px', height: '8px', marginLeft: '10px' }} + /> + )}
); } } interface KeywordBoxProps { - doc: Doc; - isEditing: boolean; + Document: Doc; } /** @@ -152,76 +215,50 @@ interface KeywordBoxProps { */ @observer export class KeywordBox extends ObservableReactComponent { - @observable _currentInput: string = ''; - private height: number = 0; - private ref: React.RefObject; - - @computed - get currentScale() { - return NumCast((this._props.doc.embedContainer as Doc)?._freeform_scale, 1); - } - - @computed - get cur_height() { - return this.ref.current?.offsetHeight ? this.ref.current?.offsetHeight : 0; - } + private _height: number = 0; + private _ref: React.RefObject; constructor(props: any) { super(props); makeObservable(this); - this.ref = React.createRef(); + this._ref = React.createRef(); reaction( () => this.cur_height, () => { - this._props.doc[DocData].keywordHeight = this.height; + this._props.Document[DocData].keywordHeight = this._height; } ); } - componentDidMount(): void { - this.height = this.ref.current?.offsetHeight ? this.ref.current?.offsetHeight : 0; - this._props.doc[DocData].keywordHeight = this.height; - } + @observable _currentInput = ''; + @observable _isEditing = !StrListCast(this._props.Document[DocData].data_labels).length; - componentDidUpdate(prevProps: Readonly): void { - this.height = this.ref.current?.offsetHeight ? this.ref.current?.offsetHeight : 0; - this._props.doc[DocData].keywordHeight = this.height; + @computed get currentScale() { + return NumCast((this._props.Document.embedContainer as Doc)?._freeform_scale, 1); } - @action - setToEditing = () => { - this._props.isEditing = true; - }; + @computed get cur_height() { + return this._ref.current?.offsetHeight ?? 0; + } - @action - setToView = () => { - this._props.isEditing = false; - }; + @computed get isEditing() { + return this._isEditing && SelectionManager.Docs().includes(this._props.Document); + } - /** - * Gets the document associated with a keyword. - * @param keyword The keyword being searched for - * @returns A Doc containing keyword information - */ - getKeywordCollection = (keyword: string) => { - // Look for the keyword document. - for (const doc of DocListCast(Doc.ActiveDashboard!.myKeywordCollections)) { - if (doc.title === keyword) { - return doc; - } - } + componentDidMount() { + this._height = this._ref.current?.offsetHeight ?? 0; + this._props.Document[DocData].keywordHeight = this._height; + } - // If not contained, create a new document and add it to the active Dashboard's keyword list. - const keywordCollection = new Doc(); - keywordCollection.title = keyword; - keywordCollection[DocData].docs = new List(); - keywordCollection.collections = new List(); - if (Doc.ActiveDashboard) { - Doc.ActiveDashboard.myKeywordCollections = new List([...DocListCast(Doc.ActiveDashboard.myKeywordCollections), keywordCollection]); - } + componentDidUpdate(prevProps: Readonly): void { + this._height = this._ref.current?.offsetHeight ?? 0; + this._props.Document[DocData].keywordHeight = this._height; + } - return keywordCollection; + @action + setToEditing = () => { + this._isEditing = true; }; /** @@ -229,94 +266,42 @@ export class KeywordBox extends ObservableReactComponent { * @param keyword */ submitLabel = undoable((keyword: string) => { - // If the active Dashboard does not have a keyword collection, create it. - if (Doc.ActiveDashboard && !Doc.ActiveDashboard.myKeywordCollections) { - Doc.ActiveDashboard.myKeywordCollections = new List(); - } - const submittedLabel = keyword.trim(); - if (submittedLabel && !this._props.doc![DocData][`${submittedLabel}`]) { - // If the keyword collection is not in active Dashboard, add it as a new doc, with the keyword as its title. - const keywordCollection = this.getKeywordCollection(submittedLabel); - - // If the document has no keywords field, create the field. - if (!this._props.doc[DocData].data_labels) { - this._props.doc[DocData].data_labels = new List(); - } - - // If the document is of type COLLECTION, make it a smart collection, otherwise, add the keyword to the document. - if (this._props.doc.type === DocumentType.COL) { - keywordCollection.collections = new List([...DocListCast(keywordCollection.collections), this._props.doc]); - - // Iterate through the keyword document's collections and add a copy of the document to each collection - for (const doc of DocListCast(keywordCollection[DocData].docs)) { - const newEmbedding = Doc.MakeEmbedding(doc); - this._props.doc[DocData].data = new List([...DocListCast(this._props.doc[DocData].data), newEmbedding]); - newEmbedding.embedContainer = this._props.doc; - } - } else { - // Add this document to the keyword's collection of associated documents. - keywordCollection[DocData].docs = new List([...DocListCast(keywordCollection[DocData].docs), this._props.doc]); - - // Iterate through the keyword document's collections and add a copy of the document to each collection - for (const collection of DocListCast(keywordCollection.collections)) { - const newEmbedding = Doc.MakeEmbedding(this._props.doc); - collection[DocData].data = new List([...DocListCast(collection.data), newEmbedding]); - newEmbedding.embedContainer = collection; - } - } - - // Push the keyword to the document's keyword list field. - (this._props.doc![DocData].data_labels! as List).push(submittedLabel); - this._props.doc![DocData][`${submittedLabel}`] = true; + if (submittedLabel && !this._props.Document[DocData][submittedLabel]) { + KeywordItem.addLabelToDoc(this._props.Document, submittedLabel); this._currentInput = ''; // Clear the input box } }, 'added doc label'); - @action - onInputChange = (e: React.ChangeEvent) => { - this._currentInput = e.target.value; - }; - render() { - const keywordsList = this._props.doc[DocData].data_labels ? this._props.doc[DocData].data_labels : new List(); - const seldoc = DocumentView.SelectedDocs().lastElement(); - if (SnappingManager.IsDragging || !(seldoc === this._props.doc) || !this._props.isEditing) { - setTimeout( - action(() => { - if ((keywordsList as List).length === 0) { - this._props.doc[DocData].showLabels = false; - } - this.setToView(); - }) - ); - } + const keywordsList = StrListCast(this._props.Document[DocData].data_labels); - return ( + return !this._props.Document.showLabels ? null : (
-
+
- {(keywordsList as List).map(keyword => { - return ; + {keywordsList.map(keyword => { + const keywordDoc = KeywordItem.findKeywordCollectionDoc(keyword); + return !keywordDoc ? null : ; })}
- {this._props.isEditing ? ( + {this.isEditing ? (
(this._currentInput = e.target.value))} onKeyDown={e => { e.key === 'Enter' ? this.submitLabel(this._currentInput) : null; e.stopPropagation(); @@ -328,45 +313,28 @@ export class KeywordBox extends ObservableReactComponent { style={{ width: '100%', borderRadius: '5px' }} />
- {Doc.ActiveDashboard?.myKeywordCollections ? ( -
- {DocListCast(Doc.ActiveDashboard?.myKeywordCollections).map(doc => { - const keyword = StrCast(doc.title); - return ( -
- ) : ( -
- )} +
+ {KeywordItem.AllKeywordCollections.map(doc => { + const keyword = StrCast(doc.title); + return ( +
- { - if ((keywordsList as List).length === 0) { - this._props.doc[DocData].showLabels = false; - } else { - this.setToView(); - } - }} - icon={'x'} - style={{ width: '4px' }} - /> + {!keywordsList.length ? null : ( // + (this._isEditing = false))} icon="x" /> + )}
- ) : ( -
- )} + ) : null}
); diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 374399445..1e80e7ee5 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -364,13 +364,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt ); }; - const keywords = () => { - if (doc && doc![DocData].showLabels && (!doc[DocData].data_labels || (doc[DocData].data_labels as List).length === 0)){ - return () - } else if (doc && doc![DocData].data_labels && doc![DocData].showLabels) { - return () - } - } + const keywords = () => doc ? : null; return ( <> {paint()} -- cgit v1.2.3-70-g09d2 From dc7bb2ff07139c45efd3bf66ace0042b76c91ccf Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 23 Aug 2024 11:50:49 -0400 Subject: modified keywordsBox to use tags instead data_labels. made text #tags trigger keywords box. made keywords box fit contents. --- src/client/views/DocumentButtonBar.tsx | 10 +---- src/client/views/KeywordBox.tsx | 51 ++++++++++------------ src/client/views/StyleProvider.tsx | 5 +-- .../views/nodes/formattedText/RichTextRules.ts | 3 +- 4 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index d42a18e4e..eb157b9ab 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -282,15 +282,9 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( @computed get keywordButton() { - const targetDoc = this.view0?.Document; - return !targetDoc ? null : ( + return !DocumentView.Selected().length ? null : ( Open keyword menu
}> -
{ - targetDoc[DocData].showLabels = !targetDoc[DocData].showLabels; - }}> +
DocumentView.Selected().map(dv => (dv.dataDoc.showLabels = !dv.dataDoc.showLabels))}>
diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx index 703299ae6..1460501db 100644 --- a/src/client/views/KeywordBox.tsx +++ b/src/client/views/KeywordBox.tsx @@ -18,7 +18,7 @@ import { ObservableReactComponent } from './ObservableReactComponent'; interface KeywordItemProps { doc: Doc; keyword: string; - keywordDoc: Doc; + keywordDoc?: Doc; setToEditing: () => void; isEditing: boolean; } @@ -100,29 +100,28 @@ export class KeywordItem extends ObservableReactComponent { } } - if (!doc[DocData].data_labels) doc[DocData].data_labels = new List(); - (doc[DocData].data_labels as List).push(keyword); - doc[DocData][keyword] = true; + if (!doc[DocData].tags) doc[DocData].tags = new List(); + const tagList = doc[DocData].tags as List; + if (!tagList.includes(keyword)) tagList.push(keyword); }; - public static RemoveLabel = (doc: Doc, keyword: string, keywordDoc: Doc) => { - if (doc[DocData].data_labels) { + public static RemoveLabel = (doc: Doc, keyword: string, keywordDoc?: Doc) => { + if (doc[DocData].tags) { if (doc.type === DocumentType.COL) { - Doc.RemoveDocFromList(keywordDoc[DocData], 'collections', doc); + keywordDoc && Doc.RemoveDocFromList(keywordDoc[DocData], 'collections', doc); for (const cur_doc of KeywordItem.allDocsWithKeyword(keyword)) { doc[DocData].data = new List(DocListCast(doc[DocData].data).filter(d => !Doc.AreProtosEqual(cur_doc, d))); } } else { - Doc.RemoveDocFromList(keywordDoc[DocData], 'docs', doc); + keywordDoc && Doc.RemoveDocFromList(keywordDoc[DocData], 'docs', doc); - for (const collection of DocListCast(keywordDoc.collections)) { + for (const collection of DocListCast(keywordDoc?.collections)) { collection[DocData].data = new List(DocListCast(collection[DocData].data).filter(d => !Doc.AreProtosEqual(doc, d))); } } } - doc[DocData].data_labels = new List((doc[DocData].data_labels as List).filter(label => label !== keyword)); - doc[DocData][keyword] = undefined; + doc[DocData].tags = new List((doc[DocData].tags as List).filter(label => label !== keyword)); }; private _ref: React.RefObject; @@ -146,9 +145,9 @@ export class KeywordItem extends ObservableReactComponent { const docData = doc[DocData]; docData.data = new List(newEmbeddings); docData.title = this._props.keyword; - docData.data_labels = new List([this._props.keyword]); - docData[`${this._props.keyword}`] = true; + docData.tags = new List([this._props.keyword]); docData.showLabels = true; + docData.freeform_fitContentsToBox = true; doc._freeform_panX = doc._freeform_panY = 0; doc._width = 900; doc._height = 900; @@ -158,7 +157,7 @@ export class KeywordItem extends ObservableReactComponent { newEmbeddings.forEach(embed => Doc.SetContainer(embed, newCollection)); // Add the collection to the keyword document's list of associated smart collections. - Doc.AddDocToList(this._props.keywordDoc, 'collections', newCollection); + this._props.keywordDoc && Doc.AddDocToList(this._props.keywordDoc, 'collections', newCollection); return newCollection; }; @@ -181,14 +180,15 @@ export class KeywordItem extends ObservableReactComponent { }; render() { - const keyword = this._props.keyword.replace(/^@/, ''); - const metadata = this._props.keyword.startsWith('@'); + setTimeout(() => KeywordItem.addLabelToDoc(this._props.doc, this._props.keyword)); // bcz: hack to make sure that Docs are added to their keyword Doc collection since metadata can get set anywhere without a guard triggering an add to the collection + const keyword = this._props.keyword.replace(/^#/, ''); + const metadata = keyword.startsWith('@') ? keyword.replace(/^@/, '') : ''; return (
{metadata ? ( {keyword}  - {this._props.doc[keyword] as string} + {this._props.doc[metadata] as string} ) : ( keyword @@ -232,7 +232,7 @@ export class KeywordBox extends ObservableReactComponent { } @observable _currentInput = ''; - @observable _isEditing = !StrListCast(this._props.Document[DocData].data_labels).length; + @observable _isEditing = !StrListCast(this._props.Document[DocData].tags).length; @computed get currentScale() { return NumCast((this._props.Document.embedContainer as Doc)?._freeform_scale, 1); @@ -267,14 +267,12 @@ export class KeywordBox extends ObservableReactComponent { */ submitLabel = undoable((keyword: string) => { const submittedLabel = keyword.trim(); - if (submittedLabel && !this._props.Document[DocData][submittedLabel]) { - KeywordItem.addLabelToDoc(this._props.Document, submittedLabel); - this._currentInput = ''; // Clear the input box - } + submittedLabel && KeywordItem.addLabelToDoc(this._props.Document, '#' + submittedLabel.replace(/^#/, '')); + this._currentInput = ''; // Clear the input box }, 'added doc label'); render() { - const keywordsList = StrListCast(this._props.Document[DocData].data_labels); + const keywordsList = StrListCast(this._props.Document[DocData].tags); return !this._props.Document.showLabels ? null : (
{ }}>
- {keywordsList.map(keyword => { - const keywordDoc = KeywordItem.findKeywordCollectionDoc(keyword); - return !keywordDoc ? null : ; - })} + {keywordsList.map(keyword => ( + + ))}
{this.isEditing ? (
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 1e80e7ee5..0fb4f7dd1 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -9,9 +9,7 @@ import { BsArrowDown, BsArrowDownUp, BsArrowUp } from 'react-icons/bs'; import { FaFilter } from 'react-icons/fa'; import { ClientUtils, DashColor, lightOrDark } from '../../ClientUtils'; import { Doc, Opt, StrListCast } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; -import { List } from '../../fields/List'; import { ScriptField } from '../../fields/ScriptField'; import { BoolCast, Cast, DocCast, ImageCast, NumCast, ScriptCast, StrCast } from '../../fields/Types'; import { AudioAnnoState } from '../../server/SharedMediaTypes'; @@ -22,6 +20,7 @@ import { undoable, UndoManager } from '../util/UndoManager'; import { TreeSort } from './collections/TreeSort'; import { Colors } from './global/globalEnums'; import { KeywordBox } from './KeywordBox'; +import { CollectionFreeFormDocumentView } from './nodes/CollectionFreeFormDocumentView'; import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; import { FieldViewProps } from './nodes/FieldView'; import { StyleProp } from './StyleProp'; @@ -364,7 +363,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt ); }; - const keywords = () => doc ? : null; + const keywords = () => doc && CollectionFreeFormDocumentView.from(props?.DocumentView?.()) ? : null; return ( <> {paint()} diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 39f589b1e..79c118490 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -396,7 +396,7 @@ export class RichTextRules { }), // create an inline view of a tag stored under the '#' field - new InputRule(/#([a-zA-Z_-]+[a-zA-Z_\-0-9]*)\s$/, (state, match, start, end) => { + new InputRule(/#(@?[a-zA-Z_-]+[a-zA-Z_\-0-9]*)\s$/, (state, match, start, end) => { const tag = match[1]; if (!tag) return state.tr; // this.Document[DocData]['#' + tag] = '#' + tag; @@ -404,6 +404,7 @@ export class RichTextRules { if (!tags.includes(tag)) { tags.push(tag); this.Document[DocData].tags = new List(tags); + this.Document[DocData].showLabels = true; } const fieldView = state.schema.nodes.dashField.create({ fieldKey: '#' + tag }); return state.tr -- cgit v1.2.3-70-g09d2 From ac580dab29fc5867680a54b2fbfd68f9d4e2a895 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 23 Aug 2024 15:23:07 -0400 Subject: changed keyword items to use a doc symbol for storage instead of a field. fixed sizing of docDecoartions around keyeword box to dynaically update accurately. Aded expand/collapse button for editing keywords --- src/client/views/DocumentDecorations.tsx | 4 +- src/client/views/KeywordBox.tsx | 91 ++++++++++++-------------------- src/client/views/StyleProvider.scss | 5 +- src/client/views/StyleProvider.tsx | 2 +- src/fields/Doc.ts | 4 +- src/fields/DocSymbols.ts | 3 ++ 6 files changed, 47 insertions(+), 62 deletions(-) diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index ce1138b7a..19c4a097b 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -9,7 +9,7 @@ import { lightOrDark, returnFalse, setupMoveUpEvents } from '../../ClientUtils'; import { Utils, emptyFunction, numberValue } from '../../Utils'; import { DateField } from '../../fields/DateField'; import { Doc, DocListCast, Field, FieldType, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc'; -import { AclAdmin, AclAugment, AclEdit, DocData } from '../../fields/DocSymbols'; +import { AclAdmin, AclAugment, AclEdit, DocData, KeywordsHeight } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { InkField } from '../../fields/InkField'; import { ScriptField } from '../../fields/ScriptField'; @@ -835,7 +835,7 @@ export class DocumentDecorations extends ObservableReactComponent DocumentView.Selected()} /> diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx index 1460501db..841c5394b 100644 --- a/src/client/views/KeywordBox.tsx +++ b/src/client/views/KeywordBox.tsx @@ -1,19 +1,22 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button, Colors, IconButton } from 'browndash-components'; -import { action, computed, makeObservable, observable, reaction } from 'mobx'; +import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; +import ResizeObserver from 'resize-observer-polyfill'; import { returnFalse, setupMoveUpEvents } from '../../ClientUtils'; import { Utils, emptyFunction } from '../../Utils'; import { Doc, DocListCast, StrListCast } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; +import { DocData, KeywordsHeight } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; import { NumCast, StrCast } from '../../fields/Types'; import { DocumentType } from '../documents/DocumentTypes'; import { DragManager } from '../util/DragManager'; -import { SelectionManager } from '../util/SelectionManager'; import { SnappingManager } from '../util/SnappingManager'; import { undoable } from '../util/UndoManager'; import { ObservableReactComponent } from './ObservableReactComponent'; +import { DocumentView } from './nodes/DocumentView'; +import { FontIconBox } from './nodes/FontIconBox/FontIconBox'; interface KeywordItemProps { doc: Doc; @@ -163,20 +166,18 @@ export class KeywordItem extends ObservableReactComponent { @action handleDragStart = (e: React.PointerEvent) => { - if (this._props.isEditing) { - setupMoveUpEvents( - this, - e, - () => { - const dragData = new DragManager.DocumentDragData([this.createCollection()]); - DragManager.StartDocumentDrag([this._ref.current!], dragData, e.clientX, e.clientY, {}); - return true; - }, - returnFalse, - emptyFunction - ); - e.preventDefault(); - } + setupMoveUpEvents( + this, + e, + () => { + const dragData = new DragManager.DocumentDragData([this.createCollection()]); + DragManager.StartDocumentDrag([this._ref.current!], dragData, e.clientX, e.clientY, {}); + return true; + }, + returnFalse, + emptyFunction + ); + e.preventDefault(); }; render() { @@ -197,7 +198,7 @@ export class KeywordItem extends ObservableReactComponent { KeywordItem.RemoveLabel(this._props.doc, this._props.keyword, this._props.keywordDoc), `remove label ${this._props.keyword}`)} - icon={'X'} + icon={} style={{ width: '8px', height: '8px', marginLeft: '10px' }} /> )} @@ -207,7 +208,7 @@ export class KeywordItem extends ObservableReactComponent { } interface KeywordBoxProps { - Document: Doc; + View: DocumentView; } /** @@ -215,50 +216,28 @@ interface KeywordBoxProps { */ @observer export class KeywordBox extends ObservableReactComponent { - private _height: number = 0; private _ref: React.RefObject; constructor(props: any) { super(props); makeObservable(this); this._ref = React.createRef(); - - reaction( - () => this.cur_height, - () => { - this._props.Document[DocData].keywordHeight = this._height; - } - ); } @observable _currentInput = ''; - @observable _isEditing = !StrListCast(this._props.Document[DocData].tags).length; + @observable _isEditing = !StrListCast(this._props.View.dataDoc.tags).length; @computed get currentScale() { - return NumCast((this._props.Document.embedContainer as Doc)?._freeform_scale, 1); + return NumCast((this._props.View.Document.embedContainer as Doc)?._freeform_scale, 1); } - - @computed get cur_height() { - return this._ref.current?.offsetHeight ?? 0; - } - @computed get isEditing() { - return this._isEditing && SelectionManager.Docs().includes(this._props.Document); - } - - componentDidMount() { - this._height = this._ref.current?.offsetHeight ?? 0; - this._props.Document[DocData].keywordHeight = this._height; - } - - componentDidUpdate(prevProps: Readonly): void { - this._height = this._ref.current?.offsetHeight ?? 0; - this._props.Document[DocData].keywordHeight = this._height; + return this._isEditing && DocumentView.SelectedDocs().includes(this._props.View.Document); } @action - setToEditing = () => { - this._isEditing = true; + setToEditing = (editing = true) => { + this._isEditing = editing; + editing && this._props.View.select(false); }; /** @@ -267,17 +246,17 @@ export class KeywordBox extends ObservableReactComponent { */ submitLabel = undoable((keyword: string) => { const submittedLabel = keyword.trim(); - submittedLabel && KeywordItem.addLabelToDoc(this._props.Document, '#' + submittedLabel.replace(/^#/, '')); + submittedLabel && KeywordItem.addLabelToDoc(this._props.View.Document, '#' + submittedLabel.replace(/^#/, '')); this._currentInput = ''; // Clear the input box }, 'added doc label'); render() { - const keywordsList = StrListCast(this._props.Document[DocData].tags); + const keywordsList = StrListCast(this._props.View.dataDoc.tags); - return !this._props.Document.showLabels ? null : ( + return !this._props.View.Document.showLabels ? null : (
r && new ResizeObserver(action(() => (this._props.View.Document[KeywordsHeight] = r?.getBoundingClientRect().height ?? 0))).observe(r)} style={{ transformOrigin: 'top left', maxWidth: `${100 * this.currentScale}%`, @@ -288,8 +267,11 @@ export class KeywordBox extends ObservableReactComponent { }}>
+ {!keywordsList.length ? null : ( // + this.setToEditing(!this._isEditing)} icon={} /> + )} {keywordsList.map(keyword => ( - + ))}
{this.isEditing ? ( @@ -325,11 +307,6 @@ export class KeywordBox extends ObservableReactComponent { ); })}
-
- {!keywordsList.length ? null : ( // - (this._isEditing = false))} icon="x" /> - )} -
) : null}
diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss index 1d41697f5..6f6939d54 100644 --- a/src/client/views/StyleProvider.scss +++ b/src/client/views/StyleProvider.scss @@ -65,10 +65,13 @@ .keywords-list { display: flex; flex-wrap: wrap; + .iconButton-container { + min-height: unset !important; + } } .keyword { - padding: 5px 5px; + padding: 1px 5px; background-color: lightblue; border: 1px solid black; border-radius: 5px; diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 0fb4f7dd1..a841ec63a 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -363,7 +363,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt ); }; - const keywords = () => doc && CollectionFreeFormDocumentView.from(props?.DocumentView?.()) ? : null; + const keywords = () => props?.DocumentView?.() && CollectionFreeFormDocumentView.from(props.DocumentView()) ? : null; return ( <> {paint()} diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index ffb5aab79..f246f49e5 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -11,7 +11,7 @@ import { ClientUtils, incrementTitleCopy } from '../ClientUtils'; import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, Animation, AudioPlay, Brushed, CachedUpdates, DirectLinks, DocAcl, DocCss, DocData, DocLayout, DocViews, FieldKeys, FieldTuples, ForceServerWrite, Height, Highlight, - Initializing, Self, SelfProxy, TransitionTimer, UpdatingFromServer, Width + Initializing, KeywordsHeight, Self, SelfProxy, TransitionTimer, UpdatingFromServer, Width } from './DocSymbols'; // prettier-ignore import { Copy, FieldChanged, HandleUpdate, Id, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols'; import { InkTool } from './InkField'; @@ -303,6 +303,7 @@ export class Doc extends RefField { Height, Highlight, Initializing, + KeywordsHeight, Self, SelfProxy, UpdatingFromServer, @@ -368,6 +369,7 @@ export class Doc extends RefField { @observable public [Highlight]: boolean = false; @observable public [Brushed]: boolean = false; @observable public [DocViews] = new ObservableSet(); + @observable public [KeywordsHeight]: number = 0; private [Self] = this; private [SelfProxy]: Doc; diff --git a/src/fields/DocSymbols.ts b/src/fields/DocSymbols.ts index 837fcc90e..9e091ab29 100644 --- a/src/fields/DocSymbols.ts +++ b/src/fields/DocSymbols.ts @@ -1,3 +1,5 @@ +// NOTE: These symbols must be added to Doc.ts constructor !! + // Symbols for fundamental Doc operations such as: permissions, field and proxy access and server interactions export const AclPrivate = Symbol('DocAclOwnerOnly'); export const AclReadonly = Symbol('DocAclReadOnly'); @@ -30,5 +32,6 @@ export const DocViews = Symbol('DocViews'); export const Brushed = Symbol('DocBrushed'); export const DocCss = Symbol('DocCss'); export const TransitionTimer = Symbol('DocTransitionTimer'); +export const KeywordsHeight = Symbol('DocKeywordsHeight'); export const DashVersion = 'v0.8.0'; -- cgit v1.2.3-70-g09d2 From a52cda0a098716c24b3c6aafe23d2bd9267c72d9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 10:43:43 -0400 Subject: moved KeywordsBox to TagsView. changed imagellable to use tags --- src/client/documents/Documents.ts | 8 +- src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/DocumentDecorations.tsx | 6 +- src/client/views/KeywordBox.tsx | 316 ------------------- src/client/views/StyleProvider.scss | 64 ---- src/client/views/StyleProvider.tsx | 6 +- src/client/views/TagsView.scss | 63 ++++ src/client/views/TagsView.tsx | 344 +++++++++++++++++++++ .../collectionFreeForm/ImageLabelBox.tsx | 58 ++-- src/client/views/nodes/DocumentView.tsx | 1 + .../views/nodes/formattedText/RichTextRules.ts | 2 +- src/fields/Doc.ts | 4 +- src/fields/DocSymbols.ts | 1 - 13 files changed, 447 insertions(+), 428 deletions(-) delete mode 100644 src/client/views/KeywordBox.tsx create mode 100644 src/client/views/TagsView.scss create mode 100644 src/client/views/TagsView.tsx diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6b5469cca..c0e4e961c 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -43,7 +43,7 @@ export class FInfo { description: string = ''; readOnly: boolean = false; fieldType?: FInfoFieldType; - values?: FieldType[] | Map; + values?: FieldType[]; filterable?: boolean = true; // can be used as a Filter in FilterPanel // format?: string; // format to display values (e.g, decimal places, $, etc) @@ -144,10 +144,6 @@ class ListInfo extends FInfo { fieldType? = FInfoFieldType.list; values?: List[] = []; } -class MapInfo extends FInfo { - fieldType? = FInfoFieldType.map; - values?: Map = new Map(); -} type BOOLt = BoolInfo | boolean; type NUMt = NumInfo | number; type STRt = StrInfo | string; @@ -160,7 +156,6 @@ type COLLt = CTypeInfo | CollectionViewType; type DROPt = DAInfo | dropActionType; type DATEt = DateInfo | number; type DTYPEt = DTypeInfo | string; -type MAPt = MapInfo | Map; export class DocumentOptions { // coordinate and dimensions depending on view x?: NUMt = new NumInfo('horizontal coordinate in freeform view', false); @@ -489,7 +484,6 @@ export class DocumentOptions { cardSort?: STRt = new StrInfo('way cards are sorted in deck view'); cardSort_customField?: STRt = new StrInfo('field key used for sorting cards'); cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) - keywords?: MAPt = new MapInfo('keywords', true); } export const DocOptions = new DocumentOptions(); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index eb157b9ab..58b7f207c 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -284,7 +284,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( get keywordButton() { return !DocumentView.Selected().length ? null : ( Open keyword menu
}> -
DocumentView.Selected().map(dv => (dv.dataDoc.showLabels = !dv.dataDoc.showLabels))}> +
DocumentView.Selected().map(dv => (dv.dataDoc.showTags = !dv.dataDoc.showTags))}>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 19c4a097b..da35459bb 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -1,3 +1,4 @@ +import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { IconButton } from 'browndash-components'; @@ -9,7 +10,7 @@ import { lightOrDark, returnFalse, setupMoveUpEvents } from '../../ClientUtils'; import { Utils, emptyFunction, numberValue } from '../../Utils'; import { DateField } from '../../fields/DateField'; import { Doc, DocListCast, Field, FieldType, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc'; -import { AclAdmin, AclAugment, AclEdit, DocData, KeywordsHeight } from '../../fields/DocSymbols'; +import { AclAdmin, AclAugment, AclEdit, DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { InkField } from '../../fields/InkField'; import { ScriptField } from '../../fields/ScriptField'; @@ -34,7 +35,6 @@ import { DocumentView } from './nodes/DocumentView'; import { ImageBox } from './nodes/ImageBox'; import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; -import { IconProp } from '@fortawesome/fontawesome-svg-core'; interface DocumentDecorationsProps { PanelWidth: number; @@ -835,7 +835,7 @@ export class DocumentDecorations extends ObservableReactComponent DocumentView.Selected()} /> diff --git a/src/client/views/KeywordBox.tsx b/src/client/views/KeywordBox.tsx deleted file mode 100644 index 841c5394b..000000000 --- a/src/client/views/KeywordBox.tsx +++ /dev/null @@ -1,316 +0,0 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Button, Colors, IconButton } from 'browndash-components'; -import { action, computed, makeObservable, observable } from 'mobx'; -import { observer } from 'mobx-react'; -import React from 'react'; -import ResizeObserver from 'resize-observer-polyfill'; -import { returnFalse, setupMoveUpEvents } from '../../ClientUtils'; -import { Utils, emptyFunction } from '../../Utils'; -import { Doc, DocListCast, StrListCast } from '../../fields/Doc'; -import { DocData, KeywordsHeight } from '../../fields/DocSymbols'; -import { List } from '../../fields/List'; -import { NumCast, StrCast } from '../../fields/Types'; -import { DocumentType } from '../documents/DocumentTypes'; -import { DragManager } from '../util/DragManager'; -import { SnappingManager } from '../util/SnappingManager'; -import { undoable } from '../util/UndoManager'; -import { ObservableReactComponent } from './ObservableReactComponent'; -import { DocumentView } from './nodes/DocumentView'; -import { FontIconBox } from './nodes/FontIconBox/FontIconBox'; - -interface KeywordItemProps { - doc: Doc; - keyword: string; - keywordDoc?: Doc; - setToEditing: () => void; - isEditing: boolean; -} - -/** - * A component that handles individual keywords. - */ -@observer -export class KeywordItem extends ObservableReactComponent { - /** - * return list of all Docs that collect Docs with specified keywords - */ - public static get AllKeywordCollections() { - return DocListCast(Doc.ActiveDashboard?.myKeywordCollections); - } - /** - * Find Doc that collects all Docs with given keyword - * @param keyword keyword string - * @returns keyword collection Doc or undefined - */ - public static findKeywordCollectionDoc = (keyword: String) => KeywordItem.AllKeywordCollections.find(doc => doc.title === keyword); - - /** - * Creates a Doc that collects Docs with the specified keyword - * @param keyword keyword string - * @returns collection Doc - */ - public static createKeywordCollectionDoc = (keyword: string) => { - const newKeywordCol = new Doc(); - newKeywordCol.title = keyword; - newKeywordCol.collections = new List(); - newKeywordCol[DocData].docs = new List(); - // If the active Dashboard does not have a keyword collection, create it. - if (Doc.ActiveDashboard) { - if (!Doc.ActiveDashboard.myKeywordCollections) Doc.ActiveDashboard.myKeywordCollections = new List(); - Doc.AddDocToList(Doc.ActiveDashboard, 'myKeywordCollections', newKeywordCol); - } - - return newKeywordCol; - }; - /** - * Gets all Docs that have the specified keyword - * @param keyword keyword string - * @returns An array of documents that contain the keyword. - */ - public static allDocsWithKeyword = (keyword: string) => DocListCast(KeywordItem.findKeywordCollectionDoc(keyword)?.[DocData].docs); - - /** - * Adds a keyword to the metadata of this document - * @param keyword keyword string - */ - public static addLabelToDoc = (doc: Doc, keyword: string) => { - // If the keyword collection is not in active Dashboard, add it as a new doc, with the keyword as its title. - const keywordCollection = KeywordItem.findKeywordCollectionDoc(keyword) ?? KeywordItem.createKeywordCollectionDoc(keyword); - - // If the document is of type COLLECTION, make it a smart collection, otherwise, add the keyword to the document. - if (doc.type === DocumentType.COL) { - Doc.AddDocToList(keywordCollection[DocData], 'collections', doc); - - // Iterate through the keyword Doc collections and add a copy of the document to each collection - for (const cdoc of DocListCast(keywordCollection[DocData].docs)) { - if (!DocListCast(doc[DocData].data).find(d => Doc.AreProtosEqual(d, cdoc))) { - const newEmbedding = Doc.MakeEmbedding(cdoc); - Doc.AddDocToList(doc[DocData], 'data', newEmbedding); - Doc.SetContainer(newEmbedding, doc); - } - } - } else { - // Add this document to the keyword's collection of associated documents. - Doc.AddDocToList(keywordCollection[DocData], 'docs', doc); - - // Iterate through the keyword document's collections and add a copy of the document to each collection - for (const collection of DocListCast(keywordCollection.collections)) { - if (!DocListCast(collection[DocData].data).find(d => Doc.AreProtosEqual(d, doc))) { - const newEmbedding = Doc.MakeEmbedding(doc); - Doc.AddDocToList(collection[DocData], 'data', newEmbedding); - Doc.SetContainer(newEmbedding, collection); - } - } - } - - if (!doc[DocData].tags) doc[DocData].tags = new List(); - const tagList = doc[DocData].tags as List; - if (!tagList.includes(keyword)) tagList.push(keyword); - }; - - public static RemoveLabel = (doc: Doc, keyword: string, keywordDoc?: Doc) => { - if (doc[DocData].tags) { - if (doc.type === DocumentType.COL) { - keywordDoc && Doc.RemoveDocFromList(keywordDoc[DocData], 'collections', doc); - - for (const cur_doc of KeywordItem.allDocsWithKeyword(keyword)) { - doc[DocData].data = new List(DocListCast(doc[DocData].data).filter(d => !Doc.AreProtosEqual(cur_doc, d))); - } - } else { - keywordDoc && Doc.RemoveDocFromList(keywordDoc[DocData], 'docs', doc); - - for (const collection of DocListCast(keywordDoc?.collections)) { - collection[DocData].data = new List(DocListCast(collection[DocData].data).filter(d => !Doc.AreProtosEqual(doc, d))); - } - } - } - doc[DocData].tags = new List((doc[DocData].tags as List).filter(label => label !== keyword)); - }; - - private _ref: React.RefObject; - - constructor(props: any) { - super(props); - makeObservable(this); - this._ref = React.createRef(); - } - - /** - * Creates a smart collection. - * @returns - */ - createCollection = () => { - // Get the documents that contain the keyword. - const newEmbeddings = KeywordItem.allDocsWithKeyword(this._props.keyword).map(doc => Doc.MakeEmbedding(doc)); - - // Create a new collection and set up configurations. - const newCollection = ((doc: Doc) => { - const docData = doc[DocData]; - docData.data = new List(newEmbeddings); - docData.title = this._props.keyword; - docData.tags = new List([this._props.keyword]); - docData.showLabels = true; - docData.freeform_fitContentsToBox = true; - doc._freeform_panX = doc._freeform_panY = 0; - doc._width = 900; - doc._height = 900; - doc.layout_fitWidth = true; - return doc; - })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true)); - newEmbeddings.forEach(embed => Doc.SetContainer(embed, newCollection)); - - // Add the collection to the keyword document's list of associated smart collections. - this._props.keywordDoc && Doc.AddDocToList(this._props.keywordDoc, 'collections', newCollection); - return newCollection; - }; - - @action - handleDragStart = (e: React.PointerEvent) => { - setupMoveUpEvents( - this, - e, - () => { - const dragData = new DragManager.DocumentDragData([this.createCollection()]); - DragManager.StartDocumentDrag([this._ref.current!], dragData, e.clientX, e.clientY, {}); - return true; - }, - returnFalse, - emptyFunction - ); - e.preventDefault(); - }; - - render() { - setTimeout(() => KeywordItem.addLabelToDoc(this._props.doc, this._props.keyword)); // bcz: hack to make sure that Docs are added to their keyword Doc collection since metadata can get set anywhere without a guard triggering an add to the collection - const keyword = this._props.keyword.replace(/^#/, ''); - const metadata = keyword.startsWith('@') ? keyword.replace(/^@/, '') : ''; - return ( -
- {metadata ? ( - - {keyword}  - {this._props.doc[metadata] as string} - - ) : ( - keyword - )} - {this.props.isEditing && ( - KeywordItem.RemoveLabel(this._props.doc, this._props.keyword, this._props.keywordDoc), `remove label ${this._props.keyword}`)} - icon={} - style={{ width: '8px', height: '8px', marginLeft: '10px' }} - /> - )} -
- ); - } -} - -interface KeywordBoxProps { - View: DocumentView; -} - -/** - * A component that handles the keyword display for documents. - */ -@observer -export class KeywordBox extends ObservableReactComponent { - private _ref: React.RefObject; - - constructor(props: any) { - super(props); - makeObservable(this); - this._ref = React.createRef(); - } - - @observable _currentInput = ''; - @observable _isEditing = !StrListCast(this._props.View.dataDoc.tags).length; - - @computed get currentScale() { - return NumCast((this._props.View.Document.embedContainer as Doc)?._freeform_scale, 1); - } - @computed get isEditing() { - return this._isEditing && DocumentView.SelectedDocs().includes(this._props.View.Document); - } - - @action - setToEditing = (editing = true) => { - this._isEditing = editing; - editing && this._props.View.select(false); - }; - - /** - * Adds the keyword to the document. - * @param keyword - */ - submitLabel = undoable((keyword: string) => { - const submittedLabel = keyword.trim(); - submittedLabel && KeywordItem.addLabelToDoc(this._props.View.Document, '#' + submittedLabel.replace(/^#/, '')); - this._currentInput = ''; // Clear the input box - }, 'added doc label'); - - render() { - const keywordsList = StrListCast(this._props.View.dataDoc.tags); - - return !this._props.View.Document.showLabels ? null : ( -
r && new ResizeObserver(action(() => (this._props.View.Document[KeywordsHeight] = r?.getBoundingClientRect().height ?? 0))).observe(r)} - style={{ - transformOrigin: 'top left', - maxWidth: `${100 * this.currentScale}%`, - width: 'max-content', - transform: `scale(${1 / this.currentScale})`, - backgroundColor: this.isEditing ? Colors.LIGHT_GRAY : Colors.TRANSPARENT, - borderColor: this.isEditing ? Colors.BLACK : Colors.TRANSPARENT, - }}> -
-
- {!keywordsList.length ? null : ( // - this.setToEditing(!this._isEditing)} icon={} /> - )} - {keywordsList.map(keyword => ( - - ))} -
- {this.isEditing ? ( -
-
- (this._currentInput = e.target.value))} - onKeyDown={e => { - e.key === 'Enter' ? this.submitLabel(this._currentInput) : null; - e.stopPropagation(); - }} - type="text" - placeholder="Input keywords for document..." - aria-label="keyword-input" - className="keyword-input" - style={{ width: '100%', borderRadius: '5px' }} - /> -
-
- {KeywordItem.AllKeywordCollections.map(doc => { - const keyword = StrCast(doc.title); - return ( -
-
- ) : null} -
-
- ); - } -} diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss index 6f6939d54..ce00f6101 100644 --- a/src/client/views/StyleProvider.scss +++ b/src/client/views/StyleProvider.scss @@ -53,67 +53,3 @@ .styleProvider-treeView-icon { opacity: 0; } - -.keywords-container { - display: flex; - flex-wrap: wrap; - flex-direction: column; - border: 1px solid; - border-radius: 4px; -} - -.keywords-list { - display: flex; - flex-wrap: wrap; - .iconButton-container { - min-height: unset !important; - } -} - -.keyword { - padding: 1px 5px; - background-color: lightblue; - border: 1px solid black; - border-radius: 5px; - white-space: nowrap; - display: flex; - align-items: center; -} - -.keyword-suggestions-box { - display: flex; - flex-wrap: wrap; - margin: auto; - align-self: center; - width: 90%; - border: 1px solid black; - border-radius: 2px; - margin-top: 8px; -} - -.keyword-suggestion { - cursor: pointer; - padding: 1px 1px; - margin: 2px 2px; - background-color: lightblue; - border: 1px solid black; - border-radius: 5px; - white-space: nowrap; - display: flex; - align-items: center; -} - -.keyword-editing-box { - margin-top: 8px; -} - -.keyword-input-box { - margin: auto; - align-self: center; - width: 90%; -} - -.keyword-buttons { - margin-left: auto; - width: 10%; -} diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index a841ec63a..e48994586 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -19,7 +19,7 @@ import { SnappingManager } from '../util/SnappingManager'; import { undoable, UndoManager } from '../util/UndoManager'; import { TreeSort } from './collections/TreeSort'; import { Colors } from './global/globalEnums'; -import { KeywordBox } from './KeywordBox'; +import { TagsView } from './TagsView'; import { CollectionFreeFormDocumentView } from './nodes/CollectionFreeFormDocumentView'; import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; import { FieldViewProps } from './nodes/FieldView'; @@ -363,14 +363,14 @@ export function DefaultStyleProvider(doc: Opt, props: Opt ); }; - const keywords = () => props?.DocumentView?.() && CollectionFreeFormDocumentView.from(props.DocumentView()) ? : null; + const tags = () => props?.DocumentView?.() && CollectionFreeFormDocumentView.from(props.DocumentView()) ? : null; return ( <> {paint()} {lock()} {filter()} {audio()} - {keywords()} + {tags()} ); } diff --git a/src/client/views/TagsView.scss b/src/client/views/TagsView.scss new file mode 100644 index 000000000..f7365a51b --- /dev/null +++ b/src/client/views/TagsView.scss @@ -0,0 +1,63 @@ +.tagsView-container { + display: flex; + flex-wrap: wrap; + flex-direction: column; + border: 1px solid; + border-radius: 4px; +} + +.tagsView-list { + display: flex; + flex-wrap: wrap; + .iconButton-container { + min-height: unset !important; + } +} + +.tagItem { + padding: 1px 5px; + background-color: lightblue; + border: 1px solid black; + border-radius: 5px; + white-space: nowrap; + display: flex; + align-items: center; +} + +.tagsView-suggestions-box { + display: flex; + flex-wrap: wrap; + margin: auto; + align-self: center; + width: 90%; + border: 1px solid black; + border-radius: 2px; + margin-top: 8px; +} + +.tagsView-suggestion { + cursor: pointer; + padding: 1px 1px; + margin: 2px 2px; + background-color: lightblue; + border: 1px solid black; + border-radius: 5px; + white-space: nowrap; + display: flex; + align-items: center; +} + +.tagsView-editing-box { + margin-top: 8px; +} + +.tagsView-input-box { + margin: auto; + align-self: center; + width: 90%; +} + +.tagsView-buttons { + margin-left: auto; + width: 10%; +} diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx new file mode 100644 index 000000000..dffd1e096 --- /dev/null +++ b/src/client/views/TagsView.tsx @@ -0,0 +1,344 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Button, Colors, IconButton } from 'browndash-components'; +import { action, computed, makeObservable, observable } from 'mobx'; +import { observer } from 'mobx-react'; +import React from 'react'; +import ResizeObserver from 'resize-observer-polyfill'; +import { returnFalse, setupMoveUpEvents } from '../../ClientUtils'; +import { emptyFunction } from '../../Utils'; +import { Doc, DocListCast, Opt, StrListCast } from '../../fields/Doc'; +import { DocData } from '../../fields/DocSymbols'; +import { List } from '../../fields/List'; +import { NumCast, StrCast } from '../../fields/Types'; +import { DocumentType } from '../documents/DocumentTypes'; +import { DragManager } from '../util/DragManager'; +import { SnappingManager } from '../util/SnappingManager'; +import { undoable } from '../util/UndoManager'; +import { ObservableReactComponent } from './ObservableReactComponent'; +import './TagsView.scss'; +import { DocumentView } from './nodes/DocumentView'; + +/** + * The TagsView is a metadata input/display panel shown at the bottom of a DocumentView in a freeform collection. + * + * This panel allow sthe user to add metadata tags to a Doc, and to display those tags, or any metadata field + * in a panel of 'buttons' (TagItems) just below the DocumentView. TagItems are interactive - + * the user can drag them off in order to display a collection of all documents that share the tag value. + * + * The tags that are added using the panel are the same as the #tags that can entered in a text Doc. + * Note that tags starting with #@ display a metadata key/value pair instead of the tag itself. + * e.g., '#@author' shows the document author + * + */ + +interface TagItemProps { + doc: Doc; + tag: string; + tagDoc: Opt; + showRemoveUI: boolean; + setToEditing: () => void; +} + +/** + * Interactive component that display a single metadata tag or value. + * + * These items can be dragged and dropped to create a collection of Docs that + * share the same metadata tag / value. + */ +@observer +export class TagItem extends ObservableReactComponent { + /** + * return list of all tag Docs (ie, Doc that are collections of Docs sharing a specific tag / value) + */ + public static get AllTagCollectionDocs() { + return DocListCast(Doc.ActiveDashboard?.myTagCollections); + } + /** + * Find tag Doc that collects all Docs with given tag / value + * @param tag tag string + * @returns tag collection Doc or undefined + */ + public static findTagCollectionDoc = (tag: String) => TagItem.AllTagCollectionDocs.find(doc => doc.title === tag); + + /** + * Creates a Doc that collects Docs with the specified tag / value + * @param tag tag string + * @returns tag collection Doc + */ + public static createTagCollectionDoc = (tag: string) => { + const newTagCol = new Doc(); + newTagCol.title = tag; + newTagCol.collections = new List(); + newTagCol[DocData].docs = new List(); + // If the active Dashboard does not have a tag Doc collection, create it. + if (Doc.ActiveDashboard) { + if (!Doc.ActiveDashboard.myTagCollections) Doc.ActiveDashboard.myTagCollections = new List(); + Doc.AddDocToList(Doc.ActiveDashboard, 'myTagCollections', newTagCol); + } + + return newTagCol; + }; + /** + * Gets all Docs that have the specified tag / value + * @param tag tag string + * @returns An array of documents that contain the tag. + */ + public static allDocsWithTag = (tag: string) => DocListCast(TagItem.findTagCollectionDoc(tag)?.[DocData].docs); + + /** + * Adds a tag to the metadata of this document and adds the Doc to the corresponding tag collection Doc (or creates it) + * @param tag tag string + */ + public static addTagToDoc = (doc: Doc, tag: string) => { + // If the tag collection is not in active Dashboard, add it as a new doc, with the tag as its title. + const tagCollection = TagItem.findTagCollectionDoc(tag) ?? TagItem.createTagCollectionDoc(tag); + + // If the document is of type COLLECTION, make it a smart collection, otherwise, add the tag to the document. + if (doc.type === DocumentType.COL) { + Doc.AddDocToList(tagCollection[DocData], 'collections', doc); + + // Iterate through the tag Doc collections and add a copy of the document to each collection + for (const cdoc of DocListCast(tagCollection[DocData].docs)) { + if (!DocListCast(doc[DocData].data).find(d => Doc.AreProtosEqual(d, cdoc))) { + const newEmbedding = Doc.MakeEmbedding(cdoc); + Doc.AddDocToList(doc[DocData], 'data', newEmbedding); + Doc.SetContainer(newEmbedding, doc); + } + } + } else { + // Add this document to the tag's collection of associated documents. + Doc.AddDocToList(tagCollection[DocData], 'docs', doc); + + // Iterate through the tag document's collections and add a copy of the document to each collection + for (const collection of DocListCast(tagCollection.collections)) { + if (!DocListCast(collection[DocData].data).find(d => Doc.AreProtosEqual(d, doc))) { + const newEmbedding = Doc.MakeEmbedding(doc); + Doc.AddDocToList(collection[DocData], 'data', newEmbedding); + Doc.SetContainer(newEmbedding, collection); + } + } + } + + if (!doc[DocData].tags) doc[DocData].tags = new List(); + const tagList = doc[DocData].tags as List; + if (!tagList.includes(tag)) tagList.push(tag); + }; + + /** + * Removes a tag from a Doc and removes the Doc from the corresponding tag collection Doc + * @param doc Doc to add tag + * @param tag tag string + * @param tagDoc doc that collections the Docs with the tag + */ + public static removeTagFromDoc = (doc: Doc, tag: string, tagDoc?: Doc) => { + if (doc[DocData].tags) { + if (doc.type === DocumentType.COL) { + tagDoc && Doc.RemoveDocFromList(tagDoc[DocData], 'collections', doc); + + for (const cur_doc of TagItem.allDocsWithTag(tag)) { + doc[DocData].data = new List(DocListCast(doc[DocData].data).filter(d => !Doc.AreProtosEqual(cur_doc, d))); + } + } else { + tagDoc && Doc.RemoveDocFromList(tagDoc[DocData], 'docs', doc); + + for (const collection of DocListCast(tagDoc?.collections)) { + collection[DocData].data = new List(DocListCast(collection[DocData].data).filter(d => !Doc.AreProtosEqual(doc, d))); + } + } + } + doc[DocData].tags = new List((doc[DocData].tags as List).filter(label => label !== tag)); + }; + + private _ref: React.RefObject; + + constructor(props: any) { + super(props); + makeObservable(this); + this._ref = React.createRef(); + } + + /** + * Creates a smart collection. + * @returns + */ + createTagCollection = () => { + // Get the documents that contain the tag. + const newEmbeddings = TagItem.allDocsWithTag(this._props.tag).map(doc => Doc.MakeEmbedding(doc)); + + // Create a new collection and set up configurations. + const newCollection = ((doc: Doc) => { + const docData = doc[DocData]; + docData.data = new List(newEmbeddings); + docData.title = this._props.tag; + docData.tags = new List([this._props.tag]); + docData.showTags = true; + docData.freeform_fitContentsToBox = true; + doc._freeform_panX = doc._freeform_panY = 0; + doc._width = 900; + doc._height = 900; + doc.layout_fitWidth = true; + return doc; + })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true)); + newEmbeddings.forEach(embed => Doc.SetContainer(embed, newCollection)); + + // Add the collection to the tag document's list of associated smart collections. + this._props.tagDoc && Doc.AddDocToList(this._props.tagDoc, 'collections', newCollection); + return newCollection; + }; + + @action + handleDragStart = (e: React.PointerEvent) => { + setupMoveUpEvents( + this, + e, + () => { + const dragData = new DragManager.DocumentDragData([this.createTagCollection()]); + DragManager.StartDocumentDrag([this._ref.current!], dragData, e.clientX, e.clientY, {}); + return true; + }, + returnFalse, + emptyFunction + ); + e.preventDefault(); + }; + + render() { + setTimeout(() => TagItem.addTagToDoc(this._props.doc, this._props.tag)); // bcz: hack to make sure that Docs are added to their tag Doc collection since metadata can get set anywhere without a guard triggering an add to the collection + const tag = this._props.tag.replace(/^#/, ''); + const metadata = tag.startsWith('@') ? tag.replace(/^@/, '') : ''; + return ( +
+ {metadata ? ( + + {tag}  + {this._props.doc[metadata] as string} + + ) : ( + tag + )} + {this.props.showRemoveUI && ( + TagItem.removeTagFromDoc(this._props.doc, this._props.tag, this._props.tagDoc), `remove tag ${this._props.tag}`)} + icon={} + style={{ width: '8px', height: '8px', marginLeft: '10px' }} + /> + )} +
+ ); + } +} + +interface TagViewProps { + View: DocumentView; +} + +/** + * Displays a panel of tags that have been added to a Doc. Also allows for editing the applied tags through a dropdown UI. + */ +@observer +export class TagsView extends ObservableReactComponent { + private _ref: React.RefObject; + + constructor(props: any) { + super(props); + makeObservable(this); + this._ref = React.createRef(); + } + + @observable _currentInput = ''; + @observable _isEditing = !StrListCast(this._props.View.dataDoc.tags).length; + + @computed get currentScale() { + return NumCast((this._props.View.Document.embedContainer as Doc)?._freeform_scale, 1); + } + @computed get isEditing() { + return this._isEditing && DocumentView.SelectedDocs().includes(this._props.View.Document); + } + + @action + setToEditing = (editing = true) => { + this._isEditing = editing; + editing && this._props.View.select(false); + }; + + /** + * Adds the specified tag to the Doc. If the tag is not prefixed with '#', then a '#' prefix is added. + * Whne the tag (after the '#') begins with '@', then a metadata key/value pair is displayed instead of + * just the tag. + * @param tag tag string to add + */ + submitTag = undoable((tag: string) => { + const submittedLabel = tag.trim(); + submittedLabel && TagItem.addTagToDoc(this._props.View.Document, '#' + submittedLabel.replace(/^#/, '')); + this._currentInput = ''; // Clear the input box + }, 'added doc label'); + + /** + * When 'showTags' is set on a Doc, this displays a wrapping panel of tagItemViews corresponding to all the tags set on the Doc). + * When the dropdown is clicked, this will toggle an extended UI that allows additional tags to be added/removed. + */ + render() { + const tagsList = StrListCast(this._props.View.dataDoc.tags); + + return !this._props.View.Document.showTags ? null : ( +
r && new ResizeObserver(action(() => (this._props.View.TagPanelHeight = r?.getBoundingClientRect().height ?? 0))).observe(r)} + style={{ + transformOrigin: 'top left', + maxWidth: `${100 * this.currentScale}%`, + width: 'max-content', + transform: `scale(${1 / this.currentScale})`, + backgroundColor: this.isEditing ? Colors.LIGHT_GRAY : Colors.TRANSPARENT, + borderColor: this.isEditing ? Colors.BLACK : Colors.TRANSPARENT, + }}> +
+
+ {!tagsList.length ? null : ( // + this.setToEditing(!this._isEditing)} icon={} /> + )} + {tagsList.map(tag => ( + + ))} +
+ {this.isEditing ? ( +
+
+ (this._currentInput = e.target.value))} + onKeyDown={e => { + e.key === 'Enter' ? this.submitTag(this._currentInput) : null; + e.stopPropagation(); + }} + type="text" + placeholder="Input tags for document..." + aria-label="tagsView-input" + className="tagsView-input" + style={{ width: '100%', borderRadius: '5px' }} + /> +
+
+ {TagItem.AllTagCollectionDocs.map((doc, i) => { + const tag = StrCast(doc.title); + return ( +
+
+ ) : null} +
+
+ ); + } +} diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index 421b5d0a6..6eb3eb784 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -1,30 +1,30 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Colors, IconButton } from 'browndash-components'; +import similarity from 'compute-cosine-similarity'; +import { ring } from 'ldrs'; +import 'ldrs/ring'; import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; +import { Utils, numberRange } from '../../../../Utils'; import { Doc, NumListCast, Opt } from '../../../../fields/Doc'; -import { Docs } from '../../../documents/Documents'; -import { DocumentType } from '../../../documents/DocumentTypes'; -import { ViewBoxBaseComponent } from '../../DocComponent'; -import { FieldView, FieldViewProps } from '../../nodes/FieldView'; -import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; -import './ImageLabelBox.scss'; -import { MainView } from '../../MainView'; -import 'ldrs/ring'; -import { ring } from 'ldrs'; -import { SnappingManager } from '../../../util/SnappingManager'; -import { ImageCast } from '../../../../fields/Types'; import { DocData } from '../../../../fields/DocSymbols'; -import { SettingsManager } from '../../../util/SettingsManager'; -import { CollectionCardView } from '../CollectionCardDeckView'; -import { gptGetEmbedding, gptImageLabel } from '../../../apis/gpt/GPT'; -import { numberRange, Utils } from '../../../../Utils'; import { List } from '../../../../fields/List'; +import { ImageCast } from '../../../../fields/Types'; +import { gptGetEmbedding, gptImageLabel } from '../../../apis/gpt/GPT'; +import { DocumentType } from '../../../documents/DocumentTypes'; +import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; -import { OpenWhere } from '../../nodes/OpenWhere'; -import similarity from 'compute-cosine-similarity'; +import { SettingsManager } from '../../../util/SettingsManager'; +import { SnappingManager } from '../../../util/SnappingManager'; +import { ViewBoxBaseComponent } from '../../DocComponent'; +import { MainView } from '../../MainView'; import { DocumentView } from '../../nodes/DocumentView'; +import { FieldView, FieldViewProps } from '../../nodes/FieldView'; +import { OpenWhere } from '../../nodes/OpenWhere'; +import { CollectionCardView } from '../CollectionCardDeckView'; +import './ImageLabelBox.scss'; +import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; export class ImageInformationItem {} @@ -139,9 +139,9 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { toggleDisplayInformation = () => { this._displayImageInformation = !this._displayImageInformation; if (this._displayImageInformation) { - this._selectedImages.forEach(doc => (doc[DocData].showLabels = true)); + this._selectedImages.forEach(doc => (doc[DocData].showTags = true)); } else { - this._selectedImages.forEach(doc => (doc[DocData].showLabels = false)); + this._selectedImages.forEach(doc => (doc[DocData].showTags = false)); } }; @@ -163,7 +163,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. const imageInfos = this._selectedImages.map(async doc => { - if (!doc[DocData].data_labels) { + if (!doc[DocData].tags) { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => !hrefBase64 ? undefined : @@ -174,14 +174,14 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { (await Promise.all(imageInfos)).forEach(imageInfo => { if (imageInfo) { - imageInfo.doc[DocData].data_labels = new List(); + imageInfo.doc[DocData].tags = (imageInfo.doc[DocData].tags as List) ?? new List(); const labels = imageInfo.labels.split('\n'); labels.forEach(label => { - label = label.replace(/^\d+\.\s*|-|\*/, '').trim(); + label = label.replace(/^\d+\.\s*|-|f\*/, '').trim(); console.log(label); - imageInfo.doc[DocData][`${label}`] = true; - (imageInfo.doc[DocData].data_labels as List).push(label); + imageInfo.doc[DocData][label] = true; + (imageInfo.doc[DocData].tags as List).push(label); }); } }); @@ -196,10 +196,10 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { this.startLoading(); for (const doc of this._selectedImages) { - for (let index = 0; index < (doc[DocData].data_labels as List).length; index++) { - const label = (doc[DocData].data_labels as List)[index]; + for (let index = 0; index < (doc[DocData].tags as List).length; index++) { + const label = (doc[DocData].tags as List)[index]; const embedding = await gptGetEmbedding(label); - doc[DocData][`data_labels_embedding_${index + 1}`] = new List(embedding); + doc[DocData][`tags_embedding_${index + 1}`] = new List(embedding); } } @@ -210,7 +210,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { // For each image, loop through the labels, and calculate similarity. Associate it with the // most similar one. this._selectedImages.forEach(doc => { - const embedLists = numberRange((doc[DocData].data_labels as List).length).map(n => Array.from(NumListCast(doc[DocData][`data_labels_embedding_${n + 1}`]))); + const embedLists = numberRange((doc[DocData].tags as List).length).map(n => Array.from(NumListCast(doc[DocData][`tags_embedding_${n + 1}`]))); const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map((l, index) => (embedding && similarity(Array.from(embedding), l)!) || 0)); const {label: mostSimilarLabelCollect} = this._labelGroups.map(label => ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) @@ -317,7 +317,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { await DocumentView.showDocument(doc, { willZoomCentered: true }); }}>
this._props.addDocTab(doc, OpenWhere.addRightKeyvalue)}> - {(doc[DocData].data_labels as List).map(label => { + {(doc[DocData].tags as List).map(label => { return (
{label} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 5efdb3df4..4c357cf45 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1124,6 +1124,7 @@ export class DocumentView extends DocComponent() { @observable private _isHovering = false; @observable private _selected = false; @observable public static CurrentlyPlaying: DocumentView[] = []; // audio or video media views that are currently playing + @observable public TagPanelHeight = 0; @computed private get shouldNotScale() { return (this.layout_fitWidth && !this.nativeWidth) || this.ComponentView?.isUnstyledView?.(); diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 79c118490..e0d6c7c05 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -404,7 +404,7 @@ export class RichTextRules { if (!tags.includes(tag)) { tags.push(tag); this.Document[DocData].tags = new List(tags); - this.Document[DocData].showLabels = true; + this.Document[DocData].showTags = true; } const fieldView = state.schema.nodes.dashField.create({ fieldKey: '#' + tag }); return state.tr diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index f246f49e5..ffb5aab79 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -11,7 +11,7 @@ import { ClientUtils, incrementTitleCopy } from '../ClientUtils'; import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, Animation, AudioPlay, Brushed, CachedUpdates, DirectLinks, DocAcl, DocCss, DocData, DocLayout, DocViews, FieldKeys, FieldTuples, ForceServerWrite, Height, Highlight, - Initializing, KeywordsHeight, Self, SelfProxy, TransitionTimer, UpdatingFromServer, Width + Initializing, Self, SelfProxy, TransitionTimer, UpdatingFromServer, Width } from './DocSymbols'; // prettier-ignore import { Copy, FieldChanged, HandleUpdate, Id, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols'; import { InkTool } from './InkField'; @@ -303,7 +303,6 @@ export class Doc extends RefField { Height, Highlight, Initializing, - KeywordsHeight, Self, SelfProxy, UpdatingFromServer, @@ -369,7 +368,6 @@ export class Doc extends RefField { @observable public [Highlight]: boolean = false; @observable public [Brushed]: boolean = false; @observable public [DocViews] = new ObservableSet(); - @observable public [KeywordsHeight]: number = 0; private [Self] = this; private [SelfProxy]: Doc; diff --git a/src/fields/DocSymbols.ts b/src/fields/DocSymbols.ts index 9e091ab29..dc18d8638 100644 --- a/src/fields/DocSymbols.ts +++ b/src/fields/DocSymbols.ts @@ -32,6 +32,5 @@ export const DocViews = Symbol('DocViews'); export const Brushed = Symbol('DocBrushed'); export const DocCss = Symbol('DocCss'); export const TransitionTimer = Symbol('DocTransitionTimer'); -export const KeywordsHeight = Symbol('DocKeywordsHeight'); export const DashVersion = 'v0.8.0'; -- cgit v1.2.3-70-g09d2 From 6bc79c5dfc5f61bf5d1b1544d399703c8006b898 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 10:59:56 -0400 Subject: cleanup of myXXXstuff on dashboards --- src/client/views/DashboardView.tsx | 5 +++-- src/client/views/TagsView.tsx | 6 +----- src/fields/Doc.ts | 8 ++++---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index dcc5442f0..f4fc8ee9f 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -429,7 +429,8 @@ export class DashboardView extends ObservableReactComponent { dashboardDoc.pane_count = 1; freeformDoc.embedContainer = dashboardDoc; dashboardDoc.myOverlayDocs = new List(); - dashboardDoc.myPublishedDocs = new List(); + dashboardDoc[DocData].myPublishedDocs = new List(); + dashboardDoc[DocData].myTagCollections = new List(); Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc); @@ -467,7 +468,7 @@ export class DashboardView extends ObservableReactComponent { }; const myCalendars = DocUtils.AssignScripts(Docs.Create.CalendarCollectionDocument([], reqdOpts)); // { treeView_ChildDoubleClick: 'openPresentation(documentView.rootDoc)' } - dashboardDoc.myCalendars = new PrefetchProxy(myCalendars); + dashboardDoc[DocData].myCalendars = new PrefetchProxy(myCalendars); } public static SetupDashboardTrails(dashboardDoc: Doc) { diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index dffd1e096..394162f46 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -70,11 +70,7 @@ export class TagItem extends ObservableReactComponent { newTagCol.title = tag; newTagCol.collections = new List(); newTagCol[DocData].docs = new List(); - // If the active Dashboard does not have a tag Doc collection, create it. - if (Doc.ActiveDashboard) { - if (!Doc.ActiveDashboard.myTagCollections) Doc.ActiveDashboard.myTagCollections = new List(); - Doc.AddDocToList(Doc.ActiveDashboard, 'myTagCollections', newTagCol); - } + Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard, 'myTagCollections', newTagCol); return newTagCol; }; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index ffb5aab79..e3178f20c 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -258,16 +258,16 @@ export class Doc extends RefField { public static set ActiveDashboard(val: Opt) { Doc.UserDoc().activeDashboard = val; } // prettier-ignore public static IsInMyOverlay(doc: Doc) { return Doc.MyOverlayDocs.includes(doc); } // prettier-ignore - public static AddToMyOverlay(doc: Doc) { return Doc.ActiveDashboard?.myOverlayDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myOverlayDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore - public static RemFromMyOverlay(doc: Doc) { return Doc.ActiveDashboard?.myOverlayDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myOverlayDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore + public static AddToMyOverlay(doc: Doc) { return Doc.ActiveDashboard ? Doc.AddDocToList(Doc.ActiveDashboard, 'myOverlayDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore + public static RemFromMyOverlay(doc: Doc) { return Doc.ActiveDashboard ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myOverlayDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore public static AddToMyPublished(doc: Doc) { doc[DocData].title_custom = true; doc[DocData].layout_showTitle = 'title'; - Doc.ActiveDashboard?.myPublishedDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myPublishedDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore + Doc.ActiveDashboard ? Doc.AddDocToList(Doc.ActiveDashboard, 'myPublishedDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore public static RemFromMyPublished(doc: Doc){ doc[DocData].title_custom = false; doc[DocData].layout_showTitle = undefined; - Doc.ActiveDashboard?.myPublishedDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myPublishedDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore + Doc.ActiveDashboard ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myPublishedDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore public static IsComicStyle(doc?: Doc) { return doc && Doc.ActiveDashboard && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === 'comic' ; } // prettier-ignore constructor(id?: FieldId, forceSave?: boolean) { -- cgit v1.2.3-70-g09d2 From cc3e1bc2c317cf34aba04e4935ae842b16ad4cae Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 11:22:38 -0400 Subject: cleanup of setting myXXstuff on dashboards --- src/client/views/DashboardView.tsx | 12 +++++------- .../collections/collectionFreeForm/FaceCollectionBox.tsx | 2 +- src/client/views/search/FaceRecognitionHandler.tsx | 12 ++++++------ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index f4fc8ee9f..4616e15e5 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -426,16 +426,14 @@ export class DashboardView extends ObservableReactComponent { const dashboardDoc = DashboardView.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row'); Doc.AddDocToList(Doc.MyHeaderBar, 'data', freeformDoc, undefined, undefined, true); + Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc); dashboardDoc.pane_count = 1; freeformDoc.embedContainer = dashboardDoc; dashboardDoc.myOverlayDocs = new List(); dashboardDoc[DocData].myPublishedDocs = new List(); dashboardDoc[DocData].myTagCollections = new List(); - - Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc); - - DashboardView.SetupDashboardTrails(dashboardDoc); - DashboardView.SetupDashboardCalendars(dashboardDoc); + dashboardDoc[DocData].myTrails = DashboardView.SetupDashboardTrails(dashboardDoc); + dashboardDoc[DocData].myCalendars = DashboardView.SetupDashboardCalendars(dashboardDoc); // open this new dashboard Doc.ActiveDashboard = dashboardDoc; Doc.ActivePage = 'dashboard'; @@ -468,7 +466,7 @@ export class DashboardView extends ObservableReactComponent { }; const myCalendars = DocUtils.AssignScripts(Docs.Create.CalendarCollectionDocument([], reqdOpts)); // { treeView_ChildDoubleClick: 'openPresentation(documentView.rootDoc)' } - dashboardDoc[DocData].myCalendars = new PrefetchProxy(myCalendars); + return new PrefetchProxy(myCalendars); } public static SetupDashboardTrails(dashboardDoc: Doc) { @@ -514,12 +512,12 @@ export class DashboardView extends ObservableReactComponent { layout_explainer: 'All of the trails that you have created will appear here.', }; const myTrails = DocUtils.AssignScripts(Docs.Create.TreeDocument([], reqdOpts), { treeView_ChildDoubleClick: 'openPresentation(documentView.Document)' }); - dashboardDoc.myTrails = new PrefetchProxy(myTrails); const contextMenuScripts = [reqdBtnScript.onClick]; if (Cast(myTrails.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) { myTrails.contextMenuScripts = new List(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!)); } + return new PrefetchProxy(myTrails); } } diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index de7c2c027..1cc1f59dc 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -164,7 +164,7 @@ export class UniqueFaceView extends ObservableReactComponent { * This renders the sidebar collection of the unique faces that have been recognized. * * Since the collection of recognized faces is stored on the active dashboard, this class - * does not itself store any Docs, but accesses the uniqueFaces field of the current + * does not itself store any Docs, but accesses the myUniqueFaces field of the current * dashboard. Each Face collection Doc is rendered using a FaceCollectionDocView which * is not a CollectionView or even a DocumentView (but probably should be). */ diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index f5fc12a8d..a17e4c54a 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -20,7 +20,7 @@ import { ImageField } from '../../../fields/URLField'; * _faceDescriptors - list of all the numerical face representations found in the image. * _faces - list of unique face Docs corresponding to recognized faces in the image. * - * unique face Doc's are created for each person identified and are stored in the Dashboard's uniqueFaces field + * unique face Doc's are created for each person identified and are stored in the Dashboard's myUniqueFaces field * * Each unique face Doc represents a unique face and collects all matching face images for that person. It has these fields: * face_label - a string label for the person that was recognized (TODO: currently it's just a 'face#') @@ -93,14 +93,14 @@ export class FaceRecognitionHandler { * returns a list of all face collection Docs on the current dashboard * @returns face collection Doc list */ - public static UniqueFaces = () => DocListCast(Doc.ActiveDashboard?.[DocData].uniqueFaces); + public static UniqueFaces = () => DocListCast(Doc.ActiveDashboard?.[DocData].myUniqueFaces); /** * Removes a unique face from the set of recognized unique faces * @param faceDoc unique face Doc * @returns */ - public static DeleteUniqueFace = (faceDoc: Doc) => Doc.ActiveDashboard && Doc.RemoveDocFromList(Doc.ActiveDashboard[DocData], 'uniqueFaces', faceDoc); + public static DeleteUniqueFace = (faceDoc: Doc) => Doc.ActiveDashboard && Doc.RemoveDocFromList(Doc.ActiveDashboard[DocData], 'myUniqueFaces', faceDoc); /** * returns the labels associated with a face collection Doc @@ -169,8 +169,8 @@ export class FaceRecognitionHandler { * @returns a unique face Doc */ private createUniqueFaceDoc = (dashboard: Doc) => { - const faceDocNum = NumCast(dashboard.uniqueFaces_count) + 1; - dashboard.uniqueFaces_count = faceDocNum; // TODO: improve to a better name + const faceDocNum = NumCast(dashboard.myUniqueFaces_count) + 1; + dashboard.myUniqueFaces_count = faceDocNum; // TODO: improve to a better name const uniqueFaceDoc = new Doc(); uniqueFaceDoc.title = `Face ${faceDocNum}`; @@ -179,7 +179,7 @@ export class FaceRecognitionHandler { uniqueFaceDoc.face_images = new List(); uniqueFaceDoc.face_descriptors = new List>(); - Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'uniqueFaces', uniqueFaceDoc); + Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'myUniqueFaces', uniqueFaceDoc); return uniqueFaceDoc; }; -- cgit v1.2.3-70-g09d2 From 2e345c1ebd498e3f7e088e6fc3e1ca17082b23c1 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 13:53:26 -0400 Subject: converted unique faces to be a Doc type similar to a collection. --- src/client/documents/DocumentTypes.ts | 1 + src/client/documents/Documents.ts | 4 + src/client/views/DashboardView.tsx | 1 + src/client/views/Main.tsx | 3 +- .../views/collections/CollectionStackingView.tsx | 3 +- src/client/views/collections/CollectionSubView.tsx | 1 + .../collectionFreeForm/FaceCollectionBox.scss | 24 ++++- .../collectionFreeForm/FaceCollectionBox.tsx | 113 +++++++++++++-------- src/client/views/search/FaceRecognitionHandler.tsx | 34 +++++-- 9 files changed, 123 insertions(+), 61 deletions(-) diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 49df943d8..b055546fc 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -18,6 +18,7 @@ export enum DocumentType { SEARCH = 'search', // search query IMAGEGROUPER = 'imagegrouper', FACECOLLECTION = 'facecollection', + UFACE = 'uniqueface', // unique face collection doc LABEL = 'label', // simple text label BUTTON = 'button', // onClick button WEBCAM = 'webcam', // webcam diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index c0e4e961c..c2211fb80 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -795,6 +795,10 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.FACECOLLECTION), undefined, options); } + export function UniqeFaceDocument(options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.UFACE), undefined, options); + } + export function LoadingDocument(file: File | string, options: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.LOADING), undefined, { _height: 150, _width: 200, title: typeof file === 'string' ? file : file.name, ...options }, undefined, ''); } diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 4616e15e5..33e905a54 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -432,6 +432,7 @@ export class DashboardView extends ObservableReactComponent { dashboardDoc.myOverlayDocs = new List(); dashboardDoc[DocData].myPublishedDocs = new List(); dashboardDoc[DocData].myTagCollections = new List(); + dashboardDoc[DocData].myUniqueFaces = new List(); dashboardDoc[DocData].myTrails = DashboardView.SetupDashboardTrails(dashboardDoc); dashboardDoc[DocData].myCalendars = DashboardView.SetupDashboardCalendars(dashboardDoc); // open this new dashboard diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 023324881..f7cd0e925 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -63,7 +63,7 @@ import { PresBox, PresElementBox } from './nodes/trails'; import { SearchBox } from './search/SearchBox'; import { ImageLabelBox } from './collections/collectionFreeForm/ImageLabelBox'; import { FaceRecognitionHandler } from './search/FaceRecognitionHandler'; -import { FaceCollectionBox } from './collections/collectionFreeForm/FaceCollectionBox'; +import { FaceCollectionBox, UniqueFaceBox } from './collections/collectionFreeForm/FaceCollectionBox'; import { Node } from 'prosemirror-model'; import { EditorView } from 'prosemirror-view'; @@ -140,6 +140,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' }; SearchBox, ImageLabelBox, FaceCollectionBox, + UniqueFaceBox, FunctionPlotBox, InkingStroke, LinkBox, diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 3f8aee792..6402ef16c 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -98,7 +98,7 @@ export class CollectionStackingView extends CollectionSubView Doc | undefined; // specify a layout Doc template to use for children of the collection childHideDecorationTitle?: boolean; childHideResizeHandles?: boolean; + childHideDecorations?: boolean; childDragAction?: dropActionType; childXPadding?: number; childYPadding?: number; diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss index 480d109c8..86120f966 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss @@ -1,10 +1,11 @@ .face-document-item { - background: #555555; margin-top: 10px; margin-bottom: 10px; padding: 10px; - border-radius: 10px; + border-radius: inherit; position: relative; + width: 100%; + height: 100%; h1 { color: white; @@ -14,14 +15,31 @@ .face-collection-buttons { position: absolute; - top: 10px; + top: 0px; right: 10px; } + .face-collection-toggle { + position: absolute; + top: 0px; + left: 10px; + } + .face-document-top { + position: absolute; + top: 0; + margin: auto; + width: 100%; + left: 0; + } .face-document-image-container { display: flex; justify-content: center; flex-wrap: wrap; + overflow-x: hidden; + overflow-y: auto; + position: absolute; + top: 75px; + height: calc(100% - 75px); .image-wrapper { position: relative; diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 1cc1f59dc..6a0d51e32 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -6,23 +6,21 @@ import 'ldrs/ring'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; -import { setupMoveUpEvents } from '../../../../ClientUtils'; -import { Utils, emptyFunction } from '../../../../Utils'; +import { lightOrDark, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils'; +import { emptyFunction } from '../../../../Utils'; import { Doc, Opt } from '../../../../fields/Doc'; -import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; -import { ImageCast } from '../../../../fields/Types'; +import { ImageCast, StrCast } from '../../../../fields/Types'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; import { dropActionType } from '../../../util/DropActionTypes'; -import { SnappingManager } from '../../../util/SnappingManager'; import { undoable } from '../../../util/UndoManager'; import { ViewBoxBaseComponent } from '../../DocComponent'; -import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocumentView } from '../../nodes/DocumentView'; import { FieldView, FieldViewProps } from '../../nodes/FieldView'; import { FaceRecognitionHandler } from '../../search/FaceRecognitionHandler'; +import { CollectionStackingView } from '../CollectionStackingView'; import './FaceCollectionBox.scss'; import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; @@ -31,31 +29,29 @@ import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; * unique face in turn displays the set of images that correspond to the face. */ -interface UniqueFaceProps { - faceDoc: Doc; -} - /** - * React component for rendering a unique face and its collection of image Docs. + * Viewer for unique face Doc collections. * * This both displays a collection of images corresponding tp a unique face, and * allows for editing the face collection by removing an image, or drag-and-dropping * an image that was not recognized. */ @observer -export class UniqueFaceView extends ObservableReactComponent { +export class UniqueFaceBox extends ViewBoxBaseComponent() { + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(UniqueFaceBox, fieldKey); + } private _dropDisposer?: DragManager.DragDropDisposer; + private _oldWheel: HTMLElement | null = null; - constructor(props: UniqueFaceProps) { + constructor(props: FieldViewProps) { super(props); makeObservable(this); } - @observable _displayImages: boolean = true; - protected createDropTarget = (ele: HTMLDivElement) => { this._dropDisposer?.(); - ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this._props.faceDoc)); + ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this._props.Document)); }; protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { @@ -63,12 +59,12 @@ export class UniqueFaceView extends ObservableReactComponent { ?.filter(doc => doc.type === DocumentType.IMG) .forEach(imgDoc => { // If the current Face Document has no faces, and the doc has more than one face descriptor, don't let the user add the document first. Or should we just use the first face ? - if (FaceRecognitionHandler.UniqueFaceDescriptors(this._props.faceDoc).length === 0 && FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).length > 1) { + if (FaceRecognitionHandler.UniqueFaceDescriptors(this._props.Document).length === 0 && FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).length > 1) { alert('Cannot add a document with multiple faces as the first item!'); } else { // Loop through the documents' face descriptors and choose the face in the iage with the smallest distance (most similar to the face colleciton) - const faceDescriptorsAsFloat32Array = FaceRecognitionHandler.UniqueFaceDescriptors(this._props.faceDoc).map(fd => new Float32Array(Array.from(fd))); - const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(this._props.faceDoc), faceDescriptorsAsFloat32Array); + const faceDescriptorsAsFloat32Array = FaceRecognitionHandler.UniqueFaceDescriptors(this._props.Document).map(fd => new Float32Array(Array.from(fd))); + const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(this._props.Document), faceDescriptorsAsFloat32Array); const faceMatcher = new FaceMatcher([labeledFaceDescriptor], 1); const { face_match } = FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).reduce( (prev, face) => { @@ -80,11 +76,12 @@ export class UniqueFaceView extends ObservableReactComponent { // assign the face in the image that's closest to the face collection to be the face that's assigned to the collection if (face_match) { - FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, face_match, this._props.faceDoc); + FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, face_match, this._props.Document); } } }); - return false; + e.stopPropagation(); + return true; } /** @@ -92,14 +89,15 @@ export class UniqueFaceView extends ObservableReactComponent { */ @action onDisplayClick() { - this._displayImages = !this._displayImages; + this._props.Document._displayImages = !this.props.Document._displayImages; + this._props.Document.height = this._props.Document._displayImages ? 400 : 100; } /** * Removes a unique face Doc from the colelction of unique faces. */ deleteUniqueFace = undoable(() => { - FaceRecognitionHandler.DeleteUniqueFace(this._props.faceDoc); + FaceRecognitionHandler.DeleteUniqueFace(this._props.Document); }, 'delete face'); /** @@ -107,9 +105,11 @@ export class UniqueFaceView extends ObservableReactComponent { * @param imgDoc - image Doc to remove */ removeFaceImageFromUniqueFace = undoable((imgDoc: Doc) => { - FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, this._props.faceDoc); + FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, this._props.Document); }, 'remove doc from face'); + onPassiveWheel = (e: WheelEvent) => e.stopPropagation(); + render() { return (
this.createDropTarget(ele!)}> @@ -117,23 +117,35 @@ export class UniqueFaceView extends ObservableReactComponent {
-

{FaceRecognitionHandler.UniqueFaceLabel(this._props.faceDoc)}

+

{FaceRecognitionHandler.UniqueFaceLabel(this._props.Document)}

- this.onDisplayClick()} - icon={} - color={MarqueeOptionsMenu.Instance.userColor} - style={{ width: '19px' }} - /> - {this._displayImages ? ( -
- {FaceRecognitionHandler.UniqueFaceImages(this._props.faceDoc).map(doc => { +
+ this.onDisplayClick()} + icon={} + color={MarqueeOptionsMenu.Instance.userColor} + style={{ width: '19px' }} + /> +
+ {this.props.Document._displayImages ? ( +
{ + this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel); + this._oldWheel = ele; + // prevent wheel events from passively propagating up through containers and prevents containers from preventDefault which would block scrolling + ele?.addEventListener('wheel', this.onPassiveWheel, { passive: false }); + }}> + {FaceRecognitionHandler.UniqueFaceImages(this._props.Document).map((doc, i) => { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return (
setupMoveUpEvents( this, @@ -165,8 +177,8 @@ export class UniqueFaceView extends ObservableReactComponent { * * Since the collection of recognized faces is stored on the active dashboard, this class * does not itself store any Docs, but accesses the myUniqueFaces field of the current - * dashboard. Each Face collection Doc is rendered using a FaceCollectionDocView which - * is not a CollectionView or even a DocumentView (but probably should be). + * dashboard. (This should probably go away as Doc type in favor of it just being a + * stacking collection of uniqueFace docs) */ @observer export class FaceCollectionBox extends ViewBoxBaseComponent() { @@ -179,18 +191,29 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { makeObservable(this); } + moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => !!(this._props.removeDocument?.(doc) && addDocument?.(doc)); + render() { - return ( -
- {FaceRecognitionHandler.UniqueFaces().map(doc => ( - - ))} -
+ return !Doc.ActiveDashboard ? null : ( + ); } } Docs.Prototypes.TemplateMap.set(DocumentType.FACECOLLECTION, { layout: { view: FaceCollectionBox, dataField: 'data' }, - options: { acl: '', _width: 400 }, + options: { acl: '', _width: 400, dropAction: dropActionType.embed }, +}); + +Docs.Prototypes.TemplateMap.set(DocumentType.UFACE, { + layout: { view: UniqueFaceBox, dataField: 'face_images' }, + options: { acl: '', _width: 400, _height: 400 }, }); diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index a17e4c54a..1ab084eaa 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -8,6 +8,8 @@ import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; import { ImageField } from '../../../fields/URLField'; +import { UniqueFaceBox } from '../collections/collectionFreeForm/FaceCollectionBox'; +import { Docs } from '../../documents/Documents'; /** * A singleton class that handles face recognition and manages face Doc collections for each face found. @@ -169,15 +171,25 @@ export class FaceRecognitionHandler { * @returns a unique face Doc */ private createUniqueFaceDoc = (dashboard: Doc) => { - const faceDocNum = NumCast(dashboard.myUniqueFaces_count) + 1; - dashboard.myUniqueFaces_count = faceDocNum; // TODO: improve to a better name - - const uniqueFaceDoc = new Doc(); - uniqueFaceDoc.title = `Face ${faceDocNum}`; - uniqueFaceDoc.face = ''; // just to make prettyprinting look better - uniqueFaceDoc.face_label = `Face${faceDocNum}`; - uniqueFaceDoc.face_images = new List(); - uniqueFaceDoc.face_descriptors = new List>(); + const faceDocNum = NumCast(dashboard[DocData].myUniqueFaces_count) + 1; + dashboard[DocData].myUniqueFaces_count = faceDocNum; // TODO: improve to a better name + + const uniqueFaceDoc = Docs.Create.UniqeFaceDocument({ + title: `Face ${faceDocNum}`, + _layout_reflowHorizontal: true, + _layout_reflowVertical: true, + _layout_nativeDimEditable: true, + _layout_borderRounding: '20px', + backgroundColor: '#555555', + _width: 400, + _height: 400, + }); + const uface = uniqueFaceDoc[DocData]; + uface.face = ''; // just to make prettyprinting look better + uface.face_label = `Face${faceDocNum}`; + uface.face_images = new List(); + uface.face_descriptors = new List>(); + Doc.SetContainer(uniqueFaceDoc, Doc.MyFaceCollection); Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'myUniqueFaces', uniqueFaceDoc); return uniqueFaceDoc; @@ -222,8 +234,8 @@ export class FaceRecognitionHandler { setTimeout(() => this.classifyFacesInImage(imgDoc), 1000); } else { const imgUrl = ImageCast(imgDoc[Doc.LayoutFieldKey(imgDoc)]); - if (imgUrl && !DocListCast(Doc.MyFaceCollection.examinedFaceDocs).includes(imgDoc)) { // only examine Docs that have an image and that haven't already been examined. - Doc.AddDocToList(Doc.MyFaceCollection, 'examinedFaceDocs', imgDoc); + if (imgUrl && !DocListCast(Doc.MyFaceCollection.examinedFaceDocs).includes(imgDoc[DocData])) { // only examine Docs that have an image and that haven't already been examined. + Doc.AddDocToList(Doc.MyFaceCollection, 'examinedFaceDocs', imgDoc[DocData]); FaceRecognitionHandler.initImageDocFaceDescriptors(imgDoc); FaceRecognitionHandler.loadImage(imgUrl).then( // load image and analyze faces img => faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors() -- cgit v1.2.3-70-g09d2 From d12b43191e01e837d5a144fb19d9d3cd8eadd777 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 15:17:14 -0400 Subject: from last --- src/client/documents/Documents.ts | 1 + .../collectionFreeForm/FaceCollectionBox.scss | 19 ++++--- .../collectionFreeForm/FaceCollectionBox.tsx | 60 ++++++++++++++-------- src/client/views/search/FaceRecognitionHandler.tsx | 5 +- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index c2211fb80..ac271526f 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -362,6 +362,7 @@ export class DocumentOptions { data?: FieldType; data_useCors?: BOOLt = new BoolInfo('whether CORS protocol should be used for web page'); + _face_showImages?: BOOLt = new BoolInfo('whether to show images in uniqe face Doc'); columnHeaders?: List; // headers for stacking views schemaHeaders?: List; // headers for schema view dockingConfig?: STRt = new StrInfo('configuration of golden layout windows (applies only if doc is rendered as a CollectionDockingView)', false); diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss index 86120f966..00297a97d 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss @@ -1,11 +1,10 @@ .face-document-item { - margin-top: 10px; - margin-bottom: 10px; - padding: 10px; - border-radius: inherit; - position: relative; + display: flex; + height: max-content; + flex-direction: column; + top: 0; + position: absolute; width: 100%; - height: 100%; h1 { color: white; @@ -24,11 +23,12 @@ left: 10px; } .face-document-top { - position: absolute; + position: relative; top: 0; margin: auto; width: 100%; left: 0; + height: 60px; } .face-document-image-container { @@ -37,9 +37,8 @@ flex-wrap: wrap; overflow-x: hidden; overflow-y: auto; - position: absolute; - top: 75px; - height: calc(100% - 75px); + position: relative; + padding: 10px; .image-wrapper { position: relative; diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 6a0d51e32..33fc3c210 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -3,14 +3,14 @@ import { IconButton, Size } from 'browndash-components'; import * as faceapi from 'face-api.js'; import { FaceMatcher } from 'face-api.js'; import 'ldrs/ring'; -import { action, makeObservable, observable } from 'mobx'; +import { IReactionDisposer, action, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; -import { lightOrDark, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils'; +import { DivHeight, lightOrDark, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; import { Doc, Opt } from '../../../../fields/Doc'; import { List } from '../../../../fields/List'; -import { ImageCast, StrCast } from '../../../../fields/Types'; +import { ImageCast, NumCast, StrCast } from '../../../../fields/Types'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; @@ -48,10 +48,29 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { super(props); makeObservable(this); } + @observable _headerRef: HTMLDivElement | null = null; + @observable _listRef: HTMLDivElement | null = null; + _disposers: { [key: string]: IReactionDisposer } = {}; + _lastHeight = 0; + observer = new ResizeObserver(() => this._props.setHeight?.((this.props.Document._face_showImages ? 20 : 0) + (!this._headerRef ? 0 : DivHeight(this._headerRef)) + (!this._listRef ? 0 : DivHeight(this._listRef)))); + + componentDidMount(): void { + this._disposers.refList = reaction( + () => ({ refList: [this._headerRef, this._listRef], autoHeight: this.layoutDoc._layout_autoHeight && !DocumentView.LightboxContains(this.DocumentView?.()) }), + ({ refList, autoHeight }) => { + this.observer.disconnect(); + if (autoHeight) refList.filter(r => r).forEach(r => this.observer.observe(r!)); + }, + { fireImmediately: true } + ); + } + componentWillUnmount(): void { + //this._disposers?.(); + } protected createDropTarget = (ele: HTMLDivElement) => { this._dropDisposer?.(); - ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this._props.Document)); + ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.Document)); }; protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { @@ -59,12 +78,12 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { ?.filter(doc => doc.type === DocumentType.IMG) .forEach(imgDoc => { // If the current Face Document has no faces, and the doc has more than one face descriptor, don't let the user add the document first. Or should we just use the first face ? - if (FaceRecognitionHandler.UniqueFaceDescriptors(this._props.Document).length === 0 && FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).length > 1) { + if (FaceRecognitionHandler.UniqueFaceDescriptors(this.Document).length === 0 && FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).length > 1) { alert('Cannot add a document with multiple faces as the first item!'); } else { // Loop through the documents' face descriptors and choose the face in the iage with the smallest distance (most similar to the face colleciton) - const faceDescriptorsAsFloat32Array = FaceRecognitionHandler.UniqueFaceDescriptors(this._props.Document).map(fd => new Float32Array(Array.from(fd))); - const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(this._props.Document), faceDescriptorsAsFloat32Array); + const faceDescriptorsAsFloat32Array = FaceRecognitionHandler.UniqueFaceDescriptors(this.Document).map(fd => new Float32Array(Array.from(fd))); + const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(this.Document), faceDescriptorsAsFloat32Array); const faceMatcher = new FaceMatcher([labeledFaceDescriptor], 1); const { face_match } = FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).reduce( (prev, face) => { @@ -76,7 +95,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { // assign the face in the image that's closest to the face collection to be the face that's assigned to the collection if (face_match) { - FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, face_match, this._props.Document); + FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, face_match, this.Document); } } }); @@ -87,17 +106,17 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { /** * Toggles whether a Face Document displays its associated docs. */ - @action onDisplayClick() { - this._props.Document._displayImages = !this.props.Document._displayImages; - this._props.Document.height = this._props.Document._displayImages ? 400 : 100; + this.Document._face_showImages && (this._lastHeight = NumCast(this.Document.height)); + this.Document._face_showImages = !this.Document._face_showImages; + setTimeout(action(() => (!this.Document.layout_autoHeight || !this.Document._face_showImages) && (this.Document.height = this.Document._face_showImages ? this._lastHeight : 60))); } /** * Removes a unique face Doc from the colelction of unique faces. */ deleteUniqueFace = undoable(() => { - FaceRecognitionHandler.DeleteUniqueFace(this._props.Document); + FaceRecognitionHandler.DeleteUniqueFace(this.Document); }, 'delete face'); /** @@ -105,7 +124,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { * @param imgDoc - image Doc to remove */ removeFaceImageFromUniqueFace = undoable((imgDoc: Doc) => { - FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, this._props.Document); + FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, this.Document); }, 'remove doc from face'); onPassiveWheel = (e: WheelEvent) => e.stopPropagation(); @@ -116,31 +135,32 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() {
-
-

{FaceRecognitionHandler.UniqueFaceLabel(this._props.Document)}

+
(this._headerRef = r))}> +

{FaceRecognitionHandler.UniqueFaceLabel(this.Document)}

this.onDisplayClick()} - icon={} + icon={} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} />
- {this.props.Document._displayImages ? ( + {this.props.Document._face_showImages ? (
{ + ref={action((ele: HTMLDivElement | null) => { + this._listRef = ele; this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel); this._oldWheel = ele; // prevent wheel events from passively propagating up through containers and prevents containers from preventDefault which would block scrolling ele?.addEventListener('wheel', this.onPassiveWheel, { passive: false }); - }}> - {FaceRecognitionHandler.UniqueFaceImages(this._props.Document).map((doc, i) => { + })}> + {FaceRecognitionHandler.UniqueFaceImages(this.Document).map((doc, i) => { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return (
Date: Mon, 26 Aug 2024 16:46:13 -0400 Subject: added recognizeFaces for face images --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/util/SettingsManager.tsx | 11 ++++++ src/client/views/StyleProvider.tsx | 2 + .../collectionFreeForm/FaceCollectionBox.scss | 11 +++++- .../collectionFreeForm/FaceCollectionBox.tsx | 45 +++++++++++++++------- src/client/views/search/FaceRecognitionHandler.tsx | 1 + 6 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 0681a21cb..dc0c95121 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -497,7 +497,7 @@ pie title Minerals in my tap water static setupFaceCollection(doc: Doc, field: string) { return DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.FaceCollectionDocument(opts), { - dontRegisterView: true, backgroundColor: "dimgray", ignoreClick: true, title: "Face Collection", isSystem: true, childDragAction: dropActionType.embed, + dontRegisterView: true, ignoreClick: true, title: "Face Collection", isSystem: true, childDragAction: dropActionType.embed, _lockedPosition: true, _type_collection: CollectionViewType.Schema }); } diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 2d8763b63..fde8869e3 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -231,6 +231,17 @@ export class SettingsManager extends React.Component { size={Size.XSMALL} color={SettingsManager.userColor} /> + { + Doc.UserDoc().recognizeFaceImages = !Doc.UserDoc().recognizeFaceImages; + }} + toggleStatus={BoolCast(Doc.UserDoc().recognizeFaceImages)} + size={Size.XSMALL} + color={SettingsManager.userColor} + /> , props: Opt() { } private _dropDisposer?: DragManager.DragDropDisposer; private _oldWheel: HTMLElement | null = null; + private _disposers: { [key: string]: IReactionDisposer } = {}; + private _lastHeight = 0; constructor(props: FieldViewProps) { super(props); @@ -50,13 +52,17 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { } @observable _headerRef: HTMLDivElement | null = null; @observable _listRef: HTMLDivElement | null = null; - _disposers: { [key: string]: IReactionDisposer } = {}; - _lastHeight = 0; - observer = new ResizeObserver(() => this._props.setHeight?.((this.props.Document._face_showImages ? 20 : 0) + (!this._headerRef ? 0 : DivHeight(this._headerRef)) + (!this._listRef ? 0 : DivHeight(this._listRef)))); + observer = new ResizeObserver(a => { + this._props.setHeight?.( + (this.props.Document._face_showImages ? 20 : 0) + // + (!this._headerRef ? 0 : DivHeight(this._headerRef)) + + (!this._listRef ? 0 : DivHeight(this._listRef)) + ); + }); componentDidMount(): void { this._disposers.refList = reaction( - () => ({ refList: [this._headerRef, this._listRef], autoHeight: this.layoutDoc._layout_autoHeight && !DocumentView.LightboxContains(this.DocumentView?.()) }), + () => ({ refList: [this._headerRef, this._listRef], autoHeight: this.layoutDoc._layout_autoHeight }), ({ refList, autoHeight }) => { this.observer.disconnect(); if (autoHeight) refList.filter(r => r).forEach(r => this.observer.observe(r!)); @@ -66,7 +72,8 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { } componentWillUnmount(): void { - //this._disposers?.(); + this.observer.disconnect(); + Object.keys(this._disposers).forEach(key => this._disposers[key]()); } protected createDropTarget = (ele: HTMLDivElement) => { this._dropDisposer?.(); @@ -213,17 +220,27 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => !!(this._props.removeDocument?.(doc) && addDocument?.(doc)); + stackingStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { + if (doc === Doc.ActiveDashboard) return this._props.styleProvider?.(this.Document, this._props, property); + return this._props.styleProvider?.(doc, this._props, property); + }; render() { return !Doc.ActiveDashboard ? null : ( - +
+
+
(Doc.UserDoc().recognizeFaceImages = !Doc.UserDoc().recognizeFaceImages))}>{`Face Recgognition is ${Doc.UserDoc().recognizeFaceImages ? 'on' : 'off'}`}
+
+ +
); } } diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index f613f78ce..7c8043219 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -230,6 +230,7 @@ export class FaceRecognitionHandler { * @param imgDoc The document being analyzed. */ private classifyFacesInImage = async (imgDoc: Doc) => { + if (!Doc.UserDoc().recognizeFaceImages) return; const activeDashboard = Doc.ActiveDashboard; if (!this._apiModelReady || !activeDashboard) { this._pendingAPIModelReadyDocs.push(imgDoc); -- cgit v1.2.3-70-g09d2 From 66daf540d581d49af5d5901963dbb95cbc2643a0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 20:19:27 -0400 Subject: from last --- src/client/views/search/FaceRecognitionHandler.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 7c8043219..e35f860ab 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -183,7 +183,6 @@ export class FaceRecognitionHandler { _layout_fitWidth: true, _layout_autoHeight: true, _face_showImages: true, - backgroundColor: '#555555', _width: 400, _height: 100, }); -- cgit v1.2.3-70-g09d2 From c4586cb36939561a8d0dd2dcbab4a20c51aaba5f Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 20:23:23 -0400 Subject: from last --- src/client/util/CurrentUserUtils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index dc0c95121..14fb65252 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -451,10 +451,10 @@ pie title Minerals in my tap water { title: "Closed", toolTip: "Recently Closed", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), ignoreClick: true, icon: "archive", hidden: true }, // this doc is hidden from the Sidebar, but it's still being used in MyFilesystem which ignores the hidden field { title: "Shared", toolTip: "Shared Docs", target: Doc.MySharedDocs, ignoreClick: true, icon: "users", funcs: {badgeValue: badgeValue}}, { title: "Trails", toolTip: "Trails ⌘R", target: Doc.UserDoc(), ignoreClick: true, icon: "pres-trail", funcs: {target: getActiveDashTrails}}, - { title: "User Doc", toolTip: "User Doc", target: this.setupUserDocView(doc, "myUserDocView"), ignoreClick: true, icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, { title: "Image Grouper", toolTip: "Image Grouper", target: this.setupImageGrouper(doc, "myImageGrouper"), ignoreClick: true, icon: "folder-open", hidden: false }, - { title: "Face Collection", toolTip: "Face Collection", target: this.setupFaceCollection(doc, "myFaceCollection"), ignoreClick: true, icon: "face-smile", hidden: false }, - ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(this)'}})); + { title: "Faces", toolTip: "Unique Faces", target: this.setupFaceCollection(doc, "myFaceCollection"), ignoreClick: true, icon: "face-smile", hidden: false }, + { title: "User Doc", toolTip: "User Doc", target: this.setupUserDocView(doc, "myUserDocView"), ignoreClick: true, icon: "address-card",funcs: {hidden: "IsNoviceMode()"} }, + ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(this)'}})); } /// the empty panel that is filled with whichever left menu button's panel has been selected -- cgit v1.2.3-70-g09d2 From 9a92fa403a5e2a094763d6f92ac55549aecf359c Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 20:38:01 -0400 Subject: cleanup of faces and tags --- src/client/views/TagsView.tsx | 4 ++++ .../collectionFreeForm/FaceCollectionBox.tsx | 17 +++++++++++++---- src/client/views/search/FaceRecognitionHandler.tsx | 5 ++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index 394162f46..82c85ddf0 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -252,6 +252,10 @@ export class TagsView extends ObservableReactComponent { return this._isEditing && DocumentView.SelectedDocs().includes(this._props.View.Document); } + /** + * Shows or hides the editing UI for adding/removing Doc tags + * @param editing + */ @action setToEditing = (editing = true) => { this._isEditing = editing; diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 7820af8aa..662436ddc 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -42,7 +42,6 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { return FieldView.LayoutString(UniqueFaceBox, fieldKey); } private _dropDisposer?: DragManager.DragDropDisposer; - private _oldWheel: HTMLElement | null = null; private _disposers: { [key: string]: IReactionDisposer } = {}; private _lastHeight = 0; @@ -50,8 +49,10 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { super(props); makeObservable(this); } + @observable _headerRef: HTMLDivElement | null = null; @observable _listRef: HTMLDivElement | null = null; + observer = new ResizeObserver(a => { this._props.setHeight?.( (this.props.Document._face_showImages ? 20 : 0) + // @@ -75,6 +76,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { this.observer.disconnect(); Object.keys(this._disposers).forEach(key => this._disposers[key]()); } + protected createDropTarget = (ele: HTMLDivElement) => { this._dropDisposer?.(); ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.Document)); @@ -111,7 +113,8 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { } /** - * Toggles whether a Face Document displays its associated docs. + * Toggles whether a Face Document displays its associated docs. This saves and restores the last height of the Doc since + * toggling the associated Documentss overwrites the Doc height. */ onDisplayClick() { this.Document._face_showImages && (this._lastHeight = NumCast(this.Document.height)); @@ -134,6 +137,9 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, this.Document); }, 'remove doc from face'); + /** + * This stops scroll wheel events when they are used to scroll the face collection. + */ onPassiveWheel = (e: WheelEvent) => e.stopPropagation(); render() { @@ -161,9 +167,8 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { pointerEvents: this._props.isContentActive() ? undefined : 'none', }} ref={action((ele: HTMLDivElement | null) => { + this._listRef?.removeEventListener('wheel', this.onPassiveWheel); this._listRef = ele; - this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel); - this._oldWheel = ele; // prevent wheel events from passively propagating up through containers and prevents containers from preventDefault which would block scrolling ele?.addEventListener('wheel', this.onPassiveWheel, { passive: false }); })}> @@ -220,6 +225,10 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => !!(this._props.removeDocument?.(doc) && addDocument?.(doc)); + /** + * this changes style provider requests that target the dashboard to requests that target the face collection box which is what's actually being rendered. + * This is needed, for instance, to get the default background color from the face collection, not the dashboard. + */ stackingStyleProvider = (doc: Doc | undefined, props: Opt, property: string) => { if (doc === Doc.ActiveDashboard) return this._props.styleProvider?.(this.Document, this._props, property); return this._props.styleProvider?.(doc, this._props, property); diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index e35f860ab..8513ec94d 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -5,11 +5,10 @@ import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; -import { DocumentType } from '../../documents/DocumentTypes'; -import { DocumentManager } from '../../util/DocumentManager'; import { ImageField } from '../../../fields/URLField'; -import { UniqueFaceBox } from '../collections/collectionFreeForm/FaceCollectionBox'; +import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; +import { DocumentManager } from '../../util/DocumentManager'; /** * A singleton class that handles face recognition and manages face Doc collections for each face found. -- cgit v1.2.3-70-g09d2 From b1e88ebc95cb7cdd18b8ba42bb267bcd9372154a Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 20:46:22 -0400 Subject: import updates --- package-lock.json | 1310 +++++++++++++++++++---------------------------------- package.json | 8 +- 2 files changed, 461 insertions(+), 857 deletions(-) diff --git a/package-lock.json b/package-lock.json index b17a5693a..1e738fcb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/textfit": "^2.4.4", - "@types/web": "^0.0.155", + "@types/web": "^0.0.157", "@types/webpack-hot-middleware": "^2.25.9", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", @@ -144,7 +144,7 @@ "mathquill": "^0.10.1-a", "md5-file": "^5.0.0", "memorystream": "^0.3.1", - "mermaid": "^10.9.1", + "mermaid": "^11.0.2", "mobile-detect": "^1.4.5", "mobx": "^6.12.0", "mobx-react": "^9.1.0", @@ -292,13 +292,13 @@ "@types/valid-url": "^1.0.7", "@types/webpack": "^5.28.5", "@types/webscopeio__react-textarea-autocomplete": "^4.7.5", - "@types/youtube": "0.0.50", + "@types/youtube": "^0.1.0", "chai": "^5.0.0", "cross-env": "^7.0.3", "eslint": "^9.9.0", "eslint-plugin-react": "^7.34.1", "globals": "^15.1.0", - "jsdom": "^24.0.0", + "jsdom": "^25.0.0", "mocha": "^10.2.0", "prettier": "^3.1.0", "scss-loader": "0.0.1", @@ -659,9 +659,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", - "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "engines": { "node": ">=6.9.0" } @@ -697,11 +697,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", - "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "version": "7.25.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.5.tgz", + "integrity": "sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==", "dependencies": { - "@babel/types": "^7.25.0", + "@babel/types": "^7.25.4", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -749,16 +749,16 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", - "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", "@babel/helper-member-expression-to-functions": "^7.24.8", "@babel/helper-optimise-call-expression": "^7.24.7", "@babel/helper-replace-supers": "^7.25.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.0", + "@babel/traverse": "^7.25.4", "semver": "^6.3.1" }, "engines": { @@ -980,11 +980,11 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", - "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.4.tgz", + "integrity": "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==", "dependencies": { - "@babel/types": "^7.25.2" + "@babel/types": "^7.25.4" }, "bin": { "parser": "bin/babel-parser.js" @@ -1324,14 +1324,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", - "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", + "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", "dependencies": { "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-remap-async-to-generator": "^7.25.0", "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/traverse": "^7.25.0" + "@babel/traverse": "^7.25.4" }, "engines": { "node": ">=6.9.0" @@ -1385,12 +1385,12 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", + "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1416,15 +1416,15 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz", - "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", + "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-compilation-targets": "^7.25.2", "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-replace-supers": "^7.25.0", - "@babel/traverse": "^7.25.0", + "@babel/traverse": "^7.25.4", "globals": "^11.1.0" }, "engines": { @@ -1849,12 +1849,12 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", + "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -2100,12 +2100,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", + "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -2115,11 +2115,11 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz", - "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz", + "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==", "dependencies": { - "@babel/compat-data": "^7.25.2", + "@babel/compat-data": "^7.25.4", "@babel/helper-compilation-targets": "^7.25.2", "@babel/helper-plugin-utils": "^7.24.8", "@babel/helper-validator-option": "^7.24.8", @@ -2148,13 +2148,13 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.25.0", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoped-functions": "^7.24.7", "@babel/plugin-transform-block-scoping": "^7.25.0", - "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-properties": "^7.25.4", "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.25.0", + "@babel/plugin-transform-classes": "^7.25.4", "@babel/plugin-transform-computed-properties": "^7.24.7", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-dotall-regex": "^7.24.7", @@ -2182,7 +2182,7 @@ "@babel/plugin-transform-optional-catch-binding": "^7.24.7", "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.25.4", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-property-literals": "^7.24.7", "@babel/plugin-transform-regenerator": "^7.24.7", @@ -2195,10 +2195,10 @@ "@babel/plugin-transform-unicode-escapes": "^7.24.7", "@babel/plugin-transform-unicode-property-regex": "^7.24.7", "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.4", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.37.1", "semver": "^6.3.1" @@ -2248,9 +2248,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", - "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2284,15 +2284,15 @@ } }, "node_modules/@babel/traverse": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", - "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.4.tgz", + "integrity": "sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", + "@babel/generator": "^7.25.4", + "@babel/parser": "^7.25.4", "@babel/template": "^7.25.0", - "@babel/types": "^7.25.2", + "@babel/types": "^7.25.4", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2309,9 +2309,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", - "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.4.tgz", + "integrity": "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==", "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", @@ -2322,15 +2322,49 @@ } }, "node_modules/@braintree/sanitize-url": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", - "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz", + "integrity": "sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==" }, "node_modules/@bundled-es-modules/pdfjs-dist": { "version": "3.6.172-alpha.1", "resolved": "https://registry.npmjs.org/@bundled-es-modules/pdfjs-dist/-/pdfjs-dist-3.6.172-alpha.1.tgz", "integrity": "sha512-edQXn/5UR1LU1rPoFaZCBk22X8COSO4xctUjakkX6YtZ8BYT9J4EStU8X4bqX7ht2FLC3J21YMQ6RPDmut/l2g==" }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -2519,6 +2553,17 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@eslint-community/regexpp": { "version": "4.11.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", @@ -2528,9 +2573,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", - "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", "dependencies": { "@eslint/object-schema": "^2.1.4", "debug": "^4.3.1", @@ -2630,9 +2675,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", - "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", + "version": "9.9.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.1.tgz", + "integrity": "sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -2690,9 +2735,9 @@ } }, "node_modules/@floating-ui/react": { - "version": "0.26.22", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.22.tgz", - "integrity": "sha512-LNv4azPt8SpT4WW7Kku5JNVjLk2GcS0bGGjFTAgqOONRFo9r/aaGHHPpdiIuQbB1t8shmWyWqTTUDmZ9fcNshg==", + "version": "0.26.23", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.23.tgz", + "integrity": "sha512-9u3i62fV0CFF3nIegiWiRDwOs7OW/KhSUJDNx2MkQM3LbE5zQOY01sL3nelcVBXvX7Ovvo3A49I8ql+20Wg/Hw==", "dependencies": { "@floating-ui/react-dom": "^2.1.1", "@floating-ui/utils": "^0.2.7", @@ -3746,6 +3791,14 @@ "gl-style-validate": "dist/gl-style-validate.mjs" } }, + "node_modules/@mermaid-js/parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.2.0.tgz", + "integrity": "sha512-33dyFdhwsX9n4+E8SRj1ulxwAgwCj9RyCMtoqXD5cDfS9F6y9xmvmjFjHoPaViH4H7I7BXD8yP/XEWig5XrHSQ==", + "dependencies": { + "langium": "3.0.0" + } + }, "node_modules/@mongodb-js/saslprep": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz", @@ -8840,9 +8893,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.17", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.17.tgz", - "integrity": "sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==", + "version": "4.3.18", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.18.tgz", + "integrity": "sha512-2UfJzigyNa8kYTKn7o4hNMPphkxtu4WTJyobK3m4FBpyj7EK5xgtPcOtxLm7Dznk/Qxr0QXn+gQbkg7mCZKdfg==", "dev": true }, "node_modules/@types/color": { @@ -9110,7 +9163,8 @@ "node_modules/@types/d3-scale-chromatic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==", + "dev": true }, "node_modules/@types/d3-selection": { "version": "3.0.10", @@ -9180,23 +9234,14 @@ "integrity": "sha512-zf2GwV/G6TdaLwpLDcGTIkHnXf8JEf/viMux+khqKQKDa8/8BAUtXXZS563GnvJ4Fg0PBLGAaFf2GekEVSZ6GQ==" }, "node_modules/@types/eslint": { - "version": "8.56.11", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.11.tgz", - "integrity": "sha512-sVBpJMf7UPo/wGecYOpk2aQya2VUGeHhe38WG7/mN5FufNSubf5VT9Uh9Uyp8/eLJpu1/tuhJ/qTo4mhSB4V4Q==", + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -9436,14 +9481,6 @@ "@types/geojson": "*" } }, - "node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dependencies": { - "@types/unist": "^2" - } - }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -9468,9 +9505,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.2.tgz", - "integrity": "sha512-nAvM3Ey230/XzxtyDcJ+VjvlzpzoHwLsF7JaDRfoI0ytO0mVheerNmM45CtA0yOILXwXXxOrcUWH3wltX+7PSw==", + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", + "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", "dependencies": { "undici-types": "~6.19.2" } @@ -9838,9 +9875,9 @@ "dev": true }, "node_modules/@types/textfit": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/textfit/-/textfit-2.4.4.tgz", - "integrity": "sha512-AYlNcJ5j/WspQfbHIhoF0Wo63F5+REnX/VPFSH5unUUuwRcr6IoXxZki3vYhG4DRVUQe51AsFYyRxml5u+qaAg==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@types/textfit/-/textfit-2.4.5.tgz", + "integrity": "sha512-C/1i+vGFD7xi1UZPePa6pNdoR0eGFCOe7QrZlTuPGPF+Y4JnFcp9cSJGZko+6tW8GmdDdKt7S9W6sCf3ncvk5g==", "dev": true, "dependencies": { "@types/jquery": "*" @@ -9870,9 +9907,9 @@ "dev": true }, "node_modules/@types/web": { - "version": "0.0.155", - "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.155.tgz", - "integrity": "sha512-rLQhlzDvG+hAgozeVIObiFrkL6X0X8vOYq88O7llQqT41j7spvZKRocMv4EC5ZuweoAMnmlOE/y1pOdV+ZaiRQ==" + "version": "0.0.157", + "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.157.tgz", + "integrity": "sha512-erqzRlWBxaV7qI0g5rIkHRRxQ3kKmqqhokqgnSy3UEQYIl+5qNCU7DwdPaOke3ZHRXmbrjpGgSc4bjM4ItSDnw==" }, "node_modules/@types/webgl-ext": { "version": "0.0.30", @@ -9950,22 +9987,22 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, "node_modules/@types/youtube": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/youtube/-/youtube-0.0.50.tgz", - "integrity": "sha512-d4GpH4uPYp9W07kc487tiq6V/EUHl18vZWFMbQoe4Sk9LXEWzFi/BMf9x7TI4m7/j7gU3KeX8H6M8aPBgykeLw==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@types/youtube/-/youtube-0.1.0.tgz", + "integrity": "sha512-Pg33m3X2mFgdmhtvzOlAfUfgOa3341N3/2JCrVY/mXVxb4hagcqqEG6w4vGCfB64StQNWHSj/T8Eotb1Rko/FQ==", "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.2.0.tgz", - "integrity": "sha512-02tJIs655em7fvt9gps/+4k4OsKULYGtLBPJfOsmOq1+3cdClYiF0+d6mHu6qDnTcg88wJBkcPLpQhq7FyDz0A==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.3.0.tgz", + "integrity": "sha512-FLAIn63G5KH+adZosDYiutqkOkYEx0nvcwNNfJAf+c7Ae/H35qWwTYvPZUKFj5AS+WfHG/WJJfWnDnyNUlp8UA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.2.0", - "@typescript-eslint/type-utils": "8.2.0", - "@typescript-eslint/utils": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0", + "@typescript-eslint/scope-manager": "8.3.0", + "@typescript-eslint/type-utils": "8.3.0", + "@typescript-eslint/utils": "8.3.0", + "@typescript-eslint/visitor-keys": "8.3.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -9989,15 +10026,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.2.0.tgz", - "integrity": "sha512-j3Di+o0lHgPrb7FxL3fdEy6LJ/j2NE8u+AP/5cQ9SKb+JLH6V6UHDqJ+e0hXBkHP1wn1YDFjYCS9LBQsZDlDEg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.3.0.tgz", + "integrity": "sha512-h53RhVyLu6AtpUzVCYLPhZGL5jzTD9fZL+SYf/+hYOx2bDkyQXztXSc4tbvKYHzfMXExMLiL9CWqJmVz6+78IQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.2.0", - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/typescript-estree": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0", + "@typescript-eslint/scope-manager": "8.3.0", + "@typescript-eslint/types": "8.3.0", + "@typescript-eslint/typescript-estree": "8.3.0", + "@typescript-eslint/visitor-keys": "8.3.0", "debug": "^4.3.4" }, "engines": { @@ -10017,13 +10054,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.2.0.tgz", - "integrity": "sha512-OFn80B38yD6WwpoHU2Tz/fTz7CgFqInllBoC3WP+/jLbTb4gGPTy9HBSTsbDWkMdN55XlVU0mMDYAtgvlUspGw==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.3.0.tgz", + "integrity": "sha512-mz2X8WcN2nVu5Hodku+IR8GgCOl4C0G/Z1ruaWN4dgec64kDBabuXyPAr+/RgJtumv8EEkqIzf3X2U5DUKB2eg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0" + "@typescript-eslint/types": "8.3.0", + "@typescript-eslint/visitor-keys": "8.3.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10034,13 +10071,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.2.0.tgz", - "integrity": "sha512-g1CfXGFMQdT5S+0PSO0fvGXUaiSkl73U1n9LTK5aRAFnPlJ8dLKkXr4AaLFvPedW8lVDoMgLLE3JN98ZZfsj0w==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.3.0.tgz", + "integrity": "sha512-wrV6qh//nLbfXZQoj32EXKmwHf4b7L+xXLrP3FZ0GOUU72gSvLjeWUl5J5Ue5IwRxIV1TfF73j/eaBapxx99Lg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.2.0", - "@typescript-eslint/utils": "8.2.0", + "@typescript-eslint/typescript-estree": "8.3.0", + "@typescript-eslint/utils": "8.3.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -10058,9 +10095,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.2.0.tgz", - "integrity": "sha512-6a9QSK396YqmiBKPkJtxsgZZZVjYQ6wQ/TlI0C65z7vInaETuC6HAHD98AGLC8DyIPqHytvNuS8bBVvNLKyqvQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.3.0.tgz", + "integrity": "sha512-y6sSEeK+facMaAyixM36dQ5NVXTnKWunfD1Ft4xraYqxP0lC0POJmIaL/mw72CUMqjY9qfyVfXafMeaUj0noWw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10071,15 +10108,15 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.2.0.tgz", - "integrity": "sha512-kiG4EDUT4dImplOsbh47B1QnNmXSoUqOjWDvCJw/o8LgfD0yr7k2uy54D5Wm0j4t71Ge1NkynGhpWdS0dEIAUA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.3.0.tgz", + "integrity": "sha512-Mq7FTHl0R36EmWlCJWojIC1qn/ZWo2YiWYc1XVtasJ7FIgjo0MVv9rZWXEE7IK2CGrtwe1dVOxWwqXUdNgfRCA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0", + "@typescript-eslint/types": "8.3.0", + "@typescript-eslint/visitor-keys": "8.3.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", @@ -10098,6 +10135,21 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -10111,15 +10163,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.2.0.tgz", - "integrity": "sha512-O46eaYKDlV3TvAVDNcoDzd5N550ckSe8G4phko++OCSC1dYIb9LTc3HDGYdWqWIAT5qDUKphO6sd9RrpIJJPfg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.3.0.tgz", + "integrity": "sha512-F77WwqxIi/qGkIGOGXNBLV7nykwfjLsdauRB/DOFPdv6LTF3BHHkBpq81/b5iMPSF055oO2BiivDJV4ChvNtXA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.2.0", - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/typescript-estree": "8.2.0" + "@typescript-eslint/scope-manager": "8.3.0", + "@typescript-eslint/types": "8.3.0", + "@typescript-eslint/typescript-estree": "8.3.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10133,12 +10185,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.2.0.tgz", - "integrity": "sha512-sbgsPMW9yLvS7IhCi8IpuK1oBmtbWUNP+hBdwl/I9nzqVsszGnNGti5r9dUtF5RLivHUFFIdRvLiTsPhzSyJ3Q==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.3.0.tgz", + "integrity": "sha512-RmZwrTbQ9QveF15m/Cl28n0LXD6ea2CjkhH5rQ55ewz3H24w+AMCJHPVYaZ8/0HoG8Z3cLLFFycRXxeO2tz9FA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/types": "8.3.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -10149,6 +10201,18 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -10986,9 +11050,9 @@ "integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==" }, "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz", + "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -14738,9 +14802,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001651", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", - "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "version": "1.0.30001653", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz", + "integrity": "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==", "funding": [ { "type": "opencollective", @@ -14898,6 +14962,30 @@ "node": ">= 16" } }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, "node_modules/child_process": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", @@ -16755,20 +16843,6 @@ "node": ">=10" } }, - "node_modules/depcheck/node_modules/minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/depcheck/node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -16857,20 +16931,9 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.3.1" } }, "node_modules/dns-packet": { @@ -16885,6 +16948,18 @@ "node": ">=6" } }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", @@ -17039,11 +17114,6 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==" }, - "node_modules/elkjs": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", - "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -17378,15 +17448,15 @@ } }, "node_modules/eslint": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz", - "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==", + "version": "9.9.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.1.tgz", + "integrity": "sha512-dHvhrbfr4xFQ9/dq+jcVneZMyRYLjggWjk6RVsIiHsP8Rz6yZ8LvZ//iU4TrZF+SXWG+JkNF2OyiZRvzgRDqMg==", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.17.1", + "@eslint/config-array": "^0.18.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.9.0", + "@eslint/js": "9.9.1", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", @@ -17477,18 +17547,6 @@ "concat-map": "0.0.1" } }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/eslint-plugin-react/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -17534,11 +17592,11 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -17621,17 +17679,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -17686,17 +17733,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -19202,6 +19238,20 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/global": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", @@ -19278,26 +19328,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/golden-layout": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/golden-layout/-/golden-layout-2.6.0.tgz", @@ -19447,6 +19477,11 @@ "node": ">=14.0.0" } }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==" + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -19569,9 +19604,9 @@ } }, "node_modules/hast-util-from-html": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", - "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.2.tgz", + "integrity": "sha512-HwOHwxdt2zC5KQ/CNoybBntRook2zJvfZE/u5/Ap7aLPe22bDqen7KwGkOqOyzL5zIqKwiYX/OTtE0FWgr6XXA==", "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.1.0", @@ -20899,9 +20934,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dependencies": { "hasown": "^2.0.2" }, @@ -21661,9 +21696,9 @@ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "node_modules/jsdom": { - "version": "24.1.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz", - "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz", + "integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==", "dev": true, "dependencies": { "cssstyle": "^4.0.1", @@ -21960,14 +21995,6 @@ "graceful-fs": "^4.1.9" } }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/kruptein": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/kruptein/-/kruptein-3.0.7.tgz", @@ -22030,6 +22057,21 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/langium": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", + "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", + "dependencies": { + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/launch-editor": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", @@ -22539,6 +22581,17 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", + "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/material-colors": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", @@ -22565,9 +22618,9 @@ } }, "node_modules/mathquill": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/mathquill/-/mathquill-0.10.1.tgz", - "integrity": "sha512-dGtVAUDyKIoS2BPYYgQK7aZAarKQB6oEEWItS5WKmMjYexPOVDm4vYL+I1puYiLvpD4auFUi2z8FeQZP4+FYOA==", + "version": "0.10.1-a", + "resolved": "https://registry.npmjs.org/mathquill/-/mathquill-0.10.1-a.tgz", + "integrity": "sha512-snSAEwAtwdwBFSor+nVBnWWQtTw67kgAgKMyAIxuz4ZPboy0qkWZmd7BL3lfOXp/INihhRlU1PcfaAtDaRhmzA==", "dependencies": { "jquery": "^1.12.3" } @@ -22622,29 +22675,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/mdast-util-gfm": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", @@ -27467,18 +27497,6 @@ } ] }, - "node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -27541,32 +27559,34 @@ } }, "node_modules/mermaid": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.1.tgz", - "integrity": "sha512-Mx45Obds5W1UkW1nv/7dHRsbfMM1aOKA2+Pxs/IGHNonygDHwmng8xTHyS9z4KWVi0rbko8gjiBmuwwXQ7tiNA==", - "dependencies": { - "@braintree/sanitize-url": "^6.0.1", - "@types/d3-scale": "^4.0.3", - "@types/d3-scale-chromatic": "^3.0.0", - "cytoscape": "^3.28.1", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.0.2.tgz", + "integrity": "sha512-KFM1o560odBHvXTTSx47ne/SE4aJKb2GbysHAVdQafIJtB6O3c0K4F+v3nC+zqS6CJhk7sXaagectNrTG+ARDw==", + "dependencies": { + "@braintree/sanitize-url": "^7.0.1", + "@mermaid-js/parser": "^0.2.0", + "cytoscape": "^3.29.2", "cytoscape-cose-bilkent": "^4.1.0", - "d3": "^7.4.0", + "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.10", - "dayjs": "^1.11.7", - "dompurify": "^3.0.5", - "elkjs": "^0.9.0", + "dayjs": "^1.11.10", + "dompurify": "^3.0.11", "katex": "^0.16.9", - "khroma": "^2.0.0", + "khroma": "^2.1.0", "lodash-es": "^4.17.21", - "mdast-util-from-markdown": "^1.3.0", - "non-layered-tidy-tree-layout": "^2.0.2", - "stylis": "^4.1.3", + "marked": "^13.0.2", + "roughjs": "^4.6.6", + "stylis": "^4.3.1", "ts-dedent": "^2.2.0", - "uuid": "^9.0.0", - "web-worker": "^1.2.0" + "uuid": "^9.0.1" } }, + "node_modules/mermaid/node_modules/stylis": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", + "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" + }, "node_modules/mermaid/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -27592,73 +27612,6 @@ "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz", "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==" }, - "node_modules/micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, "node_modules/micromark-extension-gfm": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", @@ -28595,364 +28548,10 @@ } ] }, - "node_modules/micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -29025,14 +28624,14 @@ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -29361,9 +28960,9 @@ } }, "node_modules/mongoose": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.3.tgz", - "integrity": "sha512-OubSDbsAclDFGHjV82MsKyIGQWFc42Ot1l+0dhRS6U9xODM7rm/ES/WpOQd8Ds9j0Mx8QzxZtrSCnBh6o9wUqw==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.4.tgz", + "integrity": "sha512-nG3eehhWf9l1q80WuHvp5DV+4xDNFpDWLE5ZgcFD5tslUV2USJ56ogun8gaZ62MKAocJnoStjAdno08b8U57hg==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", @@ -29455,14 +29054,6 @@ "resolved": "https://registry.npmjs.org/mr-parser/-/mr-parser-0.2.1.tgz", "integrity": "sha512-hug+mpbSSKnH13rFqy3zm+XiG+QTStiDAgMTHK355TIstQE0qBkBtSJsa5YHP94AuarVX9b/4dcebdTRZ9YiEw==" }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -29768,11 +29359,6 @@ "node": ">=10" } }, - "node_modules/non-layered-tidy-tree-layout": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", - "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" - }, "node_modules/nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -32482,9 +32068,9 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.45.tgz", - "integrity": "sha512-VZxPKNNhjKmaC1SUYowuXSRSMGyQGmQjvvA1xE4QZ0xce2kLtEhPDS+kqpCPBZYgqblCLQ2DAjSzmgCM5auvhA==", + "version": "18.19.46", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.46.tgz", + "integrity": "sha512-vnRgMS7W6cKa1/0G3/DTtQYpVrZ8c0Xm6UkLaVFrb9jtcVC3okokW09Ki1Qdrj9ISokszD69nY4WDLRlvHlhAA==", "dependencies": { "undici-types": "~5.26.4" } @@ -32830,6 +32416,11 @@ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -33182,6 +32773,20 @@ "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz", "integrity": "sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==" }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, "node_modules/polygon-clipping": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/polygon-clipping/-/polygon-clipping-0.15.7.tgz", @@ -33495,9 +33100,9 @@ } }, "node_modules/prosemirror-view": { - "version": "1.33.11", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.11.tgz", - "integrity": "sha512-K0z9oMf6EI2ZifS9yW8PUPjEw2o1ZoFAaNzvcuyfcjIzsU6pJMo3tk9r26MyzEsuGHXZwmKPEmrjgFd78biTGA==", + "version": "1.34.1", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.34.1.tgz", + "integrity": "sha512-KS2xmqrAM09h3SLu1S2pNO/ZoIP38qkTJ6KFd7+BeSfmX/ek0n5yOfGuiTZjFNTC8GOsEIUa1tHxt+2FMu3yWQ==", "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -35759,6 +35364,17 @@ "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==" }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, "node_modules/rrweb-cssom": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", @@ -35804,17 +35420,6 @@ "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dependencies": { - "mri": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/safe-array-concat": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", @@ -36504,15 +36109,6 @@ "resolved": "https://registry.npmjs.org/skmeans/-/skmeans-0.9.7.tgz", "integrity": "sha512-hNj1/oZ7ygsfmPZ7ZfN5MUBRoGg1gtpnImuJBgLO0ljQ67DtJuiQaiYdS4lUA6s0KCwnPhGivtC/WRwIZLkHyg==" }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/socket.io": { "version": "4.7.5", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", @@ -36906,9 +36502,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/streamx": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", - "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.19.0.tgz", + "integrity": "sha512-5z6CNR4gtkPbwlxyEqoDGDmWIzoNJqCBt4Eac1ICP9YaIT08ct712cFj0u1rx4F8luAuL+3Qc+RFIdI4OX00kg==", "dependencies": { "fast-fifo": "^1.3.2", "queue-tick": "^1.0.1", @@ -38080,9 +37676,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" }, "node_modules/tslint": { "version": "6.1.3", @@ -38479,14 +38075,14 @@ "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==" }, "node_modules/typescript-eslint": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.2.0.tgz", - "integrity": "sha512-DmnqaPcML0xYwUzgNbM1XaKXpEb7BShYf2P1tkUmmcl8hyeG7Pj08Er7R9bNy6AufabywzJcOybQAtnD/c9DGw==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.3.0.tgz", + "integrity": "sha512-EvWjwWLwwKDIJuBjk2I6UkV8KEQcwZ0VM10nR1rIunRDIP67QJTZAHBXTX0HW/oI1H10YESF8yWie8fRQxjvFA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.2.0", - "@typescript-eslint/parser": "8.2.0", - "@typescript-eslint/utils": "8.2.0" + "@typescript-eslint/eslint-plugin": "8.3.0", + "@typescript-eslint/parser": "8.3.0", + "@typescript-eslint/utils": "8.3.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -38738,18 +38334,6 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, - "node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-visit": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", @@ -39041,23 +38625,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/uvu": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", - "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", - "dependencies": { - "dequal": "^2.0.0", - "diff": "^5.0.0", - "kleur": "^4.0.3", - "sade": "^1.7.3" - }, - "bin": { - "uvu": "bin.js" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -39216,6 +38783,49 @@ "node": ">=0.10.0" } }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, "node_modules/vt-pbf": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", @@ -39299,11 +38909,6 @@ "node": ">= 8" } }, - "node_modules/web-worker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", - "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" - }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -39313,11 +38918,10 @@ } }, "node_modules/webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", @@ -39326,7 +38930,7 @@ "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -39430,9 +39034,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.1.tgz", - "integrity": "sha512-/t6KpZw/bnmCR0VKILjJT05mWecbf1aIM2VxCJUvBbg0iXqaQJFxbJ4PCrsY4iBH7PGwnccm4BYyoP1G+lGfAA==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", "dependencies": { "colorette": "^2.0.10", "memfs": "^4.6.0", diff --git a/package.json b/package.json index 658ba7ab5..81ee9972a 100644 --- a/package.json +++ b/package.json @@ -69,13 +69,13 @@ "@types/valid-url": "^1.0.7", "@types/webpack": "^5.28.5", "@types/webscopeio__react-textarea-autocomplete": "^4.7.5", - "@types/youtube": "0.0.50", + "@types/youtube": "^0.1.0", "chai": "^5.0.0", "cross-env": "^7.0.3", "eslint": "^9.9.0", "eslint-plugin-react": "^7.34.1", "globals": "^15.1.0", - "jsdom": "^24.0.0", + "jsdom": "^25.0.0", "mocha": "^10.2.0", "prettier": "^3.1.0", "scss-loader": "0.0.1", @@ -129,7 +129,7 @@ "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/textfit": "^2.4.4", - "@types/web": "^0.0.155", + "@types/web": "^0.0.157", "@types/webpack-hot-middleware": "^2.25.9", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", @@ -223,7 +223,7 @@ "mathquill": "^0.10.1-a", "md5-file": "^5.0.0", "memorystream": "^0.3.1", - "mermaid": "^10.9.1", + "mermaid": "^11.0.2", "mobile-detect": "^1.4.5", "mobx": "^6.12.0", "mobx-react": "^9.1.0", -- cgit v1.2.3-70-g09d2 From f0d9731e1c43ee13114d42db8c4e27c94bbbf3c0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 22:25:58 -0400 Subject: made face doc labels editable --- .../views/collections/collectionFreeForm/FaceCollectionBox.scss | 6 ++++++ .../views/collections/collectionFreeForm/FaceCollectionBox.tsx | 4 +++- src/client/views/search/FaceRecognitionHandler.tsx | 9 +++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss index a72efc948..0a001d84c 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss @@ -11,6 +11,12 @@ color: white; font-size: 24px; text-align: center; + .face-document-name { + text-align: center; + background: transparent; + width: 80%; + border: transparent; + } } .face-collection-buttons { diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 662436ddc..7e47292e5 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -149,7 +149,9 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() {
(this._headerRef = r))}> -

{FaceRecognitionHandler.UniqueFaceLabel(this.Document)}

+

+ FaceRecognitionHandler.SetUniqueFaceLabel(this.Document, e.currentTarget.value)} value={FaceRecognitionHandler.UniqueFaceLabel(this.Document)} /> +

StrCast(faceDoc[DocData].face_label); + public static UniqueFaceLabel = (faceDoc: Doc) => StrCast(faceDoc[DocData].face); + + public static SetUniqueFaceLabel = (faceDoc: Doc, value: string) => (faceDoc[DocData].face = value); /** * Returns all the face descriptors associated with a unique face Doc * @param faceDoc unique face Doc @@ -186,8 +188,7 @@ export class FaceRecognitionHandler { _height: 100, }); const uface = uniqueFaceDoc[DocData]; - uface.face = ''; // just to make prettyprinting look better - uface.face_label = `Face${faceDocNum}`; + uface.face = `Face${faceDocNum}`; uface.face_images = new List(); uface.face_descriptors = new List>(); Doc.SetContainer(uniqueFaceDoc, Doc.MyFaceCollection); -- cgit v1.2.3-70-g09d2 From cf38fc81b69abb084938c8f45eaf5d94caacb3a3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 22:49:10 -0400 Subject: added face rectangle annotations for faces in images --- src/client/views/search/FaceRecognitionHandler.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index dee0ab99b..4e500d24e 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -243,12 +243,17 @@ export class FaceRecognitionHandler { FaceRecognitionHandler.loadImage(imgUrl).then( // load image and analyze faces img => faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors() .then(imgDocFaceDescriptions => { // For each face detected, find a match. + const annos = [] as Doc[]; + const scale = NumCast(imgDoc.data_nativeWidth) / img.width; for (const fd of imgDocFaceDescriptions) { const faceDescriptor = new List(Array.from(fd.descriptor)); + annos.push(Docs.Create.FreeformDocument([], {backgroundColor: "#55555555", x: fd.alignedRect.box.left*scale, y: fd.alignedRect.box.top*scale, _width: fd.alignedRect.box.width*scale, _height: fd.alignedRect.box.height*scale})) FaceRecognitionHandler.ImageDocAddFaceDescriptor(imgDoc, faceDescriptor); // add face descriptor to image's list of descriptors const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(activeDashboard); FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); // add image/faceDescriptor to matched unique face - } // + } + + imgDoc[DocData].data_annotations = new List(annos); return imgDocFaceDescriptions; }) ); -- cgit v1.2.3-70-g09d2 From ef5a8b8261052c3079f267d1d8d0804a495e3e3d Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 23:29:47 -0400 Subject: fixed naming of face annotations --- src/client/documents/Documents.ts | 1 + src/client/views/search/FaceRecognitionHandler.tsx | 56 ++++++++++++++-------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ac271526f..235f54fe8 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -363,6 +363,7 @@ export class DocumentOptions { data?: FieldType; data_useCors?: BOOLt = new BoolInfo('whether CORS protocol should be used for web page'); _face_showImages?: BOOLt = new BoolInfo('whether to show images in uniqe face Doc'); + face?: DOCt = new DocInfo('face document'); columnHeaders?: List; // headers for stacking views schemaHeaders?: List; // headers for schema view dockingConfig?: STRt = new StrInfo('configuration of golden layout windows (applies only if doc is rendered as a CollectionDockingView)', false); diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 4e500d24e..4906ba4b6 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -9,6 +9,7 @@ import { ImageField } from '../../../fields/URLField'; import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; +import { ComputedField } from '../../../fields/ScriptField'; /** * A singleton class that handles face recognition and manages face Doc collections for each face found. @@ -176,7 +177,7 @@ export class FaceRecognitionHandler { dashboard[DocData].myUniqueFaces_count = faceDocNum; // TODO: improve to a better name const uniqueFaceDoc = Docs.Create.UniqeFaceDocument({ - title: `Face ${faceDocNum}`, + title: ComputedField.MakeFunction('this.face') as unknown as string, _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true, @@ -237,27 +238,44 @@ export class FaceRecognitionHandler { setTimeout(() => this.classifyFacesInImage(imgDoc), 1000); } else { const imgUrl = ImageCast(imgDoc[Doc.LayoutFieldKey(imgDoc)]); - if (imgUrl && !DocListCast(Doc.MyFaceCollection.examinedFaceDocs).includes(imgDoc[DocData])) { // only examine Docs that have an image and that haven't already been examined. + if (imgUrl && !DocListCast(Doc.MyFaceCollection.examinedFaceDocs).includes(imgDoc[DocData])) { + // only examine Docs that have an image and that haven't already been examined. Doc.AddDocToList(Doc.MyFaceCollection, 'examinedFaceDocs', imgDoc[DocData]); FaceRecognitionHandler.initImageDocFaceDescriptors(imgDoc); - FaceRecognitionHandler.loadImage(imgUrl).then( // load image and analyze faces - img => faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors() - .then(imgDocFaceDescriptions => { // For each face detected, find a match. - const annos = [] as Doc[]; - const scale = NumCast(imgDoc.data_nativeWidth) / img.width; - for (const fd of imgDocFaceDescriptions) { - const faceDescriptor = new List(Array.from(fd.descriptor)); - annos.push(Docs.Create.FreeformDocument([], {backgroundColor: "#55555555", x: fd.alignedRect.box.left*scale, y: fd.alignedRect.box.top*scale, _width: fd.alignedRect.box.width*scale, _height: fd.alignedRect.box.height*scale})) - FaceRecognitionHandler.ImageDocAddFaceDescriptor(imgDoc, faceDescriptor); // add face descriptor to image's list of descriptors - const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(activeDashboard); - FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); // add image/faceDescriptor to matched unique face - } + FaceRecognitionHandler.loadImage(imgUrl).then( + // load image and analyze faces + img => faceapi + .detectAllFaces(img) + .withFaceLandmarks() + .withFaceDescriptors() + .then(imgDocFaceDescriptions => { // For each face detected, find a match. + const annos = [] as Doc[]; + const scale = NumCast(imgDoc.data_nativeWidth) / img.width; + imgDocFaceDescriptions.forEach((fd, i) => { + const faceDescriptor = new List(Array.from(fd.descriptor)); + FaceRecognitionHandler.ImageDocAddFaceDescriptor(imgDoc, faceDescriptor); // add face descriptor to image's list of descriptors + const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(activeDashboard); + FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); // add image/faceDescriptor to matched unique face + annos.push( + Docs.Create.FreeformDocument([], { + title: ComputedField.MakeFunction(`this.face.face`) as unknown as string, // + annotationOn: imgDoc, + face: matchedUniqueFace, + backgroundColor: '#55555555', + x: fd.alignedRect.box.left * scale, + y: fd.alignedRect.box.top * scale, + _width: fd.alignedRect.box.width * scale, + _height: fd.alignedRect.box.height * scale, + }) + ); + Doc.SetContainer(annos.lastElement(), imgDoc[DocData]); + }); - imgDoc[DocData].data_annotations = new List(annos); - return imgDocFaceDescriptions; - }) - ); - } // prettier-ignore + imgDoc[DocData].data_annotations = new List(annos); + return imgDocFaceDescriptions; + }) + ); // prettier-ignore + } } }; } -- cgit v1.2.3-70-g09d2 From 5180a22ad70cb79ff2167a3aa0a63962ec6b0319 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 26 Aug 2024 23:49:35 -0400 Subject: made face annotation titles editable to edit face doc. --- src/client/views/search/FaceRecognitionHandler.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 4906ba4b6..0cee7184c 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -177,7 +177,7 @@ export class FaceRecognitionHandler { dashboard[DocData].myUniqueFaces_count = faceDocNum; // TODO: improve to a better name const uniqueFaceDoc = Docs.Create.UniqeFaceDocument({ - title: ComputedField.MakeFunction('this.face') as unknown as string, + title: ComputedField.MakeFunction('this.face', undefined, undefined, 'this.face = value') as unknown as string, _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true, @@ -258,9 +258,9 @@ export class FaceRecognitionHandler { FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); // add image/faceDescriptor to matched unique face annos.push( Docs.Create.FreeformDocument([], { - title: ComputedField.MakeFunction(`this.face.face`) as unknown as string, // + title: ComputedField.MakeFunction(`this.face.face`, undefined, undefined, 'this.face.face = value') as unknown as string, // annotationOn: imgDoc, - face: matchedUniqueFace, + face: matchedUniqueFace[DocData], backgroundColor: '#55555555', x: fd.alignedRect.box.left * scale, y: fd.alignedRect.box.top * scale, -- cgit v1.2.3-70-g09d2 From 248f9fdced99a36c28fb34f39b78e1267ec02486 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 27 Aug 2024 08:23:04 -0400 Subject: allow non-faces to be added to face collections --- .../views/collections/collectionFreeForm/FaceCollectionBox.tsx | 6 ++---- src/client/views/search/FaceRecognitionHandler.tsx | 10 ++++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 7e47292e5..ea1c22962 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -102,10 +102,8 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { { dist: 1, face_match: undefined as Opt> } ); - // assign the face in the image that's closest to the face collection to be the face that's assigned to the collection - if (face_match) { - FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, face_match, this.Document); - } + // assign the face in the image that's closest to the face collection's face + FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, face_match, this.Document); } }); e.stopPropagation(); diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 0cee7184c..021802061 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -1,6 +1,6 @@ import * as faceapi from 'face-api.js'; import { FaceMatcher } from 'face-api.js'; -import { Doc, DocListCast } from '../../../fields/Doc'; +import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; @@ -133,10 +133,12 @@ export class FaceRecognitionHandler { * @param faceDescriptor - the face descriptor for the face in the image to add * @param faceDoc - unique face Doc */ - public static UniqueFaceAddFaceImage = (img: Doc, faceDescriptor: List, faceDoc: Doc) => { + public static UniqueFaceAddFaceImage = (img: Doc, faceDescriptor: Opt>, faceDoc: Doc) => { Doc.AddDocToList(faceDoc, 'face_images', img); - Cast(faceDoc.face_descriptors, listSpec('number'), null).push(faceDescriptor as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that - Doc.AddDocToList(img[DocData], FaceRecognitionHandler.ImageDocFaceField(img), faceDoc); + if (faceDescriptor) { + Cast(faceDoc.face_descriptors, listSpec('number'), null).push(faceDescriptor as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that + Doc.AddDocToList(img[DocData], FaceRecognitionHandler.ImageDocFaceField(img), faceDoc); + } }; /** -- cgit v1.2.3-70-g09d2 From cf10fbb80a022ddb141e41203b9135b6f1ed9527 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 27 Aug 2024 13:49:07 -0400 Subject: uniying image labels => tags. made face tags distinguishable from other tags - and drag off to place face collection. --- src/client/documents/Documents.ts | 1 + src/client/views/TagsView.scss | 4 + src/client/views/TagsView.tsx | 61 +++++++---- .../collectionFreeForm/FaceCollectionBox.tsx | 33 ++++-- .../collectionFreeForm/ImageLabelBox.tsx | 10 +- src/client/views/search/FaceRecognitionHandler.tsx | 112 +++++++-------------- src/fields/Doc.ts | 6 +- 7 files changed, 117 insertions(+), 110 deletions(-) diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 235f54fe8..af181b031 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -364,6 +364,7 @@ export class DocumentOptions { data_useCors?: BOOLt = new BoolInfo('whether CORS protocol should be used for web page'); _face_showImages?: BOOLt = new BoolInfo('whether to show images in uniqe face Doc'); face?: DOCt = new DocInfo('face document'); + faceDescriptor?: List; columnHeaders?: List; // headers for stacking views schemaHeaders?: List; // headers for schema view dockingConfig?: STRt = new StrInfo('configuration of golden layout windows (applies only if doc is rendered as a CollectionDockingView)', false); diff --git a/src/client/views/TagsView.scss b/src/client/views/TagsView.scss index f7365a51b..24f9e86bc 100644 --- a/src/client/views/TagsView.scss +++ b/src/client/views/TagsView.scss @@ -24,6 +24,10 @@ align-items: center; } +.faceItem { + background-color: lightGreen; +} + .tagsView-suggestions-box { display: flex; flex-wrap: wrap; diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index 82c85ddf0..da1add55b 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -6,10 +6,10 @@ import React from 'react'; import ResizeObserver from 'resize-observer-polyfill'; import { returnFalse, setupMoveUpEvents } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; -import { Doc, DocListCast, Opt, StrListCast } from '../../fields/Doc'; +import { Doc, DocListCast, Field, Opt, StrListCast } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; -import { NumCast, StrCast } from '../../fields/Types'; +import { DocCast, NumCast, StrCast } from '../../fields/Types'; import { DocumentType } from '../documents/DocumentTypes'; import { DragManager } from '../util/DragManager'; import { SnappingManager } from '../util/SnappingManager'; @@ -17,6 +17,7 @@ import { undoable } from '../util/UndoManager'; import { ObservableReactComponent } from './ObservableReactComponent'; import './TagsView.scss'; import { DocumentView } from './nodes/DocumentView'; +import { FaceRecognitionHandler } from './search/FaceRecognitionHandler'; /** * The TagsView is a metadata input/display panel shown at the bottom of a DocumentView in a freeform collection. @@ -158,6 +159,10 @@ export class TagItem extends ObservableReactComponent { * @returns */ createTagCollection = () => { + if (!this._props.tagDoc) { + const face = FaceRecognitionHandler.FindUniqueFaceByName(this._props.tag); + return face ? Doc.MakeEmbedding(face) : undefined; + } // Get the documents that contain the tag. const newEmbeddings = TagItem.allDocsWithTag(this._props.tag).map(doc => Doc.MakeEmbedding(doc)); @@ -188,9 +193,13 @@ export class TagItem extends ObservableReactComponent { this, e, () => { - const dragData = new DragManager.DocumentDragData([this.createTagCollection()]); - DragManager.StartDocumentDrag([this._ref.current!], dragData, e.clientX, e.clientY, {}); - return true; + const dragCollection = this.createTagCollection(); + if (dragCollection) { + const dragData = new DragManager.DocumentDragData([dragCollection]); + DragManager.StartDocumentDrag([this._ref.current!], dragData, e.clientX, e.clientY, {}); + return true; + } + return false; }, returnFalse, emptyFunction @@ -199,20 +208,20 @@ export class TagItem extends ObservableReactComponent { }; render() { - setTimeout(() => TagItem.addTagToDoc(this._props.doc, this._props.tag)); // bcz: hack to make sure that Docs are added to their tag Doc collection since metadata can get set anywhere without a guard triggering an add to the collection + this._props.tagDoc && setTimeout(() => TagItem.addTagToDoc(this._props.doc, this._props.tag)); // bcz: hack to make sure that Docs are added to their tag Doc collection since metadata can get set anywhere without a guard triggering an add to the collection const tag = this._props.tag.replace(/^#/, ''); const metadata = tag.startsWith('@') ? tag.replace(/^@/, '') : ''; return ( -
+
{metadata ? ( {tag}  - {this._props.doc[metadata] as string} + {Field.toString(this._props.doc[metadata])} ) : ( tag )} - {this.props.showRemoveUI && ( + {this.props.showRemoveUI && this._props.tagDoc && ( TagItem.removeTagFromDoc(this._props.doc, this._props.tag, this._props.tagDoc), `remove tag ${this._props.tag}`)} @@ -234,12 +243,9 @@ interface TagViewProps { */ @observer export class TagsView extends ObservableReactComponent { - private _ref: React.RefObject; - constructor(props: any) { super(props); makeObservable(this); - this._ref = React.createRef(); } @observable _currentInput = ''; @@ -268,18 +274,26 @@ export class TagsView extends ObservableReactComponent { * just the tag. * @param tag tag string to add */ - submitTag = undoable((tag: string) => { - const submittedLabel = tag.trim(); - submittedLabel && TagItem.addTagToDoc(this._props.View.Document, '#' + submittedLabel.replace(/^#/, '')); - this._currentInput = ''; // Clear the input box - }, 'added doc label'); + submitTag = undoable( + action((tag: string) => { + const submittedLabel = tag.trim(); + submittedLabel && TagItem.addTagToDoc(this._props.View.Document, '#' + submittedLabel.replace(/^#/, '')); + this._currentInput = ''; // Clear the input box + }), + 'added doc label' + ); /** * When 'showTags' is set on a Doc, this displays a wrapping panel of tagItemViews corresponding to all the tags set on the Doc). * When the dropdown is clicked, this will toggle an extended UI that allows additional tags to be added/removed. */ render() { - const tagsList = StrListCast(this._props.View.dataDoc.tags); + const tagsList = new Set(StrListCast(this._props.View.dataDoc.tags)); + const facesList = new Set( + DocListCast(this._props.View.dataDoc[Doc.LayoutFieldKey(this._props.View.Document) + '_annotations']) + .filter(d => d.face) + .map(doc => StrCast(DocCast(doc.face)?.title)) + ); return !this._props.View.Document.showTags ? null : (
{ }}>
- {!tagsList.length ? null : ( // + {!tagsList.size ? null : ( // this.setToEditing(!this._isEditing)} icon={} /> )} - {tagsList.map(tag => ( - + {Array.from(tagsList).map((tag, i) => ( + + ))} + {Array.from(facesList).map((tag, i) => ( + ))}
{this.isEditing ? ( @@ -330,7 +347,7 @@ export class TagsView extends ObservableReactComponent { color={SnappingManager.userVariantColor} tooltip="Add existing tag" onClick={() => this.submitTag(tag)} - key={i} + key={tag} /> ); })} diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index ea1c22962..c62303dc0 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -9,8 +9,9 @@ import React from 'react'; import { DivHeight, lightOrDark, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; import { Doc, Opt } from '../../../../fields/Doc'; +import { DocData } from '../../../../fields/DocSymbols'; import { List } from '../../../../fields/List'; -import { ImageCast, NumCast, StrCast } from '../../../../fields/Types'; +import { DocCast, ImageCast, NumCast, StrCast } from '../../../../fields/Types'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; @@ -87,23 +88,27 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { ?.filter(doc => doc.type === DocumentType.IMG) .forEach(imgDoc => { // If the current Face Document has no faces, and the doc has more than one face descriptor, don't let the user add the document first. Or should we just use the first face ? - if (FaceRecognitionHandler.UniqueFaceDescriptors(this.Document).length === 0 && FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).length > 1) { + if (FaceRecognitionHandler.UniqueFaceDescriptors(this.Document).length === 0 && FaceRecognitionHandler.ImageDocFaceAnnos(imgDoc).length > 1) { alert('Cannot add a document with multiple faces as the first item!'); } else { // Loop through the documents' face descriptors and choose the face in the iage with the smallest distance (most similar to the face colleciton) const faceDescriptorsAsFloat32Array = FaceRecognitionHandler.UniqueFaceDescriptors(this.Document).map(fd => new Float32Array(Array.from(fd))); const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(this.Document), faceDescriptorsAsFloat32Array); const faceMatcher = new FaceMatcher([labeledFaceDescriptor], 1); - const { face_match } = FaceRecognitionHandler.ImageDocFaceDescriptors(imgDoc).reduce( - (prev, face) => { - const match = faceMatcher.matchDescriptor(new Float32Array(Array.from(face))); - return match.distance < prev.dist ? { dist: match.distance, face_match: face } : prev; + const { faceAnno } = FaceRecognitionHandler.ImageDocFaceAnnos(imgDoc).reduce( + (prev, faceAnno) => { + const match = faceMatcher.matchDescriptor(new Float32Array(Array.from(faceAnno.faceDescriptor as List))); + return match.distance < prev.dist ? { dist: match.distance, faceAnno } : prev; }, - { dist: 1, face_match: undefined as Opt> } + { dist: 1, faceAnno: undefined as Opt } ); // assign the face in the image that's closest to the face collection's face - FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, face_match, this.Document); + if (faceAnno) { + FaceRecognitionHandler.UniqueFaceRemoveFaceImage(faceAnno, DocCast(faceAnno.face)); + FaceRecognitionHandler.UniqueFaceAddFaceImage(faceAnno, this.Document); + faceAnno.face = this.Document; + } } }); e.stopPropagation(); @@ -224,7 +229,15 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { } moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => !!(this._props.removeDocument?.(doc) && addDocument?.(doc)); - + addDocument = (doc: Doc | Doc[], annotationKey?: string) => { + const uniqueFaceDoc = doc instanceof Doc ? doc : doc[0]; + const added = uniqueFaceDoc.type === DocumentType.UFACE; + if (added) { + Doc.SetContainer(uniqueFaceDoc, Doc.MyFaceCollection); + Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'myUniqueFaces', uniqueFaceDoc); + } + return added; + }; /** * this changes style provider requests that target the dashboard to requests that target the face collection box which is what's actually being rendered. * This is needed, for instance, to get the default background color from the face collection, not the dashboard. @@ -233,6 +246,7 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { if (doc === Doc.ActiveDashboard) return this._props.styleProvider?.(this.Document, this._props, property); return this._props.styleProvider?.(doc, this._props, property); }; + render() { return !Doc.ActiveDashboard ? null : (
@@ -245,6 +259,7 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { Document={Doc.ActiveDashboard} fieldKey="myUniqueFaces" moveDocument={this.moveDocument} + addDocument={this.addDocument} isContentActive={returnTrue} isAnyChildContentActive={returnTrue} childHideDecorations={true} diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index 6eb3eb784..5d3154e3c 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -51,7 +51,7 @@ export class ImageLabelBoxData { label = label.toUpperCase().trim(); if (label.length > 0) { if (!this._labelGroups.includes(label)) { - this._labelGroups = [...this._labelGroups, label]; + this._labelGroups = [...this._labelGroups, label.startsWith('#') ? label : '#' + label]; } } }; @@ -178,8 +178,12 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { const labels = imageInfo.labels.split('\n'); labels.forEach(label => { - label = label.replace(/^\d+\.\s*|-|f\*/, '').trim(); - console.log(label); + label = + '#' + + label + .replace(/^\d+\.\s*|-|f\*/, '') + .replace(/^#/, '') + .trim(); imageInfo.doc[DocData][label] = true; (imageInfo.doc[DocData].tags as List).push(label); }); diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 021802061..4c10307e6 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -1,15 +1,14 @@ import * as faceapi from 'face-api.js'; import { FaceMatcher } from 'face-api.js'; -import { Doc, DocListCast, Opt } from '../../../fields/Doc'; +import { Doc, DocListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; -import { listSpec } from '../../../fields/Schema'; -import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; +import { ComputedField } from '../../../fields/ScriptField'; +import { DocCast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; -import { ComputedField } from '../../../fields/ScriptField'; /** * A singleton class that handles face recognition and manages face Doc collections for each face found. @@ -18,16 +17,17 @@ import { ComputedField } from '../../../fields/ScriptField'; * as a face collection Doc). If the face matches a face collection Doc, then it will be added to that * collection along with the numerical representation of the face, its face descriptor. * - * Image Doc's that are added to one or more face collection Docs will be given these metadata fields: - * _faceDescriptors - list of all the numerical face representations found in the image. - * _faces - list of unique face Docs corresponding to recognized faces in the image. + * Image Doc's that are added to one or more face collection Docs will be given an annotation rectangle that + * highlights where the face is, and the annotation will have these fields: + * faceDescriptor - the numerical face representations found in the image. + * face - the unique face Docs corresponding to recognized face in the image. + * annotationOn - the image where the face was found * * unique face Doc's are created for each person identified and are stored in the Dashboard's myUniqueFaces field * * Each unique face Doc represents a unique face and collects all matching face images for that person. It has these fields: * face - a string label for the person that was recognized (TODO: currently it's just a 'face#') - * face_descriptors - a list of all the face descriptors for different images of the person - * face_docList - a list of all image Docs that contain a face for the person + * face_annos - a list of face annotations, where each anno has */ export class FaceRecognitionHandler { static _instance: FaceRecognitionHandler; @@ -54,42 +54,12 @@ export class FaceRecognitionHandler { }); }; - /** - * return the metadata field name where unique face Docs are stored - * @param imgDoc image with faces - * @returns name of field - */ - private static ImageDocFaceField = (imgDoc: Doc) => `${Doc.LayoutFieldKey(imgDoc)}_faces`; - /** * Returns an array of faceDocs for each face recognized in the image * @param imgDoc image with faces * @returns faceDoc array */ - private static ImageDocFaces = (imgDoc: Doc) => DocListCast(imgDoc[`${Doc.LayoutFieldKey(imgDoc)}_faces`]); - - /** - * initializes an image with an empty list of face descriptors - * @param imgDoc image to initialize - */ - private static initImageDocFaceDescriptors = (imgDoc: Doc) => { - imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_faceDescriptors`] = new List>(); - }; - /** - * returns the face descriptors for each face found on an image Doc - * @param imgDoc - * @returns list of face descriptors - */ - public static ImageDocFaceDescriptors = (imgDoc: Doc) => imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_faceDescriptors`] as List>; - - /** - * Adds a face descriptor for a face found in an image - * @param imgDoc image Doc with face - * @param faceDescriptor descriptor of a face - */ - public static ImageDocAddFaceDescriptor = (imgDoc: Doc, faceDescriptor: List) => { - Cast(imgDoc[DocData][`${Doc.LayoutFieldKey(imgDoc)}_faceDescriptors`], listSpec('number'), null).push(faceDescriptor as unknown as number); - }; + public static ImageDocFaceAnnos = (imgDoc: Doc) => DocListCast(imgDoc[`${Doc.LayoutFieldKey(imgDoc)}_annotations`]).filter(doc => doc.face); /** * returns a list of all face collection Docs on the current dashboard @@ -97,6 +67,13 @@ export class FaceRecognitionHandler { */ public static UniqueFaces = () => DocListCast(Doc.ActiveDashboard?.[DocData].myUniqueFaces); + /** + * Find a unique face from its name + * @param name name of unique face + * @returns unique face or undefined + */ + public static FindUniqueFaceByName = (name: string) => FaceRecognitionHandler.UniqueFaces().find(faceDoc => faceDoc.title === name); + /** * Removes a unique face from the set of recognized unique faces * @param faceDoc unique face Doc @@ -117,28 +94,23 @@ export class FaceRecognitionHandler { * @param faceDoc unique face Doc * @returns face descriptors */ - public static UniqueFaceDescriptors = (faceDoc: Doc) => faceDoc[DocData].face_descriptors as List>; + public static UniqueFaceDescriptors = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_annos).map(face => face.faceDescriptor as List); /** * Returns a list of all face image Docs associated with a unique face Doc * @param faceDoc unique face Doc * @returns image Docs */ - public static UniqueFaceImages = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_images); + public static UniqueFaceImages = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_annos).map(face => DocCast(face.annotationOn)); /** * Adds a face image to a unique face Doc, adds the unique face Doc to the images list of reognized faces, * and updates the unique face's set of face image descriptors * @param img - image with faces to add to a face collection Doc - * @param faceDescriptor - the face descriptor for the face in the image to add - * @param faceDoc - unique face Doc + * @param faceAnno - a face annotation */ - public static UniqueFaceAddFaceImage = (img: Doc, faceDescriptor: Opt>, faceDoc: Doc) => { - Doc.AddDocToList(faceDoc, 'face_images', img); - if (faceDescriptor) { - Cast(faceDoc.face_descriptors, listSpec('number'), null).push(faceDescriptor as unknown as number); // items are lists of numbers, not numbers, but type system can't handle that - Doc.AddDocToList(img[DocData], FaceRecognitionHandler.ImageDocFaceField(img), faceDoc); - } + public static UniqueFaceAddFaceImage = (faceAnno: Doc, faceDoc: Doc) => { + Doc.AddDocToList(faceDoc, 'face_annos', faceAnno); }; /** @@ -146,11 +118,9 @@ export class FaceRecognitionHandler { * @param img - image with faces to remove * @param faceDoc - unique face Doc */ - public static UniqueFaceRemoveFaceImage = (img: Doc, faceDoc: Doc) => { - Doc.RemoveDocFromList(faceDoc[DocData], 'face_images', img); - const descriptorsEqual = (a: List, b: List) => (a === b ? true : a.length === b.length ? a.every((element, index) => element === b[index]) : false); - faceDoc[DocData].face_descriptors = new List>(FaceRecognitionHandler.UniqueFaceDescriptors(faceDoc).filter(fd => !FaceRecognitionHandler.ImageDocFaceDescriptors(img).some(desc => descriptorsEqual(fd, desc)))); - Doc.RemoveDocFromList(img[DocData], FaceRecognitionHandler.ImageDocFaceField(img), faceDoc); + public static UniqueFaceRemoveFaceImage = (faceAnno: Doc, faceDoc: Doc) => { + Doc.RemoveDocFromList(faceDoc[DocData], 'face_annos', faceAnno); + faceAnno.face = undefined; }; constructor() { @@ -192,8 +162,7 @@ export class FaceRecognitionHandler { }); const uface = uniqueFaceDoc[DocData]; uface.face = `Face${faceDocNum}`; - uface.face_images = new List(); - uface.face_descriptors = new List>(); + uface.face_annos = new List(); Doc.SetContainer(uniqueFaceDoc, Doc.MyFaceCollection); Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'myUniqueFaces', uniqueFaceDoc); @@ -243,7 +212,6 @@ export class FaceRecognitionHandler { if (imgUrl && !DocListCast(Doc.MyFaceCollection.examinedFaceDocs).includes(imgDoc[DocData])) { // only examine Docs that have an image and that haven't already been examined. Doc.AddDocToList(Doc.MyFaceCollection, 'examinedFaceDocs', imgDoc[DocData]); - FaceRecognitionHandler.initImageDocFaceDescriptors(imgDoc); FaceRecognitionHandler.loadImage(imgUrl).then( // load image and analyze faces img => faceapi @@ -255,22 +223,20 @@ export class FaceRecognitionHandler { const scale = NumCast(imgDoc.data_nativeWidth) / img.width; imgDocFaceDescriptions.forEach((fd, i) => { const faceDescriptor = new List(Array.from(fd.descriptor)); - FaceRecognitionHandler.ImageDocAddFaceDescriptor(imgDoc, faceDescriptor); // add face descriptor to image's list of descriptors const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(activeDashboard); - FaceRecognitionHandler.UniqueFaceAddFaceImage(imgDoc, faceDescriptor, matchedUniqueFace); // add image/faceDescriptor to matched unique face - annos.push( - Docs.Create.FreeformDocument([], { - title: ComputedField.MakeFunction(`this.face.face`, undefined, undefined, 'this.face.face = value') as unknown as string, // - annotationOn: imgDoc, - face: matchedUniqueFace[DocData], - backgroundColor: '#55555555', - x: fd.alignedRect.box.left * scale, - y: fd.alignedRect.box.top * scale, - _width: fd.alignedRect.box.width * scale, - _height: fd.alignedRect.box.height * scale, - }) - ); - Doc.SetContainer(annos.lastElement(), imgDoc[DocData]); + const faceAnno = Docs.Create.FreeformDocument([], { + title: ComputedField.MakeFunction(`this.face.face`, undefined, undefined, 'this.face.face = value') as unknown as string, // + annotationOn: imgDoc, + face: matchedUniqueFace[DocData], + faceDescriptor: faceDescriptor, + backgroundColor: 'transparent', + x: fd.alignedRect.box.left * scale, + y: fd.alignedRect.box.top * scale, + _width: fd.alignedRect.box.width * scale, + _height: fd.alignedRect.box.height * scale, + }) + FaceRecognitionHandler.UniqueFaceAddFaceImage(faceAnno, matchedUniqueFace); // add image/faceDescriptor to matched unique face + annos.push(faceAnno); }); imgDoc[DocData].data_annotations = new List(annos); diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index e3178f20c..7abba7679 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -791,9 +791,9 @@ export namespace Doc { linkMap.set(link[Id], await Doc.makeClone(link, cloneMap, linkMap, rtfs, exclusions, pruneDocs, cloneLinks, cloneTemplates)); } }); - if (Doc.Get(copy, 'title', true)) copy.title = '>:' + doc.title; - // Doc.SetInPlace(copy, 'title', '>:' + doc.title, true); copy.cloneOf = doc; + const cfield = ComputedField.WithoutComputed(() => FieldValue(doc.title)); + if (Doc.Get(copy, 'title', true) && !(cfield instanceof ComputedField)) copy.title = '>:' + doc.title; cloneMap.set(doc[Id], copy); return copy; @@ -1424,7 +1424,7 @@ export namespace Doc { export function Paste(docids: string[], clone: boolean, addDocument: (doc: Doc | Doc[]) => boolean, ptx?: number, pty?: number, newPoint?: number[]) { DocServer.GetRefFields(docids).then(async fieldlist => { - const list = Array.from(Object.values(fieldlist)) + const list = Array.from(fieldlist.values()) .map(d => DocCast(d)) .filter(d => d); const docs = clone ? (await Promise.all(Doc.MakeClones(list, false, false))).map(res => res.clone) : list; -- cgit v1.2.3-70-g09d2 From b8a04a0fedf8ef3612395764a0ecd01f6824ebd1 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 27 Aug 2024 13:54:39 -0400 Subject: from last --- src/client/views/TagsView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index da1add55b..d2ca77446 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -309,7 +309,7 @@ export class TagsView extends ObservableReactComponent { }}>
- {!tagsList.size ? null : ( // + {!tagsList.size && !facesList.size ? null : ( // this.setToEditing(!this._isEditing)} icon={} /> )} {Array.from(tagsList).map((tag, i) => ( -- cgit v1.2.3-70-g09d2 From a566129971f1a29b1d42679befa27c63b73a7167 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 27 Aug 2024 17:43:27 -0400 Subject: move chat tag labels to tags_chat and updated tagsView --- src/client/views/TagsView.tsx | 32 ++++++++++++++++++++-- .../collectionFreeForm/ImageLabelBox.tsx | 15 +++++----- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index d2ca77446..89025d668 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button, Colors, IconButton } from 'browndash-components'; -import { action, computed, makeObservable, observable } from 'mobx'; +import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; import ResizeObserver from 'resize-observer-polyfill'; @@ -248,11 +248,25 @@ export class TagsView extends ObservableReactComponent { makeObservable(this); } + @observable _panelHeightDirty = 0; @observable _currentInput = ''; @observable _isEditing = !StrListCast(this._props.View.dataDoc.tags).length; + _heightDisposer: IReactionDisposer | undefined; + + componentDidMount() { + this._heightDisposer = reaction( + () => this._props.View.screenToContentsTransform(), + xf => { + this._panelHeightDirty = this._panelHeightDirty + 1; + } + ); + } + componentWillUnmount() { + this._heightDisposer?.(); + } @computed get currentScale() { - return NumCast((this._props.View.Document.embedContainer as Doc)?._freeform_scale, 1); + return NumCast(DocCast(this._props.View.Document.embedContainer)?._freeform_scale, 1); } @computed get isEditing() { return this._isEditing && DocumentView.SelectedDocs().includes(this._props.View.Document); @@ -289,11 +303,13 @@ export class TagsView extends ObservableReactComponent { */ render() { const tagsList = new Set(StrListCast(this._props.View.dataDoc.tags)); + const chatTagsList = new Set(StrListCast(this._props.View.dataDoc.tags_chat)); const facesList = new Set( DocListCast(this._props.View.dataDoc[Doc.LayoutFieldKey(this._props.View.Document) + '_annotations']) .filter(d => d.face) .map(doc => StrCast(DocCast(doc.face)?.title)) ); + this._panelHeightDirty; return !this._props.View.Document.showTags ? null : (
{ /> ); })} + {Array.from(chatTagsList).map(tag => { + return ( +
) : null} diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index 5d3154e3c..e419e522c 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -163,7 +163,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { // Converts the images into a Base64 format, afterwhich the information is sent to GPT to label them. const imageInfos = this._selectedImages.map(async doc => { - if (!doc[DocData].tags) { + if (!doc[DocData].tags_chat) { const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); return CollectionCardView.imageUrlToBase64(`${name}_o.${type}`).then(hrefBase64 => !hrefBase64 ? undefined : @@ -174,7 +174,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { (await Promise.all(imageInfos)).forEach(imageInfo => { if (imageInfo) { - imageInfo.doc[DocData].tags = (imageInfo.doc[DocData].tags as List) ?? new List(); + imageInfo.doc[DocData].tags_chat = (imageInfo.doc[DocData].tags_chat as List) ?? new List(); const labels = imageInfo.labels.split('\n'); labels.forEach(label => { @@ -184,8 +184,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { .replace(/^\d+\.\s*|-|f\*/, '') .replace(/^#/, '') .trim(); - imageInfo.doc[DocData][label] = true; - (imageInfo.doc[DocData].tags as List).push(label); + (imageInfo.doc[DocData].tags_chat as List).push(label); }); } }); @@ -200,8 +199,8 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { this.startLoading(); for (const doc of this._selectedImages) { - for (let index = 0; index < (doc[DocData].tags as List).length; index++) { - const label = (doc[DocData].tags as List)[index]; + for (let index = 0; index < (doc[DocData].tags_chat as List).length; index++) { + const label = (doc[DocData].tags_chat as List)[index]; const embedding = await gptGetEmbedding(label); doc[DocData][`tags_embedding_${index + 1}`] = new List(embedding); } @@ -214,7 +213,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { // For each image, loop through the labels, and calculate similarity. Associate it with the // most similar one. this._selectedImages.forEach(doc => { - const embedLists = numberRange((doc[DocData].tags as List).length).map(n => Array.from(NumListCast(doc[DocData][`tags_embedding_${n + 1}`]))); + const embedLists = numberRange((doc[DocData].tags_chat as List).length).map(n => Array.from(NumListCast(doc[DocData][`tags_embedding_${n + 1}`]))); const bestEmbedScore = (embedding: Opt) => Math.max(...embedLists.map((l, index) => (embedding && similarity(Array.from(embedding), l)!) || 0)); const {label: mostSimilarLabelCollect} = this._labelGroups.map(label => ({ label, similarityScore: bestEmbedScore(labelToEmbedding.get(label)) })) @@ -321,7 +320,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { await DocumentView.showDocument(doc, { willZoomCentered: true }); }}>
this._props.addDocTab(doc, OpenWhere.addRightKeyvalue)}> - {(doc[DocData].tags as List).map(label => { + {(doc[DocData].tags_chat as List).map(label => { return (
{label} -- cgit v1.2.3-70-g09d2 From e2a1db72c103b7ed878fe876c5fb9eacc7a8c893 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 27 Aug 2024 19:09:31 -0400 Subject: enabled any image Doc to be added to a face Doc --- src/client/views/TagsView.tsx | 1 + .../collectionFreeForm/FaceCollectionBox.tsx | 17 +++++++++-------- src/client/views/search/FaceRecognitionHandler.tsx | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index 89025d668..0ac015b36 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -306,6 +306,7 @@ export class TagsView extends ObservableReactComponent { const chatTagsList = new Set(StrListCast(this._props.View.dataDoc.tags_chat)); const facesList = new Set( DocListCast(this._props.View.dataDoc[Doc.LayoutFieldKey(this._props.View.Document) + '_annotations']) + .concat(this._props.View.Document) .filter(d => d.face) .map(doc => StrCast(DocCast(doc.face)?.title)) ); diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index c62303dc0..717081666 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -95,17 +95,18 @@ export class UniqueFaceBox extends ViewBoxBaseComponent() { const faceDescriptorsAsFloat32Array = FaceRecognitionHandler.UniqueFaceDescriptors(this.Document).map(fd => new Float32Array(Array.from(fd))); const labeledFaceDescriptor = new faceapi.LabeledFaceDescriptors(FaceRecognitionHandler.UniqueFaceLabel(this.Document), faceDescriptorsAsFloat32Array); const faceMatcher = new FaceMatcher([labeledFaceDescriptor], 1); - const { faceAnno } = FaceRecognitionHandler.ImageDocFaceAnnos(imgDoc).reduce( - (prev, faceAnno) => { - const match = faceMatcher.matchDescriptor(new Float32Array(Array.from(faceAnno.faceDescriptor as List))); - return match.distance < prev.dist ? { dist: match.distance, faceAnno } : prev; - }, - { dist: 1, faceAnno: undefined as Opt } - ); + const faceAnno = + FaceRecognitionHandler.ImageDocFaceAnnos(imgDoc).reduce( + (prev, faceAnno) => { + const match = faceMatcher.matchDescriptor(new Float32Array(Array.from(faceAnno.faceDescriptor as List))); + return match.distance < prev.dist ? { dist: match.distance, faceAnno } : prev; + }, + { dist: 1, faceAnno: undefined as Opt } + ).faceAnno ?? imgDoc; // assign the face in the image that's closest to the face collection's face if (faceAnno) { - FaceRecognitionHandler.UniqueFaceRemoveFaceImage(faceAnno, DocCast(faceAnno.face)); + faceAnno.face && FaceRecognitionHandler.UniqueFaceRemoveFaceImage(faceAnno, DocCast(faceAnno.face)); FaceRecognitionHandler.UniqueFaceAddFaceImage(faceAnno, this.Document); faceAnno.face = this.Document; } diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 4c10307e6..4f6f5d314 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -101,7 +101,7 @@ export class FaceRecognitionHandler { * @param faceDoc unique face Doc * @returns image Docs */ - public static UniqueFaceImages = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_annos).map(face => DocCast(face.annotationOn)); + public static UniqueFaceImages = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_annos).map(face => DocCast(face.annotationOn, face)); /** * Adds a face image to a unique face Doc, adds the unique face Doc to the images list of reognized faces, -- cgit v1.2.3-70-g09d2 From 9776e4584b61d3c67622d8ea1f2338a7dfbe857d Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 27 Aug 2024 21:57:43 -0400 Subject: fixed type --- src/client/views/pdf/Annotation.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index 3bd42873c..1891cfd4c 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -13,6 +13,7 @@ import { FieldViewProps } from '../nodes/FieldView'; import { OpenWhere } from '../nodes/OpenWhere'; import { AnchorMenu } from './AnchorMenu'; import './Annotation.scss'; +import { Property } from 'csstype'; interface IRegionAnnotationProps { x: number; @@ -45,7 +46,7 @@ interface IAnnotationProps extends FieldViewProps { annoDoc: Doc; containerDataDoc: Doc; fieldKey: string; - pointerEvents?: () => Opt; + pointerEvents?: () => Opt; } @observer export class Annotation extends ObservableReactComponent { -- cgit v1.2.3-70-g09d2 From c36607691e0b7f5c04f3209a64958f5e51ddd785 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 30 Aug 2024 00:06:05 -0400 Subject: fixed linking text anchors to dall-e images --- src/client/views/pdf/GPTPopup/GPTPopup.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 0920b1bd3..a37e73e27 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -268,7 +268,7 @@ export class GPTPopup extends ObservableReactComponent { * Transfers the image urls to actual image docs */ private transferToImage = (source: string) => { - const textAnchor = this.imgTargetDoc; + const textAnchor = this.textAnchor ?? this.imgTargetDoc; if (!textAnchor) return; const newDoc = Docs.Create.ImageDocument(source, { x: NumCast(textAnchor.x) + NumCast(textAnchor._width) + 10, -- cgit v1.2.3-70-g09d2 From b235e116167a06b6d36e2962dd3f610839f18974 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 1 Sep 2024 00:11:36 -0400 Subject: updated to latest Jimp. fixed lag dropping images from filesystem by using worker threads. --- package-lock.json | 8128 ++++---------------- package.json | 9 +- src/client/Network.ts | 2 +- src/client/util/request-image-size.ts | 9 +- .../collectionGrid/CollectionGridView.tsx | 17 +- src/server/ApiManagers/UploadManager.ts | 14 +- src/server/DashUploadUtils.ts | 94 +- 7 files changed, 1447 insertions(+), 6826 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1e738fcb1..4c5a5d4d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,8 +26,8 @@ "@fullcalendar/daygrid": "^6.1.10", "@fullcalendar/multimonth": "^6.1.10", "@internationalized/date": "^3.5.0", - "@mui/icons-material": "^5.14.19", - "@mui/material": "^5.14.19", + "@mui/icons-material": "^6.0.1", + "@mui/material": "^6.0.1", "@octokit/core": "^6.0.1", "@react-google-maps/api": "^2.19.2", "@react-spring/web": "^9.7.3", @@ -50,10 +50,11 @@ "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/textfit": "^2.4.4", - "@types/web": "^0.0.157", + "@types/web": "^0.0.159", "@types/webpack-hot-middleware": "^2.25.9", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", + "any-base": "^1.1.0", "archiver": "^7.0.1", "async": "^3.2.5", "axios": "^1.6.2", @@ -131,7 +132,7 @@ "image-size": "^1.0.2", "image-size-stream": "^1.1.0", "is-plain-obj": "^4.1.0", - "jimp": "^0.22.10", + "jimp": "^1.0.4", "jpeg-autorotate": "^9.0.0", "jquery": "^3.7.1", "js-datepicker": "^5.18.2", @@ -697,11 +698,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.5.tgz", - "integrity": "sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dependencies": { - "@babel/types": "^7.25.4", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -953,13 +954,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "peer": true, "dependencies": { "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" @@ -980,11 +981,11 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.4.tgz", - "integrity": "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dependencies": { - "@babel/types": "^7.25.4" + "@babel/types": "^7.25.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -1137,11 +1138,11 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", + "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1151,11 +1152,11 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -2248,9 +2249,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2259,9 +2260,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.0.tgz", - "integrity": "sha512-BOehWE7MgQ8W8Qn0CQnMtg2tHPHPulcS/5AVpFvs2KCK1ET+0WqZqPvnpRpFN81gYoFopdIEJX9Sgjw3ZBccPg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.6.tgz", + "integrity": "sha512-Gz0Nrobx8szge6kQQ5Z5MX9L3ObqNwCQY1PSwSNzreFL7aHGxv8Fp2j3ETV6/wWdbiV+mW6OSm8oQhg3Tcsniw==", "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" @@ -2284,15 +2285,15 @@ } }, "node_modules/@babel/traverse": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.4.tgz", - "integrity": "sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.4", - "@babel/parser": "^7.25.4", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", "@babel/template": "^7.25.0", - "@babel/types": "^7.25.4", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2309,9 +2310,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.4.tgz", - "integrity": "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", @@ -3114,399 +3115,306 @@ "node": ">=8" } }, - "node_modules/@jimp/bmp": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.12.tgz", - "integrity": "sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g==", + "node_modules/@jimp/core": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-1.0.4.tgz", + "integrity": "sha512-K+wDZbpdqwO0+GtMVdTEDttFAWA1R70uebcO+TTVliD88Cae1UKFxJOMTbAGFI+PJqvpZWpZn+5S6N5jLbHVXA==", "dependencies": { - "@jimp/utils": "^0.22.12", - "bmp-js": "^0.1.0" + "@jimp/file-ops": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "await-to-js": "^3.0.0", + "exif-parser": "^0.1.12", + "file-type": "^16.0.0", + "mime": "3" + } + }, + "node_modules/@jimp/core/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "bin": { + "mime": "cli.js" }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "engines": { + "node": ">=10.0.0" } }, - "node_modules/@jimp/core": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.12.tgz", - "integrity": "sha512-l0RR0dOPyzMKfjUW1uebzueFEDtCOj9fN6pyTYWWOM/VS4BciXQ1VVrJs8pO3kycGYZxncRKhCoygbNr8eEZQA==", + "node_modules/@jimp/diff": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/diff/-/diff-1.0.4.tgz", + "integrity": "sha512-AEsoPrZ4SiY/xFCVFwcTu3qN63gVyktL3NXHnQZoYOLcW9pvFVGsNxBa1iwk0OkK2FAR7VyuOsJtn0qmq6hUNA==", "dependencies": { - "@jimp/utils": "^0.22.12", - "any-base": "^1.1.0", - "buffer": "^5.2.0", - "exif-parser": "^0.1.12", - "file-type": "^16.5.4", - "isomorphic-fetch": "^3.0.0", - "pixelmatch": "^4.0.2", - "tinycolor2": "^1.6.0" + "@jimp/plugin-resize": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "pixelmatch": "^5.3.0" } }, - "node_modules/@jimp/custom": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.12.tgz", - "integrity": "sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q==", + "node_modules/@jimp/file-ops": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/file-ops/-/file-ops-1.0.4.tgz", + "integrity": "sha512-Epbp4brdZY6cv4jFmY8TUF6RtpIWnVFAGPr6tOTF/bI8RsXgucNbpjFQZU5M+HOAyxLED6p7o1STHFn6nGMVnA==" + }, + "node_modules/@jimp/js-bmp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/js-bmp/-/js-bmp-1.0.4.tgz", + "integrity": "sha512-p2l0xBfo+fQ/NBG93DKBC06e5xFAHRP0B4KdUINSoAXULkrBfutKd9KPBRQMAjVA8e3anLEiv1P91wYSScEvLA==", "dependencies": { - "@jimp/core": "^0.22.12" + "@jimp/core": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "bmp-ts": "^1.0.9" } }, - "node_modules/@jimp/gif": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.12.tgz", - "integrity": "sha512-y6BFTJgch9mbor2H234VSjd9iwAhaNf/t3US5qpYIs0TSbAvM02Fbc28IaDETj9+4YB4676sz4RcN/zwhfu1pg==", + "node_modules/@jimp/js-gif": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/js-gif/-/js-gif-1.0.4.tgz", + "integrity": "sha512-P/BH5JsR+WwkvpD+OPg+M4As+Cnzigin7QcTjda8A5nQyuTTL86qdrl5a5DbxBTXRnajCwIhb3oAQmbuD9ec/A==", "dependencies": { - "@jimp/utils": "^0.22.12", + "@jimp/core": "1.0.4", + "@jimp/types": "1.0.4", "gifwrap": "^0.10.1", - "omggif": "^1.0.9" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "omggif": "^1.0.10" } }, - "node_modules/@jimp/jpeg": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.12.tgz", - "integrity": "sha512-Rq26XC/uQWaQKyb/5lksCTCxXhtY01NJeBN+dQv5yNYedN0i7iYu+fXEoRsfaJ8xZzjoANH8sns7rVP4GE7d/Q==", + "node_modules/@jimp/js-jpeg": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/js-jpeg/-/js-jpeg-1.0.4.tgz", + "integrity": "sha512-BgsYW+cujySH13+8Ld5WLIvyv4VatGb1BlqP7zjS84vriX2HcgGNoyYHjnaLn1Qd5yxfU8Atewqxo0DipLlHmQ==", "dependencies": { - "@jimp/utils": "^0.22.12", + "@jimp/core": "1.0.4", + "@jimp/types": "1.0.4", "jpeg-js": "^0.4.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/js-png": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/js-png/-/js-png-1.0.4.tgz", + "integrity": "sha512-B8AeNGbPFd/wZzIKy9qZXvJ44yDDSQSDsU0OrCiNZCP70S5raWa93LehOYqEdr+brwO7+FiwI7nbCAUB/zgcPQ==", + "dependencies": { + "@jimp/core": "1.0.4", + "@jimp/types": "1.0.4", + "pngjs": "^7.0.0" + } + }, + "node_modules/@jimp/js-tiff": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/js-tiff/-/js-tiff-1.0.4.tgz", + "integrity": "sha512-K/A/Ej6C0bgUP7nD0vH3hc2ftfib7oAdRPN1HLpyyJJc4eatfLcoY1BlDgLiOwEfv8LEzhRB8+0uMwM6ZrvjcQ==", + "dependencies": { + "@jimp/core": "1.0.4", + "@jimp/types": "1.0.4", + "utif2": "^4.1.0" } }, "node_modules/@jimp/plugin-blit": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.12.tgz", - "integrity": "sha512-xslz2ZoFZOPLY8EZ4dC29m168BtDx95D6K80TzgUi8gqT7LY6CsajWO0FAxDwHz6h0eomHMfyGX0stspBrTKnQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-1.0.4.tgz", + "integrity": "sha512-u3HIa6VmKShNJ3/RPIJizecEFgRPwLVo0vyjtE/hx7L2TfbNxaWShUBUqEVL192Luk7D9SIBl998ujn37lO4DQ==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-blur": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.12.tgz", - "integrity": "sha512-S0vJADTuh1Q9F+cXAwFPlrKWzDj2F9t/9JAbUvaaDuivpyWuImEKXVz5PUZw2NbpuSHjwssbTpOZ8F13iJX4uw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-1.0.4.tgz", + "integrity": "sha512-hgNPUvlgyoRGIYFZ5u2Ptd2f3b1m2+KeDJ1RXnWshz01oc/vr0UyRZRzmhKn0S8Ic+3UYa3mAsIBp7GLsXyK5g==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/types": "1.0.4" } }, "node_modules/@jimp/plugin-circle": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.12.tgz", - "integrity": "sha512-SWVXx1yiuj5jZtMijqUfvVOJBwOifFn0918ou4ftoHgegc5aHWW5dZbYPjvC9fLpvz7oSlptNl2Sxr1zwofjTg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-1.0.4.tgz", + "integrity": "sha512-C4lBEnCYBahq4qefYyAH/mkIsWzytsERcwR17V6x4+UxmD0vW1aEMAKrPvEEsTM7O84zUgCrYuh7+Uuvf+00lw==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/types": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-color": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.12.tgz", - "integrity": "sha512-xImhTE5BpS8xa+mAN6j4sMRWaUgUDLoaGHhJhpC+r7SKKErYDR0WQV4yCE4gP+N0gozD0F3Ka1LUSaMXrn7ZIA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-1.0.4.tgz", + "integrity": "sha512-og/KO6pRncUt2ovQK+J/UseLerfjmv4IBS4Byb5KrQ1O7P5l+wvb537EMuixHOzW9G7CI7OyuzjOSEvW1LOJOQ==", "dependencies": { - "@jimp/utils": "^0.22.12", - "tinycolor2": "^1.6.0" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/core": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "tinycolor2": "^1.6.0", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-contain": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.12.tgz", - "integrity": "sha512-Eo3DmfixJw3N79lWk8q/0SDYbqmKt1xSTJ69yy8XLYQj9svoBbyRpSnHR+n9hOw5pKXytHwUW6nU4u1wegHNoQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-1.0.4.tgz", + "integrity": "sha512-5cjPOIW6W/tiVG1CU64rSsR5MJ/x2tGk6Z1erJqI+7oQDtrP9iSI1HGdhrenIegdtgsxQ8xcr3DoaEvmOkwwdA==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5", - "@jimp/plugin-scale": ">=0.3.5" + "@jimp/core": "1.0.4", + "@jimp/plugin-blit": "1.0.4", + "@jimp/plugin-resize": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-cover": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.12.tgz", - "integrity": "sha512-z0w/1xH/v/knZkpTNx+E8a7fnasQ2wHG5ze6y5oL2dhH1UufNua8gLQXlv8/W56+4nJ1brhSd233HBJCo01BXA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-1.0.4.tgz", + "integrity": "sha512-9gYQsSxJ1wvzurS9d0BBVFLb6Y6soc02NL5YA/kdaydfmpUn2M/DbIuVR+G5oaWUvL0kriTyCVLw7Pk26rqxpA==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-crop": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5", - "@jimp/plugin-scale": ">=0.3.5" + "@jimp/core": "1.0.4", + "@jimp/plugin-crop": "1.0.4", + "@jimp/plugin-resize": "1.0.4", + "@jimp/types": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-crop": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.12.tgz", - "integrity": "sha512-FNuUN0OVzRCozx8XSgP9MyLGMxNHHJMFt+LJuFjn1mu3k0VQxrzqbN06yIl46TVejhyAhcq5gLzqmSCHvlcBVw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-1.0.4.tgz", + "integrity": "sha512-FAxSqeeFNvmcEiQ6aHmxGZCtfj+atQAg5Xs8AJMOpVYe36mVLXlaQgl+TDGZl0CroURtVfigtiEVLizAtmF4pQ==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/core": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-displace": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.12.tgz", - "integrity": "sha512-qpRM8JRicxfK6aPPqKZA6+GzBwUIitiHaZw0QrJ64Ygd3+AsTc7BXr+37k2x7QcyCvmKXY4haUrSIsBug4S3CA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-1.0.4.tgz", + "integrity": "sha512-MXy2E+iwpQV4Iug3+9rYhUCFjJjw/aXn9ShwZSIUKlNuF2NWlZeI2QwbYR0sEFHHbovOMIVuA2FLzgmGM66XfQ==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-dither": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.12.tgz", - "integrity": "sha512-jYgGdSdSKl1UUEanX8A85v4+QUm+PE8vHFwlamaKk89s+PXQe7eVE3eNeSZX4inCq63EHL7cX580dMqkoC3ZLw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-1.0.4.tgz", + "integrity": "sha512-MdSmPE1l3sxtGoSVV7WLx5cMLk1KT3x+WXjivL19OBBPTLVbgPYdcOe7ikLM0ZoLbsw6PpvbGNfPY1LxDU7JzA==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/types": "1.0.4" } }, "node_modules/@jimp/plugin-fisheye": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.12.tgz", - "integrity": "sha512-LGuUTsFg+fOp6KBKrmLkX4LfyCy8IIsROwoUvsUPKzutSqMJnsm3JGDW2eOmWIS/jJpPaeaishjlxvczjgII+Q==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-1.0.4.tgz", + "integrity": "sha512-iSeiU1WzhZBi1qfLWUiMNG7Ft1AP6ZFvfR8fpr9X+ipJ+uvofBQ2SzHUxmhxcI/PGcZTdXUkUxT20LiM9h3ksQ==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-flip": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.12.tgz", - "integrity": "sha512-m251Rop7GN8W0Yo/rF9LWk6kNclngyjIJs/VXHToGQ6EGveOSTSQaX2Isi9f9lCDLxt+inBIb7nlaLLxnvHX8Q==", - "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-rotate": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-gaussian": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.12.tgz", - "integrity": "sha512-sBfbzoOmJ6FczfG2PquiK84NtVGeScw97JsCC3rpQv1PHVWyW+uqWFF53+n3c8Y0P2HWlUjflEla2h/vWShvhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-1.0.4.tgz", + "integrity": "sha512-0YoLAOtvAonHgOST7jyt36Dv0262FQZGbAvevI8TYbcU6BPPSuONBQRw04iSmakk0XdeJ5TfP+I/Z3qZSn48FQ==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/types": "1.0.4", + "zod": "^3.22.4" } }, - "node_modules/@jimp/plugin-invert": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.12.tgz", - "integrity": "sha512-N+6rwxdB+7OCR6PYijaA/iizXXodpxOGvT/smd/lxeXsZ/empHmFFFJ/FaXcYh19Tm04dGDaXcNF/dN5nm6+xQ==", + "node_modules/@jimp/plugin-hash": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-hash/-/plugin-hash-1.0.4.tgz", + "integrity": "sha512-FgL3jX5dIDtVJ5WUVzAcSy740Jk2p/6rB0Vg40TkETfEYnhHfltRGkpvv5a1kxD0icte23eICNU1lL5hw27lJw==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/core": "1.0.4", + "@jimp/js-bmp": "1.0.4", + "@jimp/js-jpeg": "1.0.4", + "@jimp/js-png": "1.0.4", + "@jimp/js-tiff": "1.0.4", + "@jimp/plugin-color": "1.0.4", + "@jimp/plugin-resize": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "@types/any-base": "^1.1.3" } }, "node_modules/@jimp/plugin-mask": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.12.tgz", - "integrity": "sha512-4AWZg+DomtpUA099jRV8IEZUfn1wLv6+nem4NRJC7L/82vxzLCgXKTxvNvBcNmJjT9yS1LAAmiJGdWKXG63/NA==", - "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-normalize": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.12.tgz", - "integrity": "sha512-0So0rexQivnWgnhacX4cfkM2223YdExnJTTy6d06WbkfZk5alHUx8MM3yEzwoCN0ErO7oyqEWRnEkGC+As1FtA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-1.0.4.tgz", + "integrity": "sha512-E9Z3aitK1coWpCXy0qycBPnfcxTbg3azygdMOZdj9Nbjnf+rh0Jz+JtG4HKJjCw9SLOgvCNjKY71JkubdyoRhg==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/types": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-print": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.12.tgz", - "integrity": "sha512-c7TnhHlxm87DJeSnwr/XOLjJU/whoiKYY7r21SbuJ5nuH+7a78EW1teOaj5gEr2wYEd7QtkFqGlmyGXY/YclyQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-1.0.4.tgz", + "integrity": "sha512-eTTTfZe7GgIZifLrQgt7EsWK/JKLm2Lm1Upro3wVKHJ8gfBtq5Fu+GxCeER+1bA7a5b9IGZSO3diRNqOpXs6bw==", "dependencies": { - "@jimp/utils": "^0.22.12", - "load-bmfont": "^1.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5" + "@jimp/core": "1.0.4", + "@jimp/js-jpeg": "1.0.4", + "@jimp/js-png": "1.0.4", + "@jimp/plugin-blit": "1.0.4", + "@jimp/types": "1.0.4", + "parse-bmfont-ascii": "^1.0.6", + "parse-bmfont-binary": "^1.0.6", + "parse-bmfont-xml": "^1.1.6", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-resize": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.12.tgz", - "integrity": "sha512-3NyTPlPbTnGKDIbaBgQ3HbE6wXbAlFfxHVERmrbqAi8R3r6fQPxpCauA8UVDnieg5eo04D0T8nnnNIX//i/sXg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-1.0.4.tgz", + "integrity": "sha512-iOOMCe3rSBKB6AhDBKJFZIjnqL1j6IB/SxdQsW8H5oCevuz4OPROxPBIdNDXxeyGBwqqppXbcnsL+sX7NUI7KQ==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/core": "1.0.4", + "@jimp/types": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-rotate": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.12.tgz", - "integrity": "sha512-9YNEt7BPAFfTls2FGfKBVgwwLUuKqy+E8bDGGEsOqHtbuhbshVGxN2WMZaD4gh5IDWvR+emmmPPWGgaYNYt1gA==", - "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5", - "@jimp/plugin-crop": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-scale": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.12.tgz", - "integrity": "sha512-dghs92qM6MhHj0HrV2qAwKPMklQtjNpoYgAB94ysYpsXslhRTiPisueSIELRwZGEr0J0VUxpUY7HgJwlSIgGZw==", - "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-shadow": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.12.tgz", - "integrity": "sha512-FX8mTJuCt7/3zXVoeD/qHlm4YH2bVqBuWQHXSuBK054e7wFRnRnbSLPUqAwSeYP3lWqpuQzJtgiiBxV3+WWwTg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-1.0.4.tgz", + "integrity": "sha512-QjY2DYFZj+m+I6F8aWDGAT/YHfpkP8AF9/qW4zi3Lq3WpBAeOqf9cvcHBjFv3hN72JQlneC5dRWE1h/QfygRxQ==", "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blur": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" + "@jimp/core": "1.0.4", + "@jimp/plugin-crop": "1.0.4", + "@jimp/plugin-resize": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/plugin-threshold": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.12.tgz", - "integrity": "sha512-4x5GrQr1a/9L0paBC/MZZJjjgjxLYrqSmWd+e+QfAEPvmRxdRoQ5uKEuNgXnm9/weHQBTnQBQsOY2iFja+XGAw==", - "dependencies": { - "@jimp/utils": "^0.22.12" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-color": ">=0.8.0", - "@jimp/plugin-resize": ">=0.8.0" - } - }, - "node_modules/@jimp/plugins": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.12.tgz", - "integrity": "sha512-yBJ8vQrDkBbTgQZLty9k4+KtUQdRjsIDJSPjuI21YdVeqZxYywifHl4/XWILoTZsjTUASQcGoH0TuC0N7xm3ww==", - "dependencies": { - "@jimp/plugin-blit": "^0.22.12", - "@jimp/plugin-blur": "^0.22.12", - "@jimp/plugin-circle": "^0.22.12", - "@jimp/plugin-color": "^0.22.12", - "@jimp/plugin-contain": "^0.22.12", - "@jimp/plugin-cover": "^0.22.12", - "@jimp/plugin-crop": "^0.22.12", - "@jimp/plugin-displace": "^0.22.12", - "@jimp/plugin-dither": "^0.22.12", - "@jimp/plugin-fisheye": "^0.22.12", - "@jimp/plugin-flip": "^0.22.12", - "@jimp/plugin-gaussian": "^0.22.12", - "@jimp/plugin-invert": "^0.22.12", - "@jimp/plugin-mask": "^0.22.12", - "@jimp/plugin-normalize": "^0.22.12", - "@jimp/plugin-print": "^0.22.12", - "@jimp/plugin-resize": "^0.22.12", - "@jimp/plugin-rotate": "^0.22.12", - "@jimp/plugin-scale": "^0.22.12", - "@jimp/plugin-shadow": "^0.22.12", - "@jimp/plugin-threshold": "^0.22.12", - "timm": "^1.6.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/png": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.12.tgz", - "integrity": "sha512-Mrp6dr3UTn+aLK8ty/dSKELz+Otdz1v4aAXzV5q53UDD2rbB5joKVJ/ChY310B+eRzNxIovbUF1KVrUsYdE8Hg==", - "dependencies": { - "@jimp/utils": "^0.22.12", - "pngjs": "^6.0.0" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/tiff": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.12.tgz", - "integrity": "sha512-E1LtMh4RyJsoCAfAkBRVSYyZDTtLq9p9LUiiYP0vPtXyxX4BiYBUYihTLSBlCQg5nF2e4OpQg7SPrLdJ66u7jg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-1.0.4.tgz", + "integrity": "sha512-wF//3Kg5nOcqBIx7p+fI/8x5T4FDzAXjTL+B8acNJIYNRJR0eceErgFvSl+lAA8xKMyVHbXtrzbUK7+p1Cdptw==", "dependencies": { - "utif2": "^4.0.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "@jimp/core": "1.0.4", + "@jimp/plugin-color": "1.0.4", + "@jimp/plugin-hash": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4", + "zod": "^3.22.4" } }, "node_modules/@jimp/types": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.12.tgz", - "integrity": "sha512-wwKYzRdElE1MBXFREvCto5s699izFHNVvALUv79GXNbsOVqlwlOxlWJ8DuyOGIXoLP4JW/m30YyuTtfUJgMRMA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-1.0.4.tgz", + "integrity": "sha512-sKM5R5kEm2VyfU68vYfEDoDtlmHMZ+pJTvYxa62SA5WEFKeO2ATBsybk5a8bJV1LDL1FXwKgXR6wsO4kx4RfQw==", "dependencies": { - "@jimp/bmp": "^0.22.12", - "@jimp/gif": "^0.22.12", - "@jimp/jpeg": "^0.22.12", - "@jimp/png": "^0.22.12", - "@jimp/tiff": "^0.22.12", - "timm": "^1.6.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" + "zod": "^3.22.4" } }, "node_modules/@jimp/utils": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz", - "integrity": "sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-1.0.4.tgz", + "integrity": "sha512-aqsJKDleM54v0s9rW+swc0SJHb/O4sy2I56ng+9UC7uhF+P6JRjvMVyqEprQ1fKBaCN/Ff0Bu0YUzEXwUtpH/g==", "dependencies": { - "regenerator-runtime": "^0.13.3" + "@jimp/types": "1.0.4", + "tinycolor2": "^1.6.0" } }, - "node_modules/@jimp/utils/node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -3799,6 +3707,45 @@ "langium": "3.0.0" } }, + "node_modules/@module-federation/runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.5.1.tgz", + "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", + "optional": true, + "peer": true, + "dependencies": { + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", + "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", + "optional": true, + "peer": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/webpack-bundler-runtime": "0.5.1" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.5.1.tgz", + "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", + "optional": true, + "peer": true + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", + "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", + "optional": true, + "peer": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/sdk": "0.5.1" + } + }, "node_modules/@mongodb-js/saslprep": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz", @@ -3808,32 +3755,32 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.16.7", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz", - "integrity": "sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.0.1.tgz", + "integrity": "sha512-TmKkCTwgtwvlFTF1tZzG4lYbi7v6NGweEJwFBZoIWZrkF1OLa0xu4umifmIyd+bVIScsEj//E2AD6bOJbPMOOQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.16.7", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.7.tgz", - "integrity": "sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.0.1.tgz", + "integrity": "sha512-CsgaF65jA3H1YzpDg6H2nFH/UHueVlmpEtPim7xF9VbjYnmnblG3aX0GflBahH96Pg0schrFWyRySlgbVAh5Kw==", "dependencies": { - "@babel/runtime": "^7.23.9" + "@babel/runtime": "^7.25.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^5.0.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@mui/material": "^6.0.1", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3842,25 +3789,25 @@ } }, "node_modules/@mui/material": { - "version": "5.16.7", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", - "integrity": "sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/core-downloads-tracker": "^5.16.7", - "@mui/system": "^5.16.7", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.6", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.0.1.tgz", + "integrity": "sha512-gOJS0RKYs9lRACaTluXPNopxFpIBhWVmhf09lHpqpPlR6bujXhuiTE2Q8puensdz3Qm2JGzl1VjccYHieV1g8A==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@mui/core-downloads-tracker": "^6.0.1", + "@mui/system": "^6.0.1", + "@mui/types": "^7.2.16", + "@mui/utils": "^6.0.1", "@popperjs/core": "^2.11.8", - "@types/react-transition-group": "^4.4.10", - "clsx": "^2.1.0", + "@types/react-transition-group": "^4.4.11", + "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1", "react-is": "^18.3.1", "react-transition-group": "^4.4.5" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", @@ -3869,9 +3816,10 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "@mui/material-pigment-css": "^6.0.1", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -3880,30 +3828,33 @@ "@emotion/styled": { "optional": true }, + "@mui/material-pigment-css": { + "optional": true + }, "@types/react": { "optional": true } } }, "node_modules/@mui/private-theming": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", - "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.0.1.tgz", + "integrity": "sha512-jQCJml1OwIrhqN5tTk5Lpqx2RZKQnShE8lMlvAkuO7Ft+xaHkP8J3iHpEk3/Pzue34DfBQtK00jcaplgM47mBA==", "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.16.6", + "@babel/runtime": "^7.25.0", + "@mui/utils": "^6.0.1", "prop-types": "^15.8.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3912,17 +3863,17 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", - "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.0.1.tgz", + "integrity": "sha512-7ZOnUhIak2vosDgMlBE/oLrsvvF3O8QKmTFpP6bhZkHjPu4dv0DbF1vC7gzgkOqiMaT0/NgRQCFW9zh38pIvsg==", "dependencies": { - "@babel/runtime": "^7.23.9", - "@emotion/cache": "^11.11.0", + "@babel/runtime": "^7.25.0", + "@emotion/cache": "^11.13.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", @@ -3931,7 +3882,7 @@ "peerDependencies": { "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -3943,21 +3894,21 @@ } }, "node_modules/@mui/system": { - "version": "5.16.7", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz", - "integrity": "sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.16.6", - "@mui/styled-engine": "^5.16.6", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.6", - "clsx": "^2.1.0", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.0.1.tgz", + "integrity": "sha512-RdWyCMi+GkAekOnpMKhy51lyzid4F6Vj96vekp3AExkFY21JWg2+KVBqcAgJOROJ3RiaeDJf98n0yrixlCvuEw==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@mui/private-theming": "^6.0.1", + "@mui/styled-engine": "^6.0.1", + "@mui/types": "^7.2.16", + "@mui/utils": "^6.0.1", + "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", @@ -3966,8 +3917,8 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -3982,11 +3933,11 @@ } }, "node_modules/@mui/types": { - "version": "7.2.15", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", - "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "version": "7.2.16", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.16.tgz", + "integrity": "sha512-qI8TV3M7ShITEEc8Ih15A2vLzZGLhD+/UPNwck/hcls2gwg7dyRjNGXcQYHKLB5Q7PuTRfrTkAoPa2VV1s67Ag==", "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3995,27 +3946,27 @@ } }, "node_modules/@mui/utils": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", - "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.0.1.tgz", + "integrity": "sha512-YmQYb2tY5nJactHltTrKA15TZfbd1R003a2xYHxUuycTv9n83rsIwHkypOxM4x7+c+Pc8xfCuE9EfLT3B3n40Q==", "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/types": "^7.2.15", + "@babel/runtime": "^7.25.0", + "@mui/types": "^7.2.16", "@types/prop-types": "^15.7.12", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-is": "^18.3.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -7110,6 +7061,175 @@ "unicode-trie": "^0.3.0" } }, + "node_modules/@rspack/binding": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.0.0.tgz", + "integrity": "sha512-eLyqSEM1h/exJYn98k+9MRktP8AYDB13x5oVn8hoxVucuhk0TubFqQSX8h9SQcZp1O3j/Z8eWWwOaNPe3JU40Q==", + "optional": true, + "peer": true, + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.0.0", + "@rspack/binding-darwin-x64": "1.0.0", + "@rspack/binding-linux-arm64-gnu": "1.0.0", + "@rspack/binding-linux-arm64-musl": "1.0.0", + "@rspack/binding-linux-x64-gnu": "1.0.0", + "@rspack/binding-linux-x64-musl": "1.0.0", + "@rspack/binding-win32-arm64-msvc": "1.0.0", + "@rspack/binding-win32-ia32-msvc": "1.0.0", + "@rspack/binding-win32-x64-msvc": "1.0.0" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-ZHQk9YK+swlTG48kJTgzFUW9T26KjhLXRok5la7t2AMoiuHyhGHHgC5iQfPJLZ62XzcJ/rfqs2rwakl97151jQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.0.0.tgz", + "integrity": "sha512-qhTXm9wUhv2lBjsqqfCu59RchH1/2jursdPAmTqGc7zMReZdZvtJs2Ri6Ma1M48BLLu+7fS4fbL8Rw1g78TOOQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0.tgz", + "integrity": "sha512-yKnlsWgvydJRxDBGGKC+cyDeoSzIvOzuVqCloy5oAFAGOMXMY6bznxrkE6/olGZncdeLEpnJzZmXSuF1dYc8ow==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0.tgz", + "integrity": "sha512-dKFmlqlF4FELT/AX02hSwX8aRawjH5zAliQzYnvgrqcEyCKE60vKacGJQ3ZeRyru6dh5MlbUNW4H1+TDT+cDVA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0.tgz", + "integrity": "sha512-fRk9i8aE4FiwW7+LkNyw+5vfFzJ8BZ2seAL9V5U2iwYwYibzFJsukg3h3Uh+IsGm30/7+ZRENtGwybQiMruL4g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0.tgz", + "integrity": "sha512-qcTJC8o3KvLwsnrJJcuBjfzSrjEbACMiCB4RtbFNecXDtI+Nputx1CO1SlUrINC25/44ILketf0/hsdBQHk60g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0.tgz", + "integrity": "sha512-gqtakP0Yl2aj+Q/Giwgt31hz8eOZpo2s+sJlkMJGVdIF4dejB31a8vbj/VNGeSN1tDRiLI4cyqa5eQU//t26aQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0.tgz", + "integrity": "sha512-nLfGu5DjdzwawzZ7zK69vZX5aL1Gt9+Ovfz4RlngDq/D5ZzqCnNWw93cqKADgFRWS4qK9vOD9RXNNnkyWB2SEw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0.tgz", + "integrity": "sha512-H9PqjgtZMw5aP+eXdFo7bgSP/Ycwn3oW81uI9qFqOOQ90W+o3T9ItghHBf2/ksc5GHibd208EwOBNxbKwjZDSQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@rspack/core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.0.0.tgz", + "integrity": "sha512-F4RA9uOLLvD1oTKa96Gcly+Sro1qaqPNENadFyiPwepa7DrwexQa/ym6CQKbvKMOYGKlVSFDPUmgFAirz35ETg==", + "optional": true, + "peer": true, + "dependencies": { + "@module-federation/runtime-tools": "0.5.1", + "@rspack/binding": "1.0.0", + "@rspack/lite-tapable": "1.0.0", + "caniuse-lite": "^1.0.30001616" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.0.tgz", + "integrity": "sha512-7MZf4lburSUZoEenwazwUDKHhqyfnLCGnQ/tKcUtztfmVzfjZfRn/EaiT0AKkYGnL2U8AGsw89oUeVyvaOLVCw==", + "optional": true, + "peer": true, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@sec-ant/readable-stream": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", @@ -8827,6 +8947,11 @@ "integrity": "sha512-fpdH+ZtlO0kqjTOqRaBdsEmvpRNOayI8k4EVkEtitL5l6wducDOXk0rgQgfZqWf/ZX9DzXrHf257S5i9xTcISQ==", "dev": true }, + "node_modules/@types/any-base": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/any-base/-/any-base-1.1.3.tgz", + "integrity": "sha512-B7RTBD7jVYxm754XDdw6UozY3ZyyBv4iF4QQSjCzeLV4avDy8JBwCuI5SN4mz27ENI6K1NtKZwQ7zcqgH2h2Mw==" + }, "node_modules/@types/archiver": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-6.0.2.tgz", @@ -8893,9 +9018,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.18", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.18.tgz", - "integrity": "sha512-2UfJzigyNa8kYTKn7o4hNMPphkxtu4WTJyobK3m4FBpyj7EK5xgtPcOtxLm7Dznk/Qxr0QXn+gQbkg7mCZKdfg==", + "version": "4.3.19", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.19.tgz", + "integrity": "sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==", "dev": true }, "node_modules/@types/color": { @@ -9309,9 +9434,9 @@ "integrity": "sha512-IGKtSn0Lonfx3HdK6KMcfd5GUc1xdeLtjW1n7ZSA5Tmn1n2gj878q6IC0s4MbF9KtBpXIRqjRQxBzi2kF4WvGw==" }, "node_modules/@types/fluent-ffmpeg": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.25.tgz", - "integrity": "sha512-a9/Jtv/RVaCG4lUwWIcuClWE5eXJFoFS/oHOecOv/RS8n+lQdJzcJVmDlxA8Xbk4B82YpO88Dijcoljb6sYTcA==", + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.26.tgz", + "integrity": "sha512-0JVF3wdQG+pN0ImwWD0bNgJiKF2OHg/7CDBHw5UIbRTvlnkgGHK6V5doE54ltvhud4o31/dEiHm23CAlxFiUQg==", "dependencies": { "@types/node": "*" } @@ -9481,6 +9606,14 @@ "@types/geojson": "*" } }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -9505,9 +9638,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "22.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", - "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz", + "integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==", "dependencies": { "undici-types": "~6.19.2" } @@ -9628,8 +9761,7 @@ "node_modules/@types/qs": { "version": "6.9.15", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", - "dev": true + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" }, "node_modules/@types/range-parser": { "version": "1.2.7", @@ -9647,9 +9779,9 @@ } }, "node_modules/@types/react": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz", - "integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==", + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", + "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -9890,9 +10022,9 @@ "dev": true }, "node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/@types/uuid": { "version": "10.0.0", @@ -9907,9 +10039,9 @@ "dev": true }, "node_modules/@types/web": { - "version": "0.0.157", - "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.157.tgz", - "integrity": "sha512-erqzRlWBxaV7qI0g5rIkHRRxQ3kKmqqhokqgnSy3UEQYIl+5qNCU7DwdPaOke3ZHRXmbrjpGgSc4bjM4ItSDnw==" + "version": "0.0.159", + "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.159.tgz", + "integrity": "sha512-BHPaU+yHqHOrua8iFksPmgLCXEt1LE/2sPB+MPTRuxDFm4z6gBgmDiXUCGleyHiOLT6R+fklgR99hq/iFGVO1w==" }, "node_modules/@types/webgl-ext": { "version": "0.0.30", @@ -10538,9 +10670,9 @@ } }, "node_modules/adm-zip": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.15.tgz", - "integrity": "sha512-jYPWSeOA8EFoZnucrKCNihqBjoEGQSU4HKgHYQgKNEQ0pQF9a/DYuo/+fAxY76k4qe75LUlLWpAM1QWcBMTOKw==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", "engines": { "node": ">=12.0" } @@ -11036,6 +11168,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/await-to-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz", + "integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -11045,14 +11185,14 @@ } }, "node_modules/aws4": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.1.tgz", - "integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==" }, "node_modules/axios": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz", - "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -11339,10 +11479,10 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "node_modules/bmp-js": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==" + "node_modules/bmp-ts": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bmp-ts/-/bmp-ts-1.0.9.tgz", + "integrity": "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==" }, "node_modules/bn.js": { "version": "4.12.0", @@ -11467,6 +11607,116 @@ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", "peer": true }, + "node_modules/browndash-components/node_modules/@mui/core-downloads-tracker": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz", + "integrity": "sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/browndash-components/node_modules/@mui/material": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", + "integrity": "sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.7", + "@mui/system": "^5.16.7", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.3.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/browndash-components/node_modules/@mui/private-theming": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", + "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.6", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/browndash-components/node_modules/@mui/styled-engine": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", + "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, "node_modules/browndash-components/node_modules/@mui/styled-engine-sc": { "version": "5.14.12", "resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.14.12.tgz", @@ -11493,6 +11743,74 @@ } } }, + "node_modules/browndash-components/node_modules/@mui/system": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz", + "integrity": "sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.6", + "@mui/styled-engine": "^5.16.6", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/browndash-components/node_modules/@mui/utils": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", + "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/browndash-components/node_modules/npm": { "version": "9.9.3", "resolved": "https://registry.npmjs.org/npm/-/npm-9.9.3.tgz", @@ -14610,9 +14928,9 @@ } }, "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -14629,7 +14947,7 @@ ], "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ieee754": "^1.2.1" } }, "node_modules/buffer-crc32": { @@ -14640,14 +14958,6 @@ "node": ">=8.0.0" } }, - "node_modules/buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -14802,9 +15112,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001653", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz", - "integrity": "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==", + "version": "1.0.30001655", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", + "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", "funding": [ { "type": "opencollective", @@ -14848,14 +15158,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/centra": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/centra/-/centra-2.7.0.tgz", - "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==", - "dependencies": { - "follow-redirects": "^1.15.6" - } - }, "node_modules/chai": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", @@ -16995,11 +17297,6 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -17424,9 +17721,9 @@ "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { "node": ">=6" } @@ -19252,15 +19549,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -19654,11 +19942,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-from-parse5/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/hast-util-is-element": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", @@ -19707,11 +19990,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-raw/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", @@ -19738,11 +20016,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-jsx-runtime/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/hast-util-to-parse5": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", @@ -19776,11 +20049,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-text/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -21056,11 +21324,6 @@ "node": ">=8" } }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" - }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -21414,15 +21677,6 @@ "node": ">=0.10.0" } }, - "node_modules/isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "dependencies": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -21581,21 +21835,38 @@ } }, "node_modules/jimp": { - "version": "0.22.12", - "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.12.tgz", - "integrity": "sha512-R5jZaYDnfkxKJy1dwLpj/7cvyjxiclxU3F4TrI/J4j2rS0niq6YDUMoPn5hs8GDpO+OZGo7Ky057CRtWesyhfg==", - "dependencies": { - "@jimp/custom": "^0.22.12", - "@jimp/plugins": "^0.22.12", - "@jimp/types": "^0.22.12", - "regenerator-runtime": "^0.13.3" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-1.0.4.tgz", + "integrity": "sha512-J1zLB9LCEMznSoh277vJuiIzTxlurJxrC1Wv9aRKtbLtRZEwxEU5iHmN300Hzc62BUCyGziVHx6g7kfTp84j0A==", + "dependencies": { + "@jimp/core": "1.0.4", + "@jimp/diff": "1.0.4", + "@jimp/js-bmp": "1.0.4", + "@jimp/js-gif": "1.0.4", + "@jimp/js-jpeg": "1.0.4", + "@jimp/js-png": "1.0.4", + "@jimp/js-tiff": "1.0.4", + "@jimp/plugin-blit": "1.0.4", + "@jimp/plugin-blur": "1.0.4", + "@jimp/plugin-circle": "1.0.4", + "@jimp/plugin-color": "1.0.4", + "@jimp/plugin-contain": "1.0.4", + "@jimp/plugin-cover": "1.0.4", + "@jimp/plugin-crop": "1.0.4", + "@jimp/plugin-displace": "1.0.4", + "@jimp/plugin-dither": "1.0.4", + "@jimp/plugin-fisheye": "1.0.4", + "@jimp/plugin-flip": "1.0.4", + "@jimp/plugin-hash": "1.0.4", + "@jimp/plugin-mask": "1.0.4", + "@jimp/plugin-print": "1.0.4", + "@jimp/plugin-resize": "1.0.4", + "@jimp/plugin-rotate": "1.0.4", + "@jimp/plugin-threshold": "1.0.4", + "@jimp/types": "1.0.4", + "@jimp/utils": "1.0.4" } }, - "node_modules/jimp/node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, "node_modules/jpeg-autorotate": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/jpeg-autorotate/-/jpeg-autorotate-9.0.0.tgz", @@ -22176,21 +22447,6 @@ "uc.micro": "^2.0.0" } }, - "node_modules/load-bmfont": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.2.tgz", - "integrity": "sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==", - "dependencies": { - "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^3.7.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" - } - }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -22656,14 +22912,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-find-and-replace/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", @@ -22675,6 +22923,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", + "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-gfm": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", @@ -22709,4523 +22980,136 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-gfm-footnote/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-footnote/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-footnote/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-strikethrough/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-gfm-table/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-table/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-table/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-task-list-item/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-gfm/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-gfm/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-math": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", - "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "longest-streak": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.1.0", - "unist-util-remove-position": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-math/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-math/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-math/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-math/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-math/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-math/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-math/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-math/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-math/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-math/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-mdx-expression/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdx-expression/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdx-expression/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz", - "integrity": "sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-mdx-jsx/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdx-jsx/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdx-jsx/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-chunked": { + "node_modules/mdast-util-gfm-footnote": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", "dependencies": { - "micromark-util-symbol": "^2.0.0" + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-classify-character": { + "node_modules/mdast-util-gfm-strikethrough": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-combine-extensions": { + "node_modules/mdast-util-gfm-table": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", "dependencies": { - "micromark-util-symbol": "^2.0.0" + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-decode-string": { + "node_modules/mdast-util-gfm-task-list-item": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", "dependencies": { - "micromark-util-symbol": "^2.0.0" + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-resolve-all": { + "node_modules/mdast-util-mdx-expression": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", + "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", "dependencies": { - "micromark-util-types": "^2.0.0" + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-subtokenize": { + "node_modules/mdast-util-mdxjs-esm": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-mdxjs-esm/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" }, "funding": { "type": "opencollective", @@ -27245,14 +23129,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-phrasing/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, "node_modules/mdast-util-to-hast": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", @@ -27271,99 +23147,7 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-to-hast/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-to-hast/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-to-hast/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-to-hast/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-to-hast/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + } }, "node_modules/mdast-util-to-markdown": { "version": "2.1.0", @@ -27384,20 +23168,7 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-to-markdown/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": { + "node_modules/mdast-util-to-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", @@ -27409,94 +23180,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-to-markdown/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-to-markdown/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -27612,78 +23295,10 @@ "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz", "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==" }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", "funding": [ { "type": "GitHub Sponsors", @@ -27695,61 +23310,26 @@ } ], "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-core-commonmark": { + "node_modules/micromark-core-commonmark": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", @@ -27782,149 +23362,142 @@ "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", "dependencies": { "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", "dependencies": { "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", "dependencies": { - "micromark-util-character": "^2.0.0", + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", "dependencies": { + "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-whitespace": { + "node_modules/micromark-extension-gfm-tagfilter": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "node_modules/micromark-extension-gfm-task-list-item": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", "dependencies": { - "micromark-util-symbol": "^2.0.0" + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-classify-character": { + "node_modules/micromark-factory-destination": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", "funding": [ { "type": "GitHub Sponsors", @@ -27941,40 +23514,10 @@ "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-normalize-identifier": { + "node_modules/micromark-factory-label": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", "funding": [ { "type": "GitHub Sponsors", @@ -27986,13 +23529,16 @@ } ], "dependencies": { - "micromark-util-symbol": "^2.0.0" + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-resolve-all": { + "node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -28004,13 +23550,14 @@ } ], "dependencies": { + "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-sanitize-uri": { + "node_modules/micromark-factory-title": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", "funding": [ { "type": "GitHub Sponsors", @@ -28022,51 +23569,16 @@ } ], "dependencies": { + "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-types": { + "node_modules/micromark-factory-whitespace": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", "funding": [ { "type": "GitHub Sponsors", @@ -28076,26 +23588,15 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + ], "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-character": { + "node_modules/micromark-util-character": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", @@ -28114,7 +23615,7 @@ "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-chunked": { + "node_modules/micromark-util-chunked": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", @@ -28132,7 +23633,7 @@ "micromark-util-symbol": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-classify-character": { + "node_modules/micromark-util-classify-character": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", @@ -28152,74 +23653,10 @@ "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-resolve-all": { + "node_modules/micromark-util-combine-extensions": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", - "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", "funding": [ { "type": "GitHub Sponsors", @@ -28231,14 +23668,14 @@ } ], "dependencies": { - "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", "funding": [ { "type": "GitHub Sponsors", @@ -28250,87 +23687,13 @@ } ], "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "micromark-util-symbol": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "node_modules/micromark-util-decode-string": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", "funding": [ { "type": "GitHub Sponsors", @@ -28342,33 +23705,16 @@ } ], "dependencies": { + "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" } }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "node_modules/micromark-util-encode": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", "funding": [ { "type": "GitHub Sponsors", @@ -28380,10 +23726,10 @@ } ] }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-types": { + "node_modules/micromark-util-html-tag-name": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", "funding": [ { "type": "GitHub Sponsors", @@ -28395,10 +23741,10 @@ } ] }, - "node_modules/micromark-extension-gfm/node_modules/micromark-util-chunked": { + "node_modules/micromark-util-normalize-identifier": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", "funding": [ { "type": "GitHub Sponsors", @@ -28413,10 +23759,10 @@ "micromark-util-symbol": "^2.0.0" } }, - "node_modules/micromark-extension-gfm/node_modules/micromark-util-combine-extensions": { + "node_modules/micromark-util-resolve-all": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", "funding": [ { "type": "GitHub Sponsors", @@ -28428,62 +23774,13 @@ } ], "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-math": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", - "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", - "dependencies": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" } }, - "node_modules/micromark-extension-math/node_modules/micromark-factory-space": { + "node_modules/micromark-util-sanitize-uri": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", "funding": [ { "type": "GitHub Sponsors", @@ -28496,13 +23793,14 @@ ], "dependencies": { "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" } }, - "node_modules/micromark-extension-math/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "node_modules/micromark-util-subtokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", "funding": [ { "type": "GitHub Sponsors", @@ -28514,11 +23812,13 @@ } ], "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, - "node_modules/micromark-extension-math/node_modules/micromark-util-symbol": { + "node_modules/micromark-util-symbol": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", @@ -28533,7 +23833,7 @@ } ] }, - "node_modules/micromark-extension-math/node_modules/micromark-util-types": { + "node_modules/micromark-util-types": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", @@ -28610,14 +23910,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dependencies": { - "dom-walk": "^0.1.0" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -28960,13 +24252,13 @@ } }, "node_modules/mongoose": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.4.tgz", - "integrity": "sha512-nG3eehhWf9l1q80WuHvp5DV+4xDNFpDWLE5ZgcFD5tslUV2USJ56ogun8gaZ62MKAocJnoStjAdno08b8U57hg==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.6.0.tgz", + "integrity": "sha512-p6VSbYKvD4ZIabqo8C0kS5eKX1Xpji+opTAIJ9wyuPJ8Y/FblgXSMnFRXnB40bYZLKPQT089K5KU8+bqIXtFdw==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", - "mongodb": "6.7.0", + "mongodb": "6.8.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -28980,51 +24272,6 @@ "url": "https://opencollective.com/mongoose" } }, - "node_modules/mongoose/node_modules/mongodb": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz", - "integrity": "sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==", - "dependencies": { - "@mongodb-js/saslprep": "^1.1.5", - "bson": "^6.7.0", - "mongodb-connection-string-url": "^3.0.0" - }, - "engines": { - "node": ">=16.20.1" - }, - "peerDependencies": { - "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.1.0", - "gcp-metadata": "^5.2.0", - "kerberos": "^2.0.1", - "mongodb-client-encryption": ">=6.0.0 <7", - "snappy": "^7.2.2", - "socks": "^2.7.1" - }, - "peerDependenciesMeta": { - "@aws-sdk/credential-providers": { - "optional": true - }, - "@mongodb-js/zstd": { - "optional": true - }, - "gcp-metadata": { - "optional": true - }, - "kerberos": { - "optional": true - }, - "mongodb-client-encryption": { - "optional": true - }, - "snappy": { - "optional": true - }, - "socks": { - "optional": true - } - } - }, "node_modules/mongoose/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -29393,9 +24640,9 @@ } }, "node_modules/npm": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.2.tgz", - "integrity": "sha512-x/AIjFIKRllrhcb48dqUNAAZl0ig9+qMuN91RpZo3Cb2+zuibfh+KISl6+kVVyktDz230JKc208UkQwwMqyB+w==", + "version": "10.8.3", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.3.tgz", + "integrity": "sha512-0IQlyAYvVtQ7uOhDFYZCGK8kkut2nh8cpAdA9E6FvRSJaTgtZRZgNjlC5ZCct//L73ygrpY93CxXpRJDtNqPVg==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -29486,13 +24733,13 @@ "@sigstore/tuf": "^2.3.4", "abbrev": "^2.0.0", "archy": "~1.0.0", - "cacache": "^18.0.3", + "cacache": "^18.0.4", "chalk": "^5.3.0", "ci-info": "^4.0.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.4.2", + "glob": "^10.4.5", "graceful-fs": "^4.2.11", "hosted-git-info": "^7.0.2", "ini": "^4.1.3", @@ -29501,7 +24748,7 @@ "json-parse-even-better-errors": "^3.0.2", "libnpmaccess": "^8.0.6", "libnpmdiff": "^6.1.4", - "libnpmexec": "^8.1.3", + "libnpmexec": "^8.1.4", "libnpmfund": "^5.0.12", "libnpmhook": "^10.0.5", "libnpmorg": "^6.0.6", @@ -29515,12 +24762,12 @@ "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^10.1.0", + "node-gyp": "^10.2.0", "nopt": "^7.2.1", "normalize-package-data": "^6.0.2", "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.2", + "npm-package-arg": "^11.0.3", "npm-pick-manifest": "^9.1.0", "npm-profile": "^10.0.0", "npm-registry-fetch": "^17.1.0", @@ -29531,7 +24778,7 @@ "proc-log": "^4.2.0", "qrcode-terminal": "^0.12.0", "read": "^3.0.1", - "semver": "^7.6.2", + "semver": "^7.6.3", "spdx-expression-parse": "^4.0.0", "ssri": "^10.0.6", "supports-color": "^9.4.0", @@ -30060,7 +25307,7 @@ } }, "node_modules/npm/node_modules/cacache": { - "version": "18.0.3", + "version": "18.0.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -30213,7 +25460,7 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.5", + "version": "4.3.6", "inBundle": true, "license": "MIT", "dependencies": { @@ -30287,7 +25534,7 @@ } }, "node_modules/npm/node_modules/foreground-child": { - "version": "3.2.1", + "version": "3.3.0", "inBundle": true, "license": "ISC", "dependencies": { @@ -30313,7 +25560,7 @@ } }, "node_modules/npm/node_modules/glob": { - "version": "10.4.2", + "version": "10.4.5", "inBundle": true, "license": "ISC", "dependencies": { @@ -30327,9 +25574,6 @@ "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -30496,15 +25740,12 @@ "license": "ISC" }, "node_modules/npm/node_modules/jackspeak": { - "version": "3.4.0", + "version": "3.4.3", "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -30582,7 +25823,7 @@ } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "8.1.3", + "version": "8.1.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -30707,12 +25948,9 @@ } }, "node_modules/npm/node_modules/lru-cache": { - "version": "10.2.2", + "version": "10.4.3", "inBundle": true, - "license": "ISC", - "engines": { - "node": "14 || >=16.14" - } + "license": "ISC" }, "node_modules/npm/node_modules/make-fetch-happen": { "version": "13.0.1", @@ -30907,7 +26145,7 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "10.1.0", + "version": "10.2.0", "inBundle": true, "license": "MIT", "dependencies": { @@ -30917,9 +26155,9 @@ "graceful-fs": "^4.2.6", "make-fetch-happen": "^13.0.0", "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.1.0", "semver": "^7.3.5", - "tar": "^6.1.2", + "tar": "^6.2.1", "which": "^4.0.0" }, "bin": { @@ -30929,14 +26167,6 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/nopt": { "version": "7.2.1", "inBundle": true, @@ -31003,7 +26233,7 @@ } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.2", + "version": "11.0.3", "inBundle": true, "license": "ISC", "dependencies": { @@ -31165,7 +26395,7 @@ } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.1.0", + "version": "6.1.2", "inBundle": true, "license": "MIT", "dependencies": { @@ -31289,7 +26519,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.6.2", + "version": "7.6.3", "inBundle": true, "license": "ISC", "bin": { @@ -32043,17 +27273,19 @@ } }, "node_modules/openai": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.56.0.tgz", - "integrity": "sha512-zcag97+3bG890MNNa0DQD9dGmmTWL8unJdNkulZzWRXrl+QeD+YkBI4H58rJcwErxqGK6a0jVPZ4ReJjhDGcmw==", + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.57.0.tgz", + "integrity": "sha512-JnwBSIYqiZ3jYjB5f2in8hQ0PRA092c6m+/6dYB0MzK0BEbn+0dioxZsPLBm5idJbg9xzLNOiGVm2OSuhZ+BdQ==", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", + "@types/qs": "^6.9.7", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7" + "node-fetch": "^2.6.7", + "qs": "^6.10.3" }, "bin": { "openai": "bin/cli" @@ -32068,9 +27300,9 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.46", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.46.tgz", - "integrity": "sha512-vnRgMS7W6cKa1/0G3/DTtQYpVrZ8c0Xm6UkLaVFrb9jtcVC3okokW09Ki1Qdrj9ISokszD69nY4WDLRlvHlhAA==", + "version": "18.19.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.47.tgz", + "integrity": "sha512-1f7dB3BL/bpd9tnDJrrHb66Y+cVrhxSOTGorRNdHwYTUlTay3HuTDPKo9a/4vX9pMQkhYBcAbL4jQdNlhCFP9A==", "dependencies": { "undici-types": "~5.26.4" } @@ -32275,10 +27507,10 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, "node_modules/parse-json": { "version": "5.2.0", @@ -32617,17 +27849,6 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, - "node_modules/phin": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/phin/-/phin-3.7.1.tgz", - "integrity": "sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==", - "dependencies": { - "centra": "^2.7.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", @@ -32655,22 +27876,22 @@ "integrity": "sha512-6Rtbp7criZRwedlvWbUYxqlqJoAlMvYHo2UcRWq79xZ54vZcaNHpVBOcWkX3ErT2aUA69tv+uiv4zKJbhD/Wgg==" }, "node_modules/pixelmatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", - "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz", + "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==", "dependencies": { - "pngjs": "^3.0.0" + "pngjs": "^6.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "node_modules/pixelmatch/node_modules/pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", + "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", "engines": { - "node": ">=4.0.0" + "node": ">=12.13.0" } }, "node_modules/pkg-dir": { @@ -32761,11 +27982,11 @@ } }, "node_modules/pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", "engines": { - "node": ">=12.13.0" + "node": ">=14.19.0" } }, "node_modules/point-in-polygon": { @@ -32810,9 +28031,9 @@ } }, "node_modules/postcss": { - "version": "8.4.41", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", - "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "version": "8.4.42", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.42.tgz", + "integrity": "sha512-hywKUQB9Ra4dR1mGhldy5Aj1X3MWDSIA1cEi+Uy0CjheLvP6Ual5RlwMCh8i/X121yEDLDIKBsrCQ8ba3FDMfQ==", "funding": [ { "type": "opencollective", @@ -34062,29 +29283,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/readable-stream/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/readable-web-to-node-stream": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", @@ -34165,723 +29363,226 @@ "engines": { "node": ">=14" }, - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/recharts-scale": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", - "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", - "dependencies": { - "decimal.js-light": "^2.4.1" - } - }, - "node_modules/recharts/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/reduce-flatten": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", - "integrity": "sha512-j5WfFJfc9CoXv/WbwVLHq74i/hdTUpy+iNC534LxczMRP67vJeK3V9JOdnL0N1cIRbn9mYhE2yVjvvKXDxvNXQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/rehype-katex": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", - "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/katex": "^0.16.0", - "hast-util-from-html-isomorphic": "^2.0.0", - "hast-util-to-text": "^4.0.0", - "katex": "^0.16.0", - "unist-util-visit-parents": "^6.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", - "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/remark-math": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", - "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-math": "^3.0.0", - "micromark-extension-math": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-math/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/remark-parse/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/remark-parse/node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse/node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse/node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/remark-parse/node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "decimal.js-light": "^2.4.1" } }, - "node_modules/remark-parse/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/recharts/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" } }, - "node_modules/remark-parse/node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/reduce-flatten": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", + "integrity": "sha512-j5WfFJfc9CoXv/WbwVLHq74i/hdTUpy+iNC534LxczMRP67vJeK3V9JOdnL0N1cIRbn9mYhE2yVjvvKXDxvNXQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, "dependencies": { - "micromark-util-symbol": "^2.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/remark-parse/node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" } }, - "node_modules/remark-parse/node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" + "@babel/runtime": "^7.8.4" } }, - "node_modules/remark-parse/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dependencies": { - "micromark-util-symbol": "^2.0.0" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/remark-parse/node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/remark-parse/node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } }, - "node_modules/remark-parse/node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } }, - "node_modules/remark-parse/node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/rehype-katex": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", "dependencies": { - "micromark-util-symbol": "^2.0.0" + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "katex": "^0.16.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-parse/node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", "dependencies": { - "micromark-util-types": "^2.0.0" + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-parse/node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" } }, - "node_modules/remark-parse/node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-parse/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/remark-parse/node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/remark-parse/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", "dependencies": { - "@types/unist": "^3.0.0" + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" }, "funding": { "type": "opencollective", @@ -34904,14 +29605,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/remark-rehype/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, "node_modules/remark-stringify": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", @@ -34926,14 +29619,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/remark-stringify/node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, "node_modules/renderkid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", @@ -36502,9 +31187,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/streamx": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.19.0.tgz", - "integrity": "sha512-5z6CNR4gtkPbwlxyEqoDGDmWIzoNJqCBt4Eac1ICP9YaIT08ct712cFj0u1rx4F8luAuL+3Qc+RFIdI4OX00kg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.0.tgz", + "integrity": "sha512-ZGd1LhDeGFucr1CUCTBOS58ZhEendd0ttpGT3usTvosS4ntIwKN9LJFp+OeCSprsCPL14BXVRZlHGRY1V9PVzQ==", "dependencies": { "fast-fifo": "^1.3.2", "queue-tick": "^1.0.1", @@ -36827,17 +31512,17 @@ } }, "node_modules/style-to-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz", - "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.7.tgz", + "integrity": "sha512-uSjr59G5u6fbxUfKbb8GcqMGT3Xs9v5IbPkjb0S16GyOeBLAzSRK0CixBv5YrYvzO6TDLzIS6QCn78tkqWngPw==", "dependencies": { "inline-style-parser": "0.2.3" } }, "node_modules/styled-components": { - "version": "6.1.12", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.12.tgz", - "integrity": "sha512-n/O4PzRPhbYI0k1vKKayfti3C/IGcPf+DqcrOB7O/ab9x4u/zjqraneT5N45+sIe87cxrCApXM8Bna7NYxwoTA==", + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz", + "integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==", "dependencies": { "@emotion/is-prop-valid": "1.2.2", "@emotion/unitless": "0.8.1", @@ -37171,11 +31856,6 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, - "node_modules/timm": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", - "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" - }, "node_modules/tiny-inflate": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", @@ -37962,9 +32642,9 @@ } }, "node_modules/type-fest": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.25.0.tgz", - "integrity": "sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.0.tgz", + "integrity": "sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==", "engines": { "node": ">=16" }, @@ -38240,11 +32920,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unified/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/uninstall": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/uninstall/-/uninstall-0.0.0.tgz", @@ -38277,11 +32952,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-find-after/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -38294,11 +32964,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-is/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/unist-util-position": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", @@ -38311,11 +32976,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-position/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/unist-util-remove-position": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", @@ -38329,10 +32989,17 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-remove-position/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, "node_modules/unist-util-visit": { "version": "5.0.0", @@ -38361,16 +33028,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit-parents/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/unist-util-visit/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/universal-user-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", @@ -38676,12 +33333,11 @@ } }, "node_modules/vfile": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.2.tgz", - "integrity": "sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "dependencies": { "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" }, "funding": { @@ -38702,11 +33358,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-location/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, "node_modules/vfile-message": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", @@ -38720,40 +33371,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-message/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/vfile-message/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/vfile/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/victory-vendor": { "version": "36.9.2", "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", @@ -39277,11 +33894,6 @@ "node": ">=0.10.0" } }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" - }, "node_modules/whatwg-mimetype": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", @@ -39647,17 +34259,6 @@ } } }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, "node_modules/xml-name-validator": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", @@ -39731,6 +34332,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, "engines": { "node": ">=0.4" } @@ -39856,6 +34458,14 @@ "node": ">= 14" } }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 81ee9972a..11c299f7d 100644 --- a/package.json +++ b/package.json @@ -105,8 +105,8 @@ "@fullcalendar/daygrid": "^6.1.10", "@fullcalendar/multimonth": "^6.1.10", "@internationalized/date": "^3.5.0", - "@mui/icons-material": "^5.14.19", - "@mui/material": "^5.14.19", + "@mui/icons-material": "^6.0.1", + "@mui/material": "^6.0.1", "@octokit/core": "^6.0.1", "@react-google-maps/api": "^2.19.2", "@react-spring/web": "^9.7.3", @@ -129,10 +129,11 @@ "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/textfit": "^2.4.4", - "@types/web": "^0.0.157", + "@types/web": "^0.0.159", "@types/webpack-hot-middleware": "^2.25.9", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", + "any-base": "^1.1.0", "archiver": "^7.0.1", "async": "^3.2.5", "axios": "^1.6.2", @@ -210,7 +211,7 @@ "image-size": "^1.0.2", "image-size-stream": "^1.1.0", "is-plain-obj": "^4.1.0", - "jimp": "^0.22.10", + "jimp": "^1.0.4", "jpeg-autorotate": "^9.0.0", "jquery": "^3.7.1", "js-datepicker": "^5.18.2", diff --git a/src/client/Network.ts b/src/client/Network.ts index 204fcf0ac..9afdc844f 100644 --- a/src/client/Network.ts +++ b/src/client/Network.ts @@ -50,7 +50,7 @@ export namespace Networking { if (!fileguidpairs.length) { return []; } - const maxFileSize = 6000000; + const maxFileSize = 50000000; if (fileguidpairs.some(f => f.file.size > maxFileSize)) { return new Promise[]>(res => res([{ source: { newFilename: '', mimetype: '' } as formidable.File, result: new Error(`max file size (${maxFileSize / 1000000}MB) exceeded`) }])); } diff --git a/src/client/util/request-image-size.ts b/src/client/util/request-image-size.ts index 7a2ecd486..c619192ed 100644 --- a/src/client/util/request-image-size.ts +++ b/src/client/util/request-image-size.ts @@ -35,7 +35,11 @@ module.exports = function requestImageSize(url: string) { res.on('data', chunk => { buffer = Buffer.concat([buffer, chunk]); + }); + + res.on('error', reject); + res.on('end', () => { try { size = imageSize(buffer); if (size) { @@ -46,11 +50,6 @@ module.exports = function requestImageSize(url: string) { /* empty */ console.log('Error: ', err); } - }); - - res.on('error', reject); - - res.on('end', () => { if (!size) { reject(new Error('Image has no size')); return; diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 61bd0241c..5c41fee37 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -9,7 +9,7 @@ import { emptyFunction } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; import { DragManager } from '../../../util/DragManager'; import { Transform } from '../../../util/Transform'; -import { undoBatch } from '../../../util/UndoManager'; +import { undoable, undoBatch } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; import { ContextMenuProps } from '../../ContextMenuItem'; import { DocumentView } from '../../nodes/DocumentView'; @@ -221,13 +221,13 @@ export class CollectionGridView extends CollectionSubView() { }); if (this.Document.gridStartCompaction) { - undoBatch(() => { + undoable(() => { this.Document.gridCompaction = this.Document.gridStartCompaction; this.setLayoutList(savedLayouts); - })(); + }, 'start grid compaction')(); this.Document.gridStartCompaction = undefined; } else { - undoBatch(() => this.setLayoutList(savedLayouts))(); + undoable(() => this.setLayoutList(savedLayouts), 'start grid compaction')(); } } }; @@ -315,9 +315,9 @@ export class CollectionGridView extends CollectionSubView() { e, returnFalse, action(() => { - undoBatch(() => { + undoable(() => { this.Document.gridRowHeight = this._rowHeight; - })(); + }, 'changing row height')(); this._rowHeight = undefined; }), emptyFunction, @@ -360,13 +360,14 @@ export class CollectionGridView extends CollectionSubView() { returnFalse, (clickEv: PointerEvent, doubleTap?: boolean) => { if (doubleTap && !clickEv.button) { - undoBatch( + undoable( action(() => { const text = Docs.Create.TextDocument('', { _width: 150, _height: 50 }); Doc.SetSelectOnLoad(text); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed Doc.AddDocToList(this.Document, this._props.fieldKey, text); this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(clickEv.clientX, clickEv.clientY)))); - }) + }), + 'create grid text' )(); } }, diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts index b2624f654..8ab27130b 100644 --- a/src/server/ApiManagers/UploadManager.ts +++ b/src/server/ApiManagers/UploadManager.ts @@ -3,7 +3,7 @@ import * as formidable from 'formidable'; import * as fs from 'fs'; import { createReadStream, createWriteStream, unlink } from 'fs'; import * as imageDataUri from 'image-data-uri'; -import Jimp from 'jimp'; +import { Jimp } from 'jimp'; import * as path from 'path'; import * as uuid from 'uuid'; import { retrocycle } from '../../decycler/decycler'; @@ -11,7 +11,7 @@ import { DashVersion } from '../../fields/DocSymbols'; import { DashUploadUtils, InjectSize, SizeSuffix } from '../DashUploadUtils'; import { Method, _success } from '../RouteManager'; import { AcceptableMedia, Upload } from '../SharedMediaTypes'; -import { clientPathToFile, Directory, pathToDirectory, publicDirectory, serverPathToFile } from '../SocketData'; +import { Directory, clientPathToFile, pathToDirectory, publicDirectory, serverPathToFile } from '../SocketData'; import { Database } from '../database'; import ApiManager, { Registration } from './ApiManager'; import { SolrManager } from './SearchManager'; @@ -203,12 +203,11 @@ export default class UploadManager extends ApiManager { try { zip.extractEntryTo(entry.entryName, publicDirectory, true, false); createReadStream(pathname).pipe(createWriteStream(targetname)); - Jimp.read(pathname).then(imgIn => { - let img = imgIn; + Jimp.read(pathname).then(img => { DashUploadUtils.imageResampleSizes(extension).forEach(({ width, suffix }) => { const outputPath = InjectSize(targetname, suffix); if (!width) createReadStream(pathname).pipe(createWriteStream(outputPath)); - else img = img.resize(width, Jimp.AUTO).write(outputPath); + else img.resize({ w: width }).write(outputPath as `${string}.${string}`); }); unlink(pathname, () => {}); }); @@ -288,13 +287,12 @@ export default class UploadManager extends ApiManager { imageDataUri.outputFile(uri, serverPathToFile(Directory.images, InjectSize(filename, origSuffix))).then((savedName: string) => { const ext = path.extname(savedName).toLowerCase(); if (AcceptableMedia.imageFormats.includes(ext)) { - Jimp.read(savedName).then(imgIn => { - let img = imgIn; + Jimp.read(savedName).then(img => { (!origSuffix ? [{ width: 400, suffix: SizeSuffix.Medium }] : Object.values(DashUploadUtils.Sizes)) // .forEach(({ width, suffix }) => { const outputPath = serverPathToFile(Directory.images, InjectSize(filename, suffix) + ext); if (!width) createReadStream(savedName).pipe(createWriteStream(outputPath)); - else img = img.resize(width, Jimp.AUTO).write(outputPath); + else img.resize({ w: width }).write(outputPath as `${string}.${string}`); }); }); } diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index 8f012f783..5cf86b2ae 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import { spawn, exec } from 'child_process'; +import { exec, spawn } from 'child_process'; import { green, red } from 'colors'; import { ExifData, ExifImage } from 'exif'; import * as exifr from 'exifr'; @@ -7,9 +7,8 @@ import * as ffmpeg from 'fluent-ffmpeg'; import * as formidable from 'formidable'; import { File } from 'formidable'; import * as fs from 'fs'; -import { createReadStream, createWriteStream, existsSync, readFileSync, rename, unlinkSync, writeFile } from 'fs'; -import Jimp from 'jimp'; -import * as autorotate from 'jpeg-autorotate'; +import { createReadStream, createWriteStream, existsSync, readFileSync, rename, unlinkSync, writeFile } from 'fs'; // import { Jimp } from "@jimp/core"; +import { Jimp } from 'jimp'; import * as md5File from 'md5-file'; import * as path from 'path'; import { basename } from 'path'; @@ -23,6 +22,38 @@ import { AcceptableMedia, Upload } from './SharedMediaTypes'; import { Directory, clientPathToFile, filesDirectory, pathToDirectory, publicDirectory, serverPathToFile } from './SocketData'; import { resolvedServerUrl } from './server_Initialization'; +import { Worker, isMainThread, parentPort } from 'worker_threads'; + +// Create an array to store worker threads +const workerThreads: Worker[] = []; +if (isMainThread) { + // Main thread code + // Create worker threads -- just one right to do image resampling + workerThreads.push(new Worker(__filename)); +} else { + // Worker thread code - Listens for messages from the main thread + parentPort?.on('message', message => workerResampleImage(message.task)); + async function workerResampleImage(task: string) { + const [sourcePath, outputFileName, outputDirectory, unlinkSource] = task.split('::'); + const sizes = DashUploadUtils.imageResampleSizes(path.extname(sourcePath)); + const imgBuffer = await fs.readFileSync(sourcePath); + const outputPath = (suffix: SizeSuffix) => { + const writtenFile = InjectSize(outputFileName, suffix); + return path.resolve(outputDirectory, writtenFile); + }; + await Jimp.fromBuffer(imgBuffer) + .then(img => sizes.filter(({ width }) => width).map(({ width, suffix }) => img.resize({ w: width }).write(outputPath(suffix) as `${string}.${string}`))) + .catch(e => { + console.log('ERROR' + e); + }); + if (unlinkSource === 'true') { + unlinkSync(sourcePath); + } + + // … operations to be performed to execute the task + } +} + // eslint-disable-next-line @typescript-eslint/no-var-requires const requestImageSize = require('../client/util/request-image-size'); @@ -277,15 +308,6 @@ export namespace DashUploadUtils { } }; - async function correctRotation(imgSourcePath: string) { - const buffer = fs.readFileSync(imgSourcePath); - try { - return (await autorotate.rotate(buffer, { quality: 30 })).buffer; - } catch (e) { - return buffer; - } - } - /** * define the resizers to use * @param ext the extension @@ -310,38 +332,29 @@ export namespace DashUploadUtils { * @param outputDirectory the directory to output to, usually Directory.Images * @returns a map with suffixes as keys and resized filenames as values. */ - export async function outputResizedImages(imgSourcePath: string, outputFileName: string, outputDirectory: string) { + export async function outputResizedImages(imgSourcePath: string, outputFileName: string, outputDirectory: string, unlinkSource: boolean) { const writtenFiles: { [suffix: string]: string } = {}; - const sizes = imageResampleSizes(path.extname(outputFileName)); - const imgBuffer = await correctRotation(imgSourcePath); - const imgReadStream = new Duplex(); - imgReadStream.push(imgBuffer); - imgReadStream.push(null); const outputPath = (suffix: SizeSuffix) => { writtenFiles[suffix] = InjectSize(outputFileName, suffix); return path.resolve(outputDirectory, writtenFiles[suffix]); }; + + const sizes = imageResampleSizes(path.extname(outputFileName)); + const imgBuffer = fs.readFileSync(imgSourcePath); + const imgReadStream = new Duplex(); + imgReadStream.push(imgBuffer); + imgReadStream.push(null); await Promise.all( - sizes.filter(({ width }) => !width).map(({ suffix }) => - new Promise(res => { - imgReadStream.pipe(createWriteStream(outputPath(suffix))).on('close', res); - }) + sizes.map(({ suffix }) => + new Promise(res => + imgReadStream.pipe(createWriteStream(outputPath(suffix))).on('close', res) + ) )); // prettier-ignore - return Jimp.read(imgBuffer) - .then(async imgIn => { - let img = imgIn; - await Promise.all( sizes.filter(({ width }) => width).map(({ width, suffix }) => { - img = img.resize(width, Jimp.AUTO).write(outputPath(suffix)); - return img; - } )); // prettier-ignore - return writtenFiles; - }) - .catch(e => { - console.log('ERROR' + e); - return writtenFiles; - }); + // Send a message to worker thread to resample image + workerThreads[0].postMessage({ task: imgSourcePath + '::' + outputFileName + '::' + outputDirectory + '::' + unlinkSource }); + return writtenFiles; } /** @@ -387,8 +400,9 @@ export namespace DashUploadUtils { writtenFiles = {}; } } else { + const unlinkSrcWhenFinished = isLocal().test(source) && cleanUp; try { - writtenFiles = await outputResizedImages(metadata.source, resolved, pathToDirectory(Directory.images)); + writtenFiles = await outputResizedImages(metadata.source, resolved, pathToDirectory(Directory.images), unlinkSrcWhenFinished); } catch (e) { // input is a blob or other, try reading it to create a metadata source file. const reqSource = request(metadata.source); @@ -400,16 +414,14 @@ export namespace DashUploadUtils { .on('close', () => res()) .on('error', () => rej()); }); - writtenFiles = await outputResizedImages(readSource, resolved, pathToDirectory(Directory.images)); + writtenFiles = await outputResizedImages(readSource, resolved, pathToDirectory(Directory.images), unlinkSrcWhenFinished); fs.unlink(readSource, err => console.log("Couldn't unlink temporary image file:" + readSource, err)); } } Array.from(Object.keys(writtenFiles)).forEach(suffix => { information.accessPaths[suffix] = getAccessPaths(images, writtenFiles[suffix]); }); - if (isLocal().test(source) && cleanUp) { - unlinkSync(source); - } + return information; }; -- cgit v1.2.3-70-g09d2 From a958577d4c27b276aa37484e3f895e196138b17c Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 1 Sep 2024 12:55:59 -0400 Subject: consolidated image resampling. fixed importing zipped workspace. --- src/client/views/PropertiesButtons.tsx | 20 --- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 4 +- src/client/views/nodes/PDFBox.tsx | 4 - src/server/ApiManagers/SearchManager.ts | 200 --------------------- src/server/ApiManagers/UploadManager.ts | 49 ++--- src/server/DashUploadUtils.ts | 74 ++++---- src/server/index.ts | 2 - 8 files changed, 56 insertions(+), 299 deletions(-) delete mode 100644 src/server/ApiManagers/SearchManager.ts diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index f346d4ba8..f96a4a255 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -246,26 +246,6 @@ export class PropertiesButtons extends React.Component { // ); // } - // @computed get freezeThumb() { - // return this.propertyToggleBtn( - // 'FreezeThumb', - // '_thumb-frozen', - // on => `${on ? 'Freeze' : 'Unfreeze'} thumbnail`, - // on => 'snowflake', - // (dv, doc) => { - // if (doc['thumb-frozen']) doc['thumb-frozen'] = undefined; - // else { - // document.body.focus(); // so that we can access the clipboard without an error - // setTimeout(() => - // pasteImageBitmap((data_url: any, error: any) => { - // error && console.log(error); - // data_url && Utils.convertDataUri(data_url, doc[Id] + '-thumb-frozen', true).then(returnedfilename => (doc['thumb-frozen'] = new ImageField(returnedfilename))); - // }) - // ); - // } - // } - // ); - // } @computed get snapButton() { // THESE ARE NOT COMING return this.propertyToggleBtn( diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index c4cf8dee7..dbf781e63 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1811,7 +1811,7 @@ export class CollectionFreeFormView extends CollectionSubView { error && console.log(error); data && - ClientUtils.convertDataUri(data, this._props.Document[Id] + '-thumb-frozen').then(returnedfilename => { - this._props.Document['thumb-frozen'] = new ImageField(returnedfilename); + ClientUtils.convertDataUri(data, this._props.Document[Id] + '_icon_' + new Date().getTime()).then(returnedfilename => { + this._props.Document[DocData].icon = new ImageField(returnedfilename); }); }) ); diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index b17275a1e..cb0b0d71f 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -56,10 +56,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { @computed get pdfUrl() { return Cast(this.dataDoc[this._props.fieldKey], PdfField); } - @computed get pdfThumb() { - return ImageCast(this.layoutDoc['thumb-frozen'], ImageCast(this.layoutDoc.thumb))?.url; - } - constructor(props: FieldViewProps) { super(props); makeObservable(this); diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts deleted file mode 100644 index 684b49eaf..000000000 --- a/src/server/ApiManagers/SearchManager.ts +++ /dev/null @@ -1,200 +0,0 @@ -/* eslint-disable no-use-before-define */ -import { exec } from 'child_process'; -import { cyan, green, red, yellow } from 'colors'; -import { logExecution } from '../ActionUtilities'; -import { Method } from '../RouteManager'; -import RouteSubscriber from '../RouteSubscriber'; -import { Search } from '../Search'; -import { Database } from '../database'; -import ApiManager, { Registration } from './ApiManager'; - -export class SearchManager extends ApiManager { - protected initialize(register: Registration): void { - register({ - method: Method.GET, - subscription: new RouteSubscriber('solr').add('action'), - secureHandler: async ({ req, res }) => { - const { action } = req.params; - switch (action) { - case 'start': - case 'stop': - { - const status = req.params.action === 'start'; - SolrManager.SetRunning(status); - } - break; - case 'update': - await SolrManager.update(); - break; - default: - console.log(yellow(`${action} is an unknown solr operation.`)); - } - res.redirect('/home'); - }, - }); - - register({ - method: Method.GET, - subscription: '/dashsearch', - secureHandler: async ({ req, res }) => { - const solrQuery: any = {}; - ['q', 'fq', 'start', 'rows', 'sort', 'hl.maxAnalyzedChars', 'hl', 'hl.fl'].forEach(key => { - solrQuery[key] = req.query[key]; - }); - if (solrQuery.q === undefined) { - res.send([]); - return; - } - const results = await Search.search(solrQuery); - res.send(results); - }, - }); - } -} - -export namespace SolrManager { - export function SetRunning(status: boolean) { - const args = status ? 'start' : 'stop -p 8983'; - console.log(`solr management: trying to ${args}`); - exec(`solr ${args}`, { cwd: './solr-8.3.1/bin' }, (error, stdout, stderr) => { - if (error) { - console.log(red(`solr management error: unable to ${args} server`)); - console.log(red(error.message)); - } - console.log(cyan(stdout)); - console.log(yellow(stderr)); - }); - if (status) { - console.log(cyan('Start script is executing: please allow 15 seconds for solr to start on port 8983.')); - } - } - - export async function update() { - console.log(green('Beginning update...')); - await logExecution({ - startMessage: 'Clearing existing Solr information...', - endMessage: 'Solr information successfully cleared', - action: Search.clear, - color: cyan, - }); - const cursor = await logExecution({ - startMessage: 'Connecting to and querying for all documents from database...', - endMessage: ({ result, error }) => { - const success = error === null && result !== undefined; - if (!success) { - console.log(red('Unable to connect to the database.')); - process.exit(0); - } - return 'Connection successful and query complete'; - }, - action: () => Database.Instance.query({}), - color: yellow, - }); - const updates: any[] = []; - let numDocs = 0; - function updateDoc(doc: any) { - numDocs++; - if (numDocs % 50 === 0) { - console.log(`Batch of 50 complete, total of ${numDocs}`); - } - if (doc.__type !== 'Doc') { - return; - } - const { fields } = doc; - if (!fields) { - return; - } - const update2: any = { id: doc._id }; - let dynfield = false; - fields.forEach((key: any) => { - const value = fields[key]; - const term = ToSearchTerm(value); - if (term !== undefined) { - const { suffix, value: tvalue } = term; - if (key.endsWith('modificationDate')) { - update2['modificationDate' + suffix] = tvalue; - } - update2[key + suffix] = value; - dynfield = true; - } - }); - if (dynfield) { - updates.push(update2); - } - } - await cursor?.forEach(updateDoc); - const result = await logExecution({ - startMessage: `Dispatching updates for ${updates.length} documents`, - endMessage: 'Dispatched updates complete', - action: () => Search.updateDocuments(updates), - color: cyan, - }); - try { - if (result) { - const { status } = JSON.parse(result).responseHeader; - console.log(status ? red(`Failed with status code (${status})`) : green('Success!')); - } else { - console.log(red('Solr is likely not running!')); - } - } catch (e) { - console.log(red('Error:')); - console.log(e); - console.log('\n'); - } - await cursor?.close(); - } - - const suffixMap: { [type: string]: string | [string, string | ((json: any) => any)] } = { - number: '_n', - string: '_t', - boolean: '_b', - image: ['_t', 'url'], - video: ['_t', 'url'], - pdf: ['_t', 'url'], - audio: ['_t', 'url'], - web: ['_t', 'url'], - map: ['_t', 'url'], - date: ['_d', value => new Date(value.date).toISOString()], - proxy: ['_i', 'fieldId'], - prefetch_proxy: ['_i', 'fieldId'], - list: [ - '_l', - list => { - const results = []; - // eslint-disable-next-line no-restricted-syntax - for (const value of list.fields) { - const term = ToSearchTerm(value); - if (term) { - results.push(term.value); - } - } - return results.length ? results : null; - }, - ], - }; - - function ToSearchTerm(valIn: any): { suffix: string; value: any } | undefined { - let val = valIn; - if (val === null || val === undefined) { - return undefined; - } - const type = val.__type || typeof val; - let suffix = suffixMap[type]; - if (!suffix) { - return undefined; - } - - if (Array.isArray(suffix)) { - const accessor = suffix[1]; - if (typeof accessor === 'function') { - val = accessor(val); - } else { - val = val[accessor]; - } - // eslint-disable-next-line prefer-destructuring - suffix = suffix[0]; - } - - return { suffix, value: val }; - } -} diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts index 8ab27130b..868373474 100644 --- a/src/server/ApiManagers/UploadManager.ts +++ b/src/server/ApiManagers/UploadManager.ts @@ -1,20 +1,18 @@ import * as AdmZip from 'adm-zip'; import * as formidable from 'formidable'; import * as fs from 'fs'; -import { createReadStream, createWriteStream, unlink } from 'fs'; +import { unlink } from 'fs'; import * as imageDataUri from 'image-data-uri'; -import { Jimp } from 'jimp'; import * as path from 'path'; import * as uuid from 'uuid'; import { retrocycle } from '../../decycler/decycler'; import { DashVersion } from '../../fields/DocSymbols'; -import { DashUploadUtils, InjectSize, SizeSuffix } from '../DashUploadUtils'; +import { DashUploadUtils, InjectSize, SizeSuffix, workerResample } from '../DashUploadUtils'; import { Method, _success } from '../RouteManager'; import { AcceptableMedia, Upload } from '../SharedMediaTypes'; import { Directory, clientPathToFile, pathToDirectory, publicDirectory, serverPathToFile } from '../SocketData'; import { Database } from '../database'; import ApiManager, { Registration } from './ApiManager'; -import { SolrManager } from './SearchManager'; export default class UploadManager extends ApiManager { protected initialize(register: Registration): void { @@ -185,7 +183,7 @@ export default class UploadManager extends ApiManager { let linkids: string[] = []; try { // eslint-disable-next-line no-restricted-syntax - for (const name in Object.keys(files)) { + for (const name in files) { if (Object.prototype.hasOwnProperty.call(files, name)) { const f = files[name]; // eslint-disable-next-line no-continue @@ -194,25 +192,17 @@ export default class UploadManager extends ApiManager { const zip = new AdmZip(path2.filepath); zip.getEntries().forEach(entry => { const entryName = entry.entryName.replace(/%%%/g, '/'); - if (!entryName.startsWith('files/')) { - return; - } - const extension = path.extname(entryName); - const pathname = publicDirectory + '/' + entry.entryName; - const targetname = publicDirectory + '/' + entryName; - try { - zip.extractEntryTo(entry.entryName, publicDirectory, true, false); - createReadStream(pathname).pipe(createWriteStream(targetname)); - Jimp.read(pathname).then(img => { - DashUploadUtils.imageResampleSizes(extension).forEach(({ width, suffix }) => { - const outputPath = InjectSize(targetname, suffix); - if (!width) createReadStream(pathname).pipe(createWriteStream(outputPath)); - else img.resize({ w: width }).write(outputPath as `${string}.${string}`); - }); - unlink(pathname, () => {}); - }); - } catch (e) { - console.log(e); + if (entryName.startsWith('files/')) { + const pathname = publicDirectory + '/' + entry.entryName; + const targetname = publicDirectory + '/' + entryName; + try { + zip.extractEntryTo(entry.entryName, publicDirectory, true, false); + const extension = path.extname(targetname).toLowerCase(); + const basefilename = targetname.substring(0, targetname.length - extension.length); + workerResample(pathname, basefilename.replace(/_o$/, '') + extension, SizeSuffix.Original, true); + } catch (e) { + console.log(e); + } } }); const json = zip.getEntry('docs.json'); @@ -243,7 +233,6 @@ export default class UploadManager extends ApiManager { unlink(path2.filepath, () => {}); } } - SolrManager.update(); res.send(JSON.stringify({ id, docids, linkids }) || 'error'); } catch (e) { console.log(e); @@ -286,15 +275,9 @@ export default class UploadManager extends ApiManager { } imageDataUri.outputFile(uri, serverPathToFile(Directory.images, InjectSize(filename, origSuffix))).then((savedName: string) => { const ext = path.extname(savedName).toLowerCase(); + const outputPath = serverPathToFile(Directory.images, filename + ext); if (AcceptableMedia.imageFormats.includes(ext)) { - Jimp.read(savedName).then(img => { - (!origSuffix ? [{ width: 400, suffix: SizeSuffix.Medium }] : Object.values(DashUploadUtils.Sizes)) // - .forEach(({ width, suffix }) => { - const outputPath = serverPathToFile(Directory.images, InjectSize(filename, suffix) + ext); - if (!width) createReadStream(savedName).pipe(createWriteStream(outputPath)); - else img.resize({ w: width }).write(outputPath as `${string}.${string}`); - }); - }); + workerResample(savedName, outputPath, origSuffix, false); } res.send(clientPathToFile(Directory.images, filename + ext)); }); diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index 5cf86b2ae..1e55a885a 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -7,7 +7,7 @@ import * as ffmpeg from 'fluent-ffmpeg'; import * as formidable from 'formidable'; import { File } from 'formidable'; import * as fs from 'fs'; -import { createReadStream, createWriteStream, existsSync, readFileSync, rename, unlinkSync, writeFile } from 'fs'; // import { Jimp } from "@jimp/core"; +import { createReadStream, createWriteStream, existsSync, readFileSync, rename, unlinkSync, writeFile } from 'fs'; import { Jimp } from 'jimp'; import * as md5File from 'md5-file'; import * as path from 'path'; @@ -25,32 +25,38 @@ import { resolvedServerUrl } from './server_Initialization'; import { Worker, isMainThread, parentPort } from 'worker_threads'; // Create an array to store worker threads -const workerThreads: Worker[] = []; +enum workertasks { + JIMP = 'jimp', +} +const JimpWorker: Worker | undefined = isMainThread ? new Worker(__filename) : undefined; +export const workerResample = (imgSourcePath: string, outputPath: string, origSuffix: SizeSuffix, unlinkSource: boolean) => { + JimpWorker?.postMessage({ task: workertasks.JIMP, imgSourcePath, outputPath, origSuffix, unlinkSource }); +}; + if (isMainThread) { - // Main thread code - // Create worker threads -- just one right to do image resampling - workerThreads.push(new Worker(__filename)); + // main thread code if needed ... } else { // Worker thread code - Listens for messages from the main thread - parentPort?.on('message', message => workerResampleImage(message.task)); - async function workerResampleImage(task: string) { - const [sourcePath, outputFileName, outputDirectory, unlinkSource] = task.split('::'); - const sizes = DashUploadUtils.imageResampleSizes(path.extname(sourcePath)); - const imgBuffer = await fs.readFileSync(sourcePath); - const outputPath = (suffix: SizeSuffix) => { - const writtenFile = InjectSize(outputFileName, suffix); - return path.resolve(outputDirectory, writtenFile); - }; - await Jimp.fromBuffer(imgBuffer) - .then(img => sizes.filter(({ width }) => width).map(({ width, suffix }) => img.resize({ w: width }).write(outputPath(suffix) as `${string}.${string}`))) - .catch(e => { - console.log('ERROR' + e); - }); - if (unlinkSource === 'true') { - unlinkSync(sourcePath); + parentPort?.on('message', message => { + switch (message.task) { + case workertasks.JIMP: + return workerResampleImage(message); + default: } - - // … operations to be performed to execute the task + }); + + async function workerResampleImage(message: { imgSourcePath: string; outputPath: string; origSuffix: string; unlinkSource: boolean }) { + const { imgSourcePath, outputPath, origSuffix, unlinkSource } = message; + const sizes = !origSuffix ? [{ width: 400, suffix: SizeSuffix.Medium }] : DashUploadUtils.imageResampleSizes(path.extname(imgSourcePath)); + // prettier-ignore + Jimp.read(imgSourcePath) + .then(img => + sizes.forEach(({ width, suffix }) => + img.resize({ w: width || img.bitmap.width }) + .write(InjectSize(outputPath, suffix) as `${string}.${string}`) + )) + .catch(e => console.log('Error Jimp:', e)) + .finally(() => unlinkSource && unlinkSync(imgSourcePath)); } } @@ -332,28 +338,22 @@ export namespace DashUploadUtils { * @param outputDirectory the directory to output to, usually Directory.Images * @returns a map with suffixes as keys and resized filenames as values. */ - export async function outputResizedImages(imgSourcePath: string, outputFileName: string, outputDirectory: string, unlinkSource: boolean) { + export async function outputResizedImages(imgSourcePath: string, outputFileName: string, unlinkSource: boolean) { const writtenFiles: { [suffix: string]: string } = {}; - - const outputPath = (suffix: SizeSuffix) => { - writtenFiles[suffix] = InjectSize(outputFileName, suffix); - return path.resolve(outputDirectory, writtenFiles[suffix]); - }; - + const outputPath = path.resolve(pathToDirectory(Directory.images), outputFileName); const sizes = imageResampleSizes(path.extname(outputFileName)); - const imgBuffer = fs.readFileSync(imgSourcePath); + const imgReadStream = new Duplex(); - imgReadStream.push(imgBuffer); + imgReadStream.push(fs.readFileSync(imgSourcePath)); imgReadStream.push(null); await Promise.all( sizes.map(({ suffix }) => new Promise(res => - imgReadStream.pipe(createWriteStream(outputPath(suffix))).on('close', res) + imgReadStream.pipe(createWriteStream(writtenFiles[suffix] = InjectSize(outputPath, suffix))).on('close', res) ) )); // prettier-ignore - // Send a message to worker thread to resample image - workerThreads[0].postMessage({ task: imgSourcePath + '::' + outputFileName + '::' + outputDirectory + '::' + unlinkSource }); + workerResample(imgSourcePath, outputPath, SizeSuffix.Original, unlinkSource); return writtenFiles; } @@ -402,7 +402,7 @@ export namespace DashUploadUtils { } else { const unlinkSrcWhenFinished = isLocal().test(source) && cleanUp; try { - writtenFiles = await outputResizedImages(metadata.source, resolved, pathToDirectory(Directory.images), unlinkSrcWhenFinished); + writtenFiles = await outputResizedImages(metadata.source, resolved, unlinkSrcWhenFinished); } catch (e) { // input is a blob or other, try reading it to create a metadata source file. const reqSource = request(metadata.source); @@ -414,7 +414,7 @@ export namespace DashUploadUtils { .on('close', () => res()) .on('error', () => rej()); }); - writtenFiles = await outputResizedImages(readSource, resolved, pathToDirectory(Directory.images), unlinkSrcWhenFinished); + writtenFiles = await outputResizedImages(readSource, resolved, unlinkSrcWhenFinished); fs.unlink(readSource, err => console.log("Couldn't unlink temporary image file:" + readSource, err)); } } diff --git a/src/server/index.ts b/src/server/index.ts index 3e0d86814..88dbd232d 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -8,7 +8,6 @@ import DataVizManager from './ApiManagers/DataVizManager'; import DeleteManager from './ApiManagers/DeleteManager'; import DownloadManager from './ApiManagers/DownloadManager'; import GeneralGoogleManager from './ApiManagers/GeneralGoogleManager'; -import { SearchManager } from './ApiManagers/SearchManager'; import SessionManager from './ApiManagers/SessionManager'; import UploadManager from './ApiManagers/UploadManager'; import UserManager from './ApiManagers/UserManager'; @@ -67,7 +66,6 @@ function routeSetter({ addSupervisedRoute, logRegistrationOutcome }: RouteManage new UserManager(), new UploadManager(), new DownloadManager(), - new SearchManager(), new DeleteManager(), new UtilManager(), new GeneralGoogleManager(), -- cgit v1.2.3-70-g09d2