From bff5a298df61f96fbdcbbb7ebd6a5a441c85151c Mon Sep 17 00:00:00 2001 From: geireann Date: Thu, 18 Jul 2024 15:31:13 -0400 Subject: starting to remove anys --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') 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 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(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') 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 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 (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') 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 (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.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 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(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') 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 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(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') 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